“HTML5畫布” 的知識(shí)點(diǎn)(共10條)

前言

html5Canvas的知識(shí)點(diǎn)篓吁,是開發(fā)的必備技能莉擒,在實(shí)際工作中也常常會(huì)涉及到挠唆。

最近熬夜總結(jié)html5Canvas相關(guān)的知識(shí)點(diǎn)婚脱,大家一起看一下吧:

1.html5Canvas基礎(chǔ)知識(shí)

Canvas是什么粹懒?翻譯過來是畫布的意思

Canvas元素用于在網(wǎng)頁上繪制2D圖形和圖像

Canvas使用的場景有:1重付,動(dòng)畫;2凫乖,H5游戲堪夭;3,圖表拣凹。

效果動(dòng)畫,加載Loading:

H5游戲效果:

對(duì)于Canvas需要掌握:

使用Canvas畫直線恨豁,矩形嚣镜,圓形以及設(shè)置它們的樣式。

Canvas中的圖形變換橘蜜,漸變菊匿,文字和圖片

Canvas的像素獲取计福,陰影和曲線繪制以及區(qū)域的剪輯跌捆。

Canvas動(dòng)畫,交互和離屏技術(shù)象颖。

Canvas坐標(biāo)體系

canvas默認(rèn)大小佩厚,300*150

通過HTML,css说订,JavaScript設(shè)置width和height的區(qū)別

HTML和JavaScript設(shè)置的畫布大小

css設(shè)置的是畫布縮放后的大小

坐標(biāo)系原點(diǎn)及方向(原點(diǎn)在左上角抄瓦,向右為x方向,向下為y方向)

畫直線陶冷,矩形和原型

畫直線:ctx.moveTo(x1,y1)钙姊,ctx.lineTo(x2,y2)

畫圓形:?ctx.arc(x,y,radius,0,Math.PI*2,true)

畫矩形:可以通過直線來畫,也可以直接用(ctx.strokeRect(x1,y1,x2,y2)

beginPath和closePath

beginPath和closePath并不是成對(duì)出現(xiàn)的

beginPath的作用是開始一條新路徑

closePath的作用是使當(dāng)前路徑閉合

描邊和填充樣式

strokeStyle用來設(shè)置畫筆樣式埂伦,也就是直線煞额,曲線,邊框的樣式

fillStyle用來設(shè)置 填充樣式

lineWidth用來設(shè)置線條的粗細(xì)

Canvas中的圖形變換沾谜,漸變膊毁,文字和圖片

Canvas中的圖像變換

Canvas中的漸變

Canvas中的文字

Canvas中的圖片

Canvas中的圖形變換

圖形變換都是針對(duì)坐標(biāo)系來說的:

平移:ctx.translate(x,y)

旋轉(zhuǎn):ctx.rotate(rad)

縮放:ctx.scale(x,y)

save和restore

用來保存和恢復(fù)上下文的環(huán)境ctx,一般成對(duì)出現(xiàn)

ctx.save()类早,保存當(dāng)前上下文環(huán)境媚媒。

ctx.restore(),恢復(fù)到上一次的上下文環(huán)境

Canvas中的漸變

線性漸變:ctx.createLinearGradient(xStart,yStart,xEnd,yEnd)

(xStart,yStart)是線段的起點(diǎn)涩僻,(xEnd,yEnd)是線段終點(diǎn)缭召。起點(diǎn)到終點(diǎn)之間的顏色呈漸變栈顷。

gradient.addColorStop可以來控制漸變的顏色

漸變可以理解為一種顏色

徑向漸變:

ctx.createRadialGradient(xStart,yStart, radiusStart,xEnd,yEnd,radiusEnd);

(xStart,yStart)是第一個(gè)圓的原心,radiusStart是第一個(gè)圓的半徑嵌巷,(xEnd,yEnd)是第二個(gè)圓的原心萄凤,radiusEnd是第二個(gè)圓的半徑

第一圓到第二個(gè)圓之間的顏色呈現(xiàn)漸變。

Canvas中的文字

描邊文字:ctx.strokeText(text,x,y)

填充文字:ctx.fillText(text,x,y);

設(shè)置字體樣式:ctx.font

例如:ctx.font="bold 100px sans-serif"

設(shè)置水平對(duì)齊方式:ctx.textAlign

left,start搪哪,左對(duì)齊靡努,center居中對(duì)齊,end,right晓折,右對(duì)齊

設(shè)置垂直對(duì)齊方式:ctx.textBaseline

top惑朦,頂對(duì)齊,middle漓概,居中漾月,bottom,底部對(duì)齊

計(jì)算文本寬度:ctx.measuerText(text).width?須在設(shè)置字體樣式之后計(jì)算

Canvas圖片

繪制圖片3種方法

ctx.drawImage(image,x,y)胃珍,該方法把圖片繪制在(x,y)處

ctx.drawImage(image,x,y,w,h)梁肿,該方法把圖片繪制在(x,y)處,并縮放為寬w,高h(yuǎn)

ctx.drawImage(image,sx,sy,sw,sh,dx,dy,dw,dh)觅彰,該方法把圖片中(sx,sy)處的寬sw吩蔑,高sh的區(qū)域,繪制到(dx,dy)處填抬,并縮放為寬dw烛芬,高dh

在image加載完成之后繪制:

var img = new Image();img.src = 'logo.png';img.onload = function() {? ? ctx.drawImage(img,0,0,40,40,0,0,80,80);}

Canvas繪制

Canvas的圖形繪制和像素獲取

Canvas陰影繪制

Canvas剪輯區(qū)域

Canvas曲線繪制

Canvas圖形畫刷

ctx.createPattern可以創(chuàng)建一個(gè)畫刷模式,進(jìn)而可以設(shè)置到fillStyle里飒责,進(jìn)行畫刷的填充蛀骇。

函數(shù)原型:ctx.createPattern(image,type)

type取值:

no-repeat不平鋪

repeat-x橫方向平

repeat-y縱方向平鋪

repeat全方向平鋪

Canvas像素操作

獲取像素

var imageData = ctx.getImageData(x,y,w,h)返回的是一維數(shù)組:[r1,g1,b1,a1,r2,g2,b2,a2...]

設(shè)置像素

ctx.putImageData(imageData,x,y)把imageData放在(x,y)處

設(shè)置像素

ctx.putImageData(imageData, x, y, dirtyX, dirtyY, dirtyW, dirtyH)只顯示(dirtyX,dirtyY)處的寬dirtyW,dirtyH的區(qū)域

Canvas陰影繪制

ctx.shadowOffsetX:陰影x方向的偏移距離

ctx.shadowOffsetY:陰影y方向的偏移距離

ctx.shadowColor:陰影的顏色

ctx.shadowBlur:陰影的模糊半徑

效果圖:

Canvas剪輯區(qū)域

設(shè)置一個(gè)路徑;

調(diào)用ctx.clip();

再繪制圖形读拆。

Canvas繪制曲線

狐線:

context.arc(x,y,radius, starAngle,endAngle, anticlockwise)圓心(x,y)? 半徑radius從starAngle到endAngleanticlockwise代表是否逆時(shí)針方向

生成工具

Canvas Quadratic Curve Example

http://blogs.sitepointstatic.com/examples/tech/canvas-curves/quadratic-curve.html

http://blogs.sitepointstatic.com/examples/tech/canvas-curves/bezier-curve.html

二次樣條曲線:

context.quadraticCurveTo(qcpx,qcpy, qx,qy)

貝塞爾曲線:

context.bezierCurveTo(cp1x,cp1y, cp2x, cp2y, x,y)

Canvas動(dòng)畫擅憔,Canvas離屏技術(shù)

ctx.clearRect(x,y, width,height)

清除(x,y)點(diǎn)起, 寬width,高h(yuǎn)eight的區(qū)域檐晕,用于重新繪制

離屏技術(shù)是什么:通過在離屏Canvas中繪制元素暑诸,再復(fù)制到顯示Canvas中,從而大幅提高性能的一種技術(shù)辟灰。

使用離屏技術(shù):

一般把靜態(tài)場景繪制在離屏canvas上个榕,更新動(dòng)態(tài)場景的時(shí)候,把靜態(tài)場景copy過來芥喇,而不是重新繪制西采。

離屏技術(shù):

一個(gè)Canvas中的圖形繪制到另一個(gè)Canvas方法:

ctx.drawImage(canvas,x,y),該方法把canvas繪制在(x,y)處ctx.drawImage(canvas,x,y, w,h),該方法把canvas繪制在(x,y)處,并縮放為寬w,高h(yuǎn)ctx.drawImage(canvas, sx, sy, sw, sh, dx, dy, dw, dh)继控,該方法把canvas中(sx, sy)處的寬sw,高sh的區(qū)域械馆,繪制到(dx,dy)處胖眷,并縮放為寬dw, 高dh

對(duì)canvas插件的相關(guān)了解

什么是Canvas插件,掌握Chart.js插件霹崎,了解Chartist.js和HighCharts.js插件

(圖表)Chart.js插件:https://www.chartjs.org/

Chartist.js插件是一個(gè)簡單的響應(yīng)式圖表插件:支持SVG格式(http://gionkunz.github.io/chartist-js/)

HighCharts.js插件:方便快捷的HTML5交互性圖標(biāo)庫:https://www.highcharts.com/

Chartist.js插件與HighCharts.js插件

Chartist.js配置簡單珊搀,css和JavaScript分離,響應(yīng)式圖表尾菇,支持不同的瀏覽器尺寸和分辨率境析。

HighCharts.js,兼容當(dāng)今所有的瀏覽器派诬,包含iPhone劳淆,IE,火狐等默赂。

響應(yīng)式布局憔儿,它的用戶體驗(yàn)友好,響應(yīng)式網(wǎng)站可以根據(jù)不同終端放可,不同尺寸和不同應(yīng)用環(huán)境,自動(dòng)調(diào)整界面布局朝刊,展示內(nèi)容耀里,提供非常好的視覺效果。響應(yīng)式布局就是一個(gè)網(wǎng)站能夠兼容多個(gè)終端

2. 構(gòu)建Canvas元素

示例:

<style>#canva {? ? border: 1px solid red;}</style><div><canvas id="canva" width="200" height="200"></canvas>// 繪制寬高200的canvas</div>

使用JavaScript實(shí)現(xiàn)繪圖的流程

在開始繪圖時(shí)拾氓,先要獲取Canvas元素的對(duì)象冯挎,在獲取一個(gè)繪圖的上下文。

獲取Canvas對(duì)象 ,使用document對(duì)象的getElementById()方法獲取咙鞍。

var canvas = document.getElementById("canvas")可以使用通過標(biāo)簽名稱來獲取對(duì)象的getElementsByTagName方法

創(chuàng)建二維的繪圖上下文對(duì)象

使用getContext()方法來獲取

var context? = canvas.getContext("2d")

在Canvas上繪制文字

context.font="98px 黑體"; // 文字樣式context.fillStyle="red"; // 文字顏色context.textAlign = "center"; // 文字對(duì)齊方式// 繪制文字context.fillText("達(dá)達(dá)前端"房官,100, 123, 234);

繪制圖像:drawImage(image, x, y) // 在畫布上定位圖像// 方法在畫布上繪制圖像、畫布或視頻续滋。// 方法也能夠繪制圖像的某些部分翰守,以及/或者增加或減少圖像的尺寸。drawImage(image, x, y, width, height)// 在畫布上定位圖像疲酌,并規(guī)定圖像的寬度和高度drawImage(image, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight)// 剪切圖像蜡峰,并在畫布上定位被剪切的部分

參數(shù):

參數(shù)描述

image規(guī)定要使用的圖像,畫布或視頻

sourceX開始剪切的x坐標(biāo)位置

sourceY開始剪切的y坐標(biāo)位置

sourceWidth被剪切圖像的寬度

sourceHeight被剪切圖像的高度

destX在畫布上放置圖像的 x 坐標(biāo)位置

destY在畫布上放置圖像的 y 坐標(biāo)位置

destWidth要使用的圖像的寬度

destHeight要使用的圖像的高度

插入圖像:

在Canvas中繪制文字:

// canvas 寬高200<canvas id="canvas" width="200" height="200"></canvas><style type="text/css">canvas {? ? border: 2px solid #ccc;}</style><script>? ? // 獲取canvas? ? var canvas = document.getElementById("canvas");? ? var context = canvas.getContext("2d");? ? // 設(shè)置字體? ? context.font="98px 黑體";? ? // 填充? ? context.fillStyle="#036";? ? // 文本水平位置? ? context.textAlign="center";? ? // 執(zhí)行繪制? ? context.fillText("達(dá)達(dá)前端",100, 120, 200);</script>

3.繪制矩形

兩個(gè)方法:

strokeRect() -?矩形邊框

fillRect() -?填充矩形區(qū)域

strokeStyle -?設(shè)置線條的顏色

lineWidth -?設(shè)置線條寬度朗恳,默認(rèn)寬度為1湿颅,單位是像素

fillStyle - 設(shè)置區(qū)域或文字的填充顏色

繪制矩形邊框,使用strokeStyle方法:

// 繪制矩形邊框strokeRect(x,y, width, height);

填充矩形區(qū)域粥诫,使用fillRect()方法:

// 填充矩形區(qū)域fillRect(x,y,width,height);

繪制矩形

// 繪制矩形function drawRect() {? ? var canvas = document.getElementById("canvas");? ? var context = canvas.getContext("2d");? ? // 描邊? ? context.strokeStyle = "#000";? ? // 線條寬度? ? context.lineWidth = 1;? ? // 矩形邊框? ? context.strokeRect(50,50, 150, 100);? ? // 填充? ? context.fillStyle="#f90";? ? // 矩形? ? context.fillRect(50,50,150,100);}window.addEventListener("load",DrawRect,true);

使用clearRect方法油航,可以擦除指定的矩形區(qū)域:

// 擦除指定的矩形區(qū)域context.clearRect(x,y,width,height)

4.體驗(yàn)canvas繪圖

在實(shí)際開發(fā)中,畫布是默認(rèn)300*150的大小怀浆。

// 為畫布設(shè)置邊框canvas {? ? border: 1px solid #ccc;}// 準(zhǔn)備畫布谊囚,默認(rèn)是300*150// 設(shè)置畫布的大小<canvas width="1200" height="800"></canvas>// 準(zhǔn)備繪制工具<script>// 獲取元素var myCanvas = document.querySelector('canvas');// 獲取上下文怕享,繪制工具箱var ctx = myCanvas.getContext('2d');// 移動(dòng)畫筆ctx.moveTo(100,100);// 繪制直線,軌跡ctx.lineTo(200,100);// 描邊ctx.stroke()

創(chuàng)建Canvas元素

向 HTML5 頁面添加 canvas 元素

// 規(guī)定元素的 id秒啦、寬度和高度

圖形繪制

需要理解些概念:

路徑的概念

路徑的繪制

描邊?stroke()

填充?fill()

閉合路徑

手動(dòng)閉合

程序閉合?closePath()

開啟新的路徑?beginPath()

設(shè)置樣式

lineWidth 線寬熬粗,默認(rèn)1px

lineCap 線末端類型:(butt默認(rèn))、round余境、square

lineJoin 相交線的拐點(diǎn)?miter(默認(rèn))驻呐、round、bevel

strokeStyle 線的顏色

fillStyle 填充顏色

setLineDash()?設(shè)置虛線

getLineDash()?獲取虛線寬度集合

lineDashOffset?設(shè)置虛線偏移量(負(fù)值向右偏移)

矩形繪制

strokeRect(x,y,w,h)?有獨(dú)立路徑芳来,不影響別的繪制

fillRect(x,y,w,h)?有獨(dú)立路徑含末,不影響別的繪制

clearRect(x,y,w,h)?擦除矩形區(qū)域

圓弧繪制

x 圓心橫坐標(biāo)

y 圓心縱坐標(biāo)

r 半徑

startAngle?開始角度

endAngle?結(jié)束角度

anticlockwise?是否逆時(shí)針方向繪制(默認(rèn)false表示順時(shí)針;true表示逆時(shí)針)

繪制文本

strokeText()

fillText(text,x,y,maxWidth)

text 要繪制的文本

x,y 文本繪制的坐標(biāo)(文本左下角)

maxWidth 設(shè)置文本最大寬度即舌,可選參數(shù)

ctx.textAlign?文本水平對(duì)齊方式佣盒,相對(duì)繪制坐標(biāo)來說的

left

center

right

start 默認(rèn)

end

ctx.direction?屬性css(rtl ltr) start和end于此相關(guān)

如果是ltr,start和left表現(xiàn)一致

如果是rtl,start和right表現(xiàn)一致

ctx.textBaseline?設(shè)置基線(垂直對(duì)齊方式 ?)

top 文本的基線處于文本的正上方,并且有一段距離

middle 文本的基線處于文本的正中間

bottom 文本的基線處于文本的證下方顽聂,并且有一段距離

hanging 文本的基線處于文本的正上方肥惭,并且和文本粘合

alphabetic 默認(rèn)值,基線處于文本的下方紊搪,并且穿過文字

ideographic 和bottom相似蜜葱,但是不一樣

measureText()?獲取文本寬度obj.width

繪制圖片

x,y,w,h 圖片中的一個(gè)矩形區(qū)域

x1,y1,w1,h1 畫布中的一個(gè)矩形區(qū)域

img 圖片對(duì)象、canvas對(duì)象耀石、video對(duì)象

x,y 圖片繪制的左上角

w,h 圖片繪制尺寸設(shè)置(圖片縮放牵囤,不是截取)

img 圖片對(duì)象、canvas對(duì)象滞伟、video對(duì)象

x,y 圖片繪制的左上角

三個(gè)參數(shù)drawImage(img,x,y)

五個(gè)參數(shù)drawImage(img,x,y,w,h)

九個(gè)參數(shù)drawImage(img,x,y,w,h,x1,y1,w1,h1)

坐標(biāo)變換

平移 移動(dòng)畫布的原點(diǎn)

translate(x,y)?參數(shù)表示移動(dòng)目標(biāo)點(diǎn)的坐標(biāo)

縮放

scale(x,y)?參數(shù)表示寬高的縮放比例

旋轉(zhuǎn)

rotate(angle)?參數(shù)表示旋轉(zhuǎn)角度

5.使用路徑

lineTo()

rect()

arc()

fill()

stroke()

創(chuàng)建繪圖路徑

使用方法:beginPath()和closePath()揭鳞,分別表示開始一個(gè)新的路徑和關(guān)閉當(dāng)前的路徑

使用beginPath()方法創(chuàng)建一個(gè)新的路徑

moveTo(x,y),開始繪圖時(shí)的坐標(biāo)

lineTo(x,y)梆奈,繪制直線到目標(biāo)坐標(biāo)

arc(x,y, radius, startAngle,endAngle, counterclockwise)

x,y描述弧的圓形的圓心坐標(biāo)

radius圓形的半徑

startAngle描述弧的開始點(diǎn)的角度

endAngle描述弧的結(jié)束點(diǎn)的角度

counterclockwise野崇,true值,表示逆時(shí)針方向亩钟,否則反之

rect(x,y, width, height):xy,起點(diǎn)坐標(biāo)舞骆,矩形的寬高,繪制矩形路徑

closePath方法關(guān)閉當(dāng)前路徑

繪制圖形樣式

stokeStyle?屬性設(shè)置矩形邊框的顏色

lineWidth?屬性設(shè)置邊框的寬度

fillStyle?屬性設(shè)置填充的顏色

繪制網(wǎng)格径荔,網(wǎng)格大小

vargrid =10;// 畫多少條x軸方向的線督禽,橫向的條數(shù),畫布的高度varcanvasHeight = myCanvas.heightvarcanvasWidth = myCanvas.width// 畫布寬高ctx.canvas.widthctx.canvas.height// 網(wǎng)格大小vargridSize =10;varcanvasHeight = ctx.canvas.height;varxLineTotal = canvasHeight / gridSize// 總線條varxLineTotal =Math.floor(canvasHeight / gridSize);for(vari=0; i<=xLineTotal; i++) {? ? ctx.beginPath();ctx.moveTo(0, i*gridSize-0.5);ctx.lineTo(canvasWidth, i*gridSize-0.5);ctx.strokeStyle='#eee';? ? ctx.stroke();}// 畫多少條y軸方向的線varyLineTotal = canvasWidth / gridSizevaryLineTotal =Math.floor(canvasWidth / gridSize);for(vari=0; i <= yLineTotal; i++) {? ? ctx.beginPath();ctx.moveTo(i*gridSize-0.5,0);ctx.lineTo(i*gridSize-0.5,canvasHeight);ctx.strokeStyle='#eee';? ? ctx.stroke();}

繪制坐標(biāo)系总处,確定圓點(diǎn)狈惫,確定離畫布旁邊的距離,確定坐標(biāo)軸的長度,確定箭頭的大小胧谈,繪制箭頭填充忆肾。

// 繪制坐標(biāo)系varspace =20;vararrowSize =10;// 畫布寬高varcanvasWidth = ctx.canvas.width;varcanvasHeight = ctx.canvas.height;// 坐標(biāo)系varx0 = space;vary0 = canvasHeight - space;// 繪制x軸ctx.moveTo(x0,y0);ctx.lineTo(canvasWidth-space, y0);ctx.stroke();// 箭頭ctx.lineTo(canvasWidth-space-arrowSize, y0 + arrowSize/2);ctx.lineTo(canvasWidth-space-arrowSize, y0 - arrowSize/2);ctx.lineTo(canvasWidth-space, y0);ctx.fill();ctx.stroke();// 繪制y軸ctx.beginPath();ctx.moveTo(x0, y0);ctx.lineTo(space, space);ctx.stroke();// 箭頭ctx.lineTo(space+space-arrowSize/2, space + arrowSize);ctx.lineTo(space-space-arrowSize/2, space - arrowSize);ctx.lineTo(space, space);ctx.fill();ctx.stroke();// 繪制點(diǎn)varcoordinate = {x:146,y:356}// 點(diǎn)尺寸vardottedSize =6;ctx.moveTo(coordinate.x - dottedSize/2, coordinate.y - dottedSize/2);ctx.lineTo(coordinate.x + dottedSize/2, coordinate.y - dottedSize/2);ctx.lineTo(coordinate.x + dottedSize/2, coordinate.y + dottedSize/2);ctx.lineTo(coordinate.x - dottedSize/2, coordinate.y + dottedSize/2);ctx.closePath();ctx.fill();

arc方法和rect方法

// 圓形context.arc(100,100,30,0,Math.PI*2,true);

使用beginPath()方法可以新創(chuàng)建一個(gè)子路徑,closePath()方法用來閉合路徑的菱肖。

繪制兩條直線

function DrawLine() {? ? var canvas = document.getElementById("canvas");? ? var context = canvas.getContext("2d");? ? // 創(chuàng)建繪制過程? ? context.beginPath();? ? context.moveTo(50,50);? ? context.lineTo(120,120);? ? context.lineTo(120,60);? ? context.closePath();? ? context.strokeStyle="#000";? ? // 執(zhí)行繪制? ? context.stroke();}

beginPath()?方法開始一條路徑客冈,或者重置當(dāng)前的路徑

closePath()?方法創(chuàng)建從當(dāng)前點(diǎn)到開始點(diǎn)的路徑

如果不用beginPath()方法,繪制圖形時(shí)不再創(chuàng)建子路徑稳强,第一次的圖形在執(zhí)行過程中會(huì)被繪制填充兩次场仲。

圖形組合

屬性?globalCompositeOperation?設(shè)置如何在畫布上組合顏色

12中組合類型:

值說明

copy只繪制新圖形,刪除其他所有內(nèi)容

darker在圖形重疊的地方退疫,顏色由兩個(gè)顏色值相減后決定

destination-atop已有的內(nèi)容只在它和新的圖形重疊的地方保留渠缕,新圖形繪制在內(nèi)容后

destination-in在新圖形和已有畫布重疊的地方,已有內(nèi)容都保留褒繁,所有其他內(nèi)容成為透明

destination-out在新圖形和已有內(nèi)容不重疊的地方亦鳞,已有內(nèi)容保留所有其他內(nèi)容成為透明

destination-over新圖形繪制于已有內(nèi)容的后面

lighter在圖形重疊的地方,顏色由兩種顏色值的疊加值來決定

source-atop只在新圖形和已有內(nèi)容重疊的地方才繪制新圖形

source-in在新圖形和已有內(nèi)容重疊的地方棒坏,新圖形才會(huì)被繪制燕差,所有其他內(nèi)容成為透明

source-out只在和已有圖形不重疊的地方繪制新圖形

source-over新圖形繪制于已有圖形的頂部

xor在重置和正常繪制的其他地方,圖形都成為透明

繪制曲線

// 圓形坝冕,曲線arc(x, y, radius, startAngle, endAngle, counterclockwise);

x,y?表示弧的圓形的圓心坐標(biāo)

radius?表示弧的圓形的半徑

startAngle?表示圓弧的開始點(diǎn)的角度

endAngle?表示圓弧的結(jié)束點(diǎn)的角度

counterclockwise?若true表示逆時(shí)針徒探,false反之順時(shí)針

<style>// 畫布背景顏色#canvas {? ? background: #000;}</style>// 畫布寬度400<canvas id="canvas" width="400" height="400"><script> var canvas = document.getElementById('canvas'); var context= canvas.getContext('2d') // 開始 context.beginPath(); // 繪制圓形 context.arc(100, 100, 50, 0, Math.PI*2, true); // 關(guān)閉 context.closePath(); // 填充顏色 context.fillStyle = 'rgb(255,255,255)'; context.fill();</script>

如果使用css設(shè)置寬高,畫布會(huì)按照300*150的比例進(jìn)行縮放徽诲,將300*150的頁面顯示在400*400的容器中。

// 設(shè)置畫布寬度var cx = canvas.width = 400;var cy = canvas.height = 400;

使用js動(dòng)態(tài)設(shè)置寬高吵血。

建議使用HTML中的width和height谎替,或者js動(dòng)態(tài)設(shè)置寬高

創(chuàng)建一個(gè)canvas標(biāo)簽,第一步:

// 獲取這個(gè)canvas的上下文對(duì)象var canvas = document.getElementById('canvas');var context = canvas.getContext('2d');

方法:

fill()?填充路徑

stroke()?描邊

arc()?創(chuàng)建圓弧

rect()?創(chuàng)建矩形

fillRect()?繪制矩形路徑區(qū)域

strokeRect()?繪制矩形路徑描邊

clearRect()?在給定的矩形內(nèi)清除指定的像素

beginPath()?起始一條路徑蹋辅,或重置當(dāng)前路徑

moveTo()?把路徑移動(dòng)到畫布中的指定點(diǎn)钱贯,不創(chuàng)建線條

lineTo()添加一個(gè)新點(diǎn),在畫布中創(chuàng)建從該點(diǎn)到最后指定點(diǎn)的線條

clip()?從原始畫布剪切任意形狀和尺寸的區(qū)域

arcTo()?創(chuàng)建兩切線之間的弧/曲線

quadraticCurveTo()?創(chuàng)建二次方貝塞爾曲線

bezierCurveTo()?創(chuàng)建三次方貝塞爾曲線

isPointInPath()?如果指定的點(diǎn)位于當(dāng)前路徑中侦另,則返回 true秩命,否則返回 false

輔助線繪制弧線:arcTo()?方法

語法:

// 輔助線繪制弧線arcTo(x1, y1, x2, y2, radius)

arcTo()方法繪制一條弧線

代碼:

// 繪制一條弧線function draw() {? ? var canvas = document.getElementById('canvas');? ? var context = canvas.getContext('2d');? ? // 開始繪制? ? context.beginPath();? ? // 移動(dòng)點(diǎn)? ? context.moveTo(80, 120);? ? // 繪制線條? ? context.lineTo(150, 60);? ? context.lineTo(180, 130);? ? // 描邊? ? context.strokeStyle="rgba(0,0,0,0.4)";? ? context.lineWidth=2;? ? context.stroke();? ? context.beginPath();? ? context.moveTo(80,120);? ? context.arcTo(150,60,180,130,50);? ? context.strolkeStyle="rgba(255,135,0,1)";? ? context.stroke();}

繪制二次樣條曲線

quadraticCurveTo()方法:

quadraticCurveTo(cpX, cpY, x, y);// cpX, cpY描述了控制點(diǎn)的坐標(biāo),x, y描述了曲線的終點(diǎn)坐標(biāo)

繪制貝濟(jì)埃曲線

bezierCurveTo()方法:它是應(yīng)用于二維圖形應(yīng)用程序的數(shù)學(xué)曲線褒傅。

bezierCurveTo(cp1X, cp1Y, cp2X, cp2Y, x, y);// cp1X, cp1Y 表示第一個(gè)控制點(diǎn)的坐標(biāo) // cp2X, cp2Y 表示第二個(gè)控制點(diǎn)的坐標(biāo) // x, y表示曲線的終點(diǎn)坐標(biāo)

繪制曲線:

function draw() {? ? // 繪制曲線? ? var canvas = document..getElementById('canvas');? ? var context = canvas.getContext('2d');? ? // 開始繪制? ? context.beginPath();? ? // 移動(dòng)? ? context.moveTo(100,180);? ? // 連線? ? context.lineTo(110,80);? ? context.moveTo(260,100);? ? context.lineTo(300,200);? ? // 描邊? ? context.strokeStyle="rgba(0,0,0,0.4)";? ? // 設(shè)置寬度? ? context.lineWidth=3;? ? context.stroke();? ? context.beginPath();? ? context.moveTo(100,180);? ? // 繪制貝濟(jì)埃曲線? ? context.bezierCurveTo(110,80,260,100,300,200);? ? // 設(shè)置寬度? ? context.lineWidth = 3;? ? context.strokeStyle="rgba(255,135,0,1)";? ? context.stroke();}

四分之一圓

varcanvas =document.getElementById('canvas');varcontext = canvas.getContext('2d');// 畫布寬度200varcanX = canvas.width =200varcanY = canvas.height =200;// 開始繪制context.beginPath();// 四分之一圓context.arc(100,100,50,0,Math.PI*0.5,false);context.strokeStyle="white"context.stroke();context.beginPath();context.lineTo(200,200);context.lineTo(200,100);context.lineTo(100,50);context.strokeStyle ='#fff';context.stroke();

lineCap?設(shè)置或返回線條的結(jié)束斷點(diǎn)樣式

lineJoin?設(shè)置或返回兩條線相交時(shí)弃锐,產(chǎn)生拐角類型

lineWidth?設(shè)置或返回當(dāng)前的線條寬度

miterLimit?設(shè)置或返回最大斜接長度

fillRect()?繪制一個(gè)實(shí)心矩形

strokeRect()?繪制一個(gè)空心矩形

設(shè)置陰影,shadowBlur?-context.shadowBlur?= 20

createLinearGradient()創(chuàng)建線性漸變

createPattern()在指定的方向上重復(fù)指定的元素

createRadialGradient()創(chuàng)建放射狀/環(huán)形的漸變

addColorStop()規(guī)定漸變對(duì)象中的顏色和停止位置

gradient.addColorStop(stop,color)

scale()?縮放當(dāng)前繪圖變大或變小

rotate()?旋轉(zhuǎn)當(dāng)前繪圖

translate()?重新映射畫布的(0,0)位置

6.使用圖像

使用三種方法插入圖像

function draw() {? ? var canvas = document.getElementById('canvas');? ? var context = canvas.getContext('2d');? ? // image實(shí)例? ? var newImg = new Image();? ? newImg.src='../images/dada.jpg' // 指定圖像的文件地址? ? newImg.onload = function(){? ? ? ? // 繪圖? ? ? ? context.drawImage(newImg, 0, 0);? ? ? ? context.drawImage(newImg, 250,100, 150,200);? ? ? ? context.drawImage(newImg, 90,80,100,100,0,0,120,120);? ? }}

在插入圖像之前殿托,需要考慮圖像加載的時(shí)間霹菊,如果圖像沒加載完成就已經(jīng)執(zhí)行drawImage()方法,就不會(huì)顯示任何圖片支竹。

7.繪制漸變

提供了兩種漸變的創(chuàng)建的方法:

// 創(chuàng)建線性漸變createLinearGradient()方法// 創(chuàng)建徑向漸變createRadialGradient()方法

設(shè)置漸變顏色和過渡方式

語法如下:

offset是一個(gè)范圍在0.0到1.0之間的浮點(diǎn)值 表示漸變的開始點(diǎn)和結(jié)束點(diǎn)之間的一部分

offset的0為開始點(diǎn)旋廷,1為結(jié)束點(diǎn)

addColorStop(offset, color);

繪制線性漸變的矩形

function draw() {? ? var canvas = document.getElementById('canvas')? ? var context = canvas.getContext('2d')? ? // 創(chuàng)建漸變對(duì)象鸠按,線性漸變? ? var grd = context.createLinearGradient(0,0,300,0)? ? // 設(shè)置漸變顏色? ? grd.addColorStop(0, '#xxx'); // 設(shè)置顏色? ? grd.addColorStop(1, '#xxx'); // 設(shè)置顏色? ? // 將填充樣式設(shè)置為線性漸變對(duì)象? ? context.fillStyle = grd;? ? context.fillRect(0,0,300,80);}

繪制徑向漸變的矩形

function draw() {? ? var canvas = document.getElementById('canvas')? ? var context = canvas.getContext('2d')? ? // 徑向漸變? ? var grd = context.createRadialGradient(50,50,0,100,100,90);? ? // 設(shè)置漸變顏色以及方式? ? grd.addColorStop(0,'#xxx');? ? grd.addColorStop(1,'#xxx');? ? context.fillStyle = grd;? ? context.beginPath();? ? // 圓形? ? context.arc(100,100,90,0,Math.PI*2,true);? ? context.fill();}

描邊屬性

線帽屬性:lineCap,表示指定線條的末端如何繪制值:lineCap: butt, round, square饶碘,當(dāng)線條具有一定的寬度才能表現(xiàn)出來目尖。

butt// 定義了線段沒有線帽round// 定義了線段的末端為一個(gè)半圓形的線帽square// 定義了線段的末端為一個(gè)矩形的線帽

線條的連接屬性lineJoin,用于兩條線條到的連接方式:

miter兩條線段的外邊緣一直延伸到它們相交扎运,屬性miterLimit是用來描述如何繪制兩條線段的交點(diǎn)瑟曲,是表示延伸長度和線條長度的比值。

默認(rèn)為10绪囱,只有miter使用時(shí)有效

lineJoin = [value];round // 兩條線段的外邊緣應(yīng)該和一個(gè)填充的弧結(jié)合bevel // 兩條線段的外邊緣應(yīng)該和一個(gè)填充的三角形相交

8.模式

語法如下:

createPattern(image, repetitionStyle)

repeat?表示圖像在各個(gè)方向上循環(huán)平鋪

repeat-x?表示圖像在橫向上循環(huán)平鋪

repeat-y?表示圖像在縱向上循環(huán)平鋪

no-repeat?表示圖像只使用一次

function draw() {? ? var canvas = document.getElementById('canvas')? ? var context = canvas.getContext('2d')? ? var img = new Image();? ? // 使用Image()構(gòu)造函數(shù)創(chuàng)建圖像對(duì)象? ? img.src='../images/xxx'? ? // 指定圖像的文件地址? ? img.onload = function() {? ? ? ? // 繪圖模式? ? ? ? var ptrn = context.createPattern(img, 'repeat');? ? ? ? // 填充樣式? ? ? ? context.fillStyle = ptrn;? ? ? ? // 填充矩形? ? ? ? context.fillReat(0,0,500,200);? ? }}

移動(dòng)變化:

// 移動(dòng)translate(dx,dy);// 繪制function draw() {? ? var canvas = document.getElementById('canvas')? ? var context = canvas.getContext('2d')? ? // 設(shè)置移動(dòng)偏移量? ? context.translate(200, 200);? ? // 繪制一個(gè)圓形? ? ArcFace(context);}// 繪制一個(gè)圓形function ArcFace(context) {? ? // 繪制一個(gè)圓形邊框? ? context.beginPath();? ? // 繪制圓形? ? context.arc(0,0,90,0,Math.PI*2,true);? ? // 線寬? ? context.lineWidth=5;? ? // 描邊? ? context.strokeStyle='#f90';? ? context.stroke();? ? // 繪制? ? context.beginPath();? ? context.moveTo(-30, -30);? ? context.lineTo(-30, -20);? ? context.moveTo(30, -30);? ? context.lineTo(30, -20);? ? context.moveTo(-20, 30);? ? // 曲線? ? context.bezierCurveTo(-20, 44, 20, 30, 30, 20);? ? context.strokeStyle='#000';? ? context.lineWidth=10;? ? context.lineCap = 'round';? ? // 笑臉??? ? context.stroke();}

縮放變換测蹲,語法如下:

scale(sx, sy);// sx為水平方向上的縮放因子,sy為垂直方向上的縮放因子

// 示例function draw() {? ? var canvas = document.getElementById('canvas')? ? var context = canvas.getContent('2d')? ? // 移動(dòng)? ? context.translate(200,200);? ? // 縮放? ? context.scale(0.5,0.5);? ? ArcFace(context);}

旋轉(zhuǎn)變換:

rotate(angle)

// 旋轉(zhuǎn)例子function draw() {? ? var canvas = document.getElementById('canvas');? ? var context = canvas.getContext('2d')? ? context.translate(200,200);? ? // 旋轉(zhuǎn)? ? context.rotate(Math.PI/6);? ? context.scale(0.5, 0.5)? ? ArcFace(context)}

矩形變形鬼吵,語法如下:

transform(m1x,m1y,m2x,m2y,dx,dy); // 移動(dòng)扣甲,縮放,旋轉(zhuǎn)1. 移動(dòng)translate (dx, dy)2. 縮放scale (sx,sy)3. 旋轉(zhuǎn)rotate (A)

9.使用文本

繪制文本的方法:

fillText(text, x, y, maxwidth)

strokeText(texxt, x, y, maxwidth)

text表示要繪制的文本

參數(shù)x表示繪制文字的起點(diǎn)橫坐標(biāo)

參數(shù)y表示繪制文字的起點(diǎn)縱坐標(biāo)

參數(shù)maxwidth表示顯示文本的最大寬度

文本屬性表:

屬性說明

font數(shù)組字體樣式

textAlignstart,end,left,right,center

textBaselinetop,hanging,middle,alphabetic,ideographic,bottom

繪制文本

// 繪制文本示例function draw() {? ? var canvas = document.getElementById('canvas')? ? var context = canvas.getContext('2d')? ? // 填充顏色? ? context.fillStyle = '#000';? ? context.font = 'bold 12px impact';? ? // 繪制文本? ? context..fillText('達(dá)達(dá)前端齿椅,魔王哪吒', 10, 10);? ? context.strokeStyle = '#000';? ? context.font = 'bold italic 12px impact';? ? // 繪制文本? ? context.strokeText('jeskson', 10, 10);}

繪制獲取文本寬度的measureText()方法:

measureText(text)

測量文本的寬度:

function draw() {? ? var canvas = document.getElementById('canvas');? ? var context = canvas.getContext('2d');? ? context.fillStyle='#000';? ? context.font='bold 10px impact';? ? // 測量文本的寬度? ? var tm = context.measureText(txt);? ? context.fillText(txt,10,10);? ? context.fillText(tm.width, tm.width+10, 50);? ? context.strokeStyle = '#000';? ? context.font = 'bold italic 10px impact';? ? // 測量文本的寬度? ? tm = context.measureText(txt);? ? context.strokeText(txt,10,10);? ? context.strokeText(tm.width, tm.width+10, 100);}

陰影效果

陰影屬性表:

屬性說明

shadowColor使用半透明顏色

shadowOffsetX陰影的橫向位移量

shadowOffsetY陰影的縱向位移量

shadowBlur高斯模糊

狀態(tài)保存和恢復(fù)

狀態(tài)保存方法save()

狀態(tài)恢復(fù)方法restore()琉挖,恢復(fù)最后一次保存的狀態(tài)

狀態(tài)的保存和恢復(fù)是通過數(shù)據(jù)棧進(jìn)行的

10.操作像素

圖像數(shù)據(jù)對(duì)象ImageData

獲取圖像數(shù)據(jù)的方法getImageData(),用于從Canvas上下文中獲取圖像數(shù)據(jù)涣脚。getImageData(sx, sy, sw, sh);

繪制圖像數(shù)據(jù)的方法putImageData()getImageData(imagedata,dx,dy[,..])

創(chuàng)建圖像數(shù)據(jù)的方法createImageData()

繪制海報(bào)

<template> <view class="backgroundColor"> ? ? // 畫布 <canvas class="isCan" canvas-id="dadaPoster" :style="{ width: cansWh.cansWidth + 'px', height: cansWh.cansHeight + 'px' }"></canvas> // 效果圖 <image class="showImg" mode="aspectFit" v-if="tempImgShow" @longpress="longpress" :src="tempImg"></image> // 按鈕 <view v-if="tempImgShow" class="fixedBox flex flex-direction"> <view class="boxTop text-white">長按圖片發(fā)送給朋友</view> <view class="boxDown"> <button class="flexBtn" hover-class="btnHover" @click="closeCans">關(guān)閉</button> </view> </view> </view></template>data() { return { tempImgShow: false, tempImg: '', cansWh: { // 畫布寬高 cansWidth: 800, cansHeight: 900, }, qrcode: { // 舉例二維碼 top: 0.85, left: 0.035, width: 0.23, qrHeight: null, }, ... productImg: { // 產(chǎn)品圖 top: 0.1, left: 0.03, width: 1, height: 0.5, }, };},

// 繪制圖drawImg(method,param){ return new Promise((resolve, reject)=>{ if(param.url.indexOf('http') === 0){ uni.downloadFile({ url: param.url, success(res) { param.url = res.tempFilePath method(param).then(res=>{ resolve(res) }).catch(err=>{ reject(err) }) }, fail(error) { console.log(error) } }) }else{ method(param).then(res=>{ resolve(res) }).catch(err=>{ reject(err) }) } })}

// 繪制圓形drawCircle(param) {var that = this,x = param.x,y = param.y,r = param.r,url = param.url;return new Promise((resolve, reject) => { x = Math.ceil(that.cansWh.cansWidth * x); y = Math.ceil(that.cansWh.cansHeight * y); r = r > 1 ? r : Math.ceil(that.cansWh.cansWidth * r); that.ctx.save(); var d = 2 * r; var cx = x + r; var cy = y + r; that.ctx.arc(cx, cy, r, 0, 2 * Math.PI); that.ctx.clip(); that.ctx.drawImage(url, x, y, d, d); that.ctx.restore(); that.ctx.draw(true, res=>{ resolve(); });});}

// 繪制圖drawPic(item) {return new Promise((resolve, reject) => { let x, y, w, h, r; y = item.sTop <= 1 ? this.cansWh.cansHeight * item.sTop : item.sTop; w = item.sWidth <= 1 ? this.cansWh.cansWidth * item.sWidth : item.sWidth; h = item.sHeight <= 1 ? this.cansWh.cansHeight * item.sHeight : item.sHeight; if (item.sLeft == 'center') { x = item.sWidth <= 1 ? this.cansWh.cansWidth * (0.5 - item.sWidth / 2) : this.cansWh.cansWidth * 0.5 - item.sWidth / 2; } else { x = this.cansWh.cansWidth * item.sLeft; } if (item.r) { r = item.r; this.ctx.save(); if (w < 2 * r) r = w / 2; if (h < 2 * r) r = h / 2; this.ctx.beginPath(); this.ctx.moveTo(x + r, y); this.ctx.arcTo(x + w, y, x + w, y + h, r); this.ctx.arcTo(x + w, y + h, x, y + h, r); this.ctx.arcTo(x, y + h, x, y, r); this.ctx.arcTo(x, y, x + w, y, r); this.ctx.closePath(); this.ctx.clip(); this.ctx.drawImage(item.url, x, y, w, h); this.ctx.restore(); // 返回上一狀態(tài) } else { this.ctx.drawImage(item.url, x, y, w, h); } this.ctx.draw(true, res=>{ resolve(); });});}

// 保存saveCans() {let tempRatio = 1;uni.canvasToTempFilePath({x: 0,y: 0,width: this.cansWh.cansWidth * tempRatio,height: this.cansWh.cansHeight * tempRatio,destWidth: this.cansWh.cansWidth * tempRatio * 2,destHeight: this.cansWh.cansHeight * tempRatio * 2,canvasId: 'dadaPoster',success: (res) => { this.tempImg = res.tempFilePath; setTimeout(() => { this.tempImgShow = true; }, 100); uni.hideLoading();},fail: (res) => { console.log(res); uni.hideLoading();}},);}

小結(jié)

canvas標(biāo)簽的使用

// canvas標(biāo)簽的使用<canvas width="100" height="100"></canvas>// 獲取canvasvar canvas = document.getElementById('target')if(canvas.getContext) {? ? var ctx = canvas.getContext('2d');}else {? ? alert('該瀏覽器版本過低示辈,請(qǐng)更換')}// 矩形fillRect( x , y , width , height) // 填充strokeRect( x , y , width , height) // 空心clearRect( x, y , width , height ) // 清除透明 var grd = ctx.createLinearGradient( x1 ,y1 ,x2 ,y2); //線性漸變var grd = ctx.createRadialGradient(x1 ,y1 ,r1 ,x2 ,y2 ,r2);//徑向漸變

曲線

二次貝塞爾曲線quadraticCurveTo( cp1x, cp1y , x ,y )

(cp1x,cp1y) 控制點(diǎn) (x,y)結(jié)束點(diǎn)

三次貝塞爾曲線bezierCurveTo( cp1x, cp1y ,cp2x , cp2y ,x , y )(cp1x,cp1y)控制點(diǎn)1 (cp2x,cp2y) 控制點(diǎn)2 (x,y)結(jié)束點(diǎn)

HTML5繪圖制作海報(bào)

<body>? ? <img src="img/bg.png" id="img1" style="display: block" width="1200" height="800" />? ? <img src="img/dada.png" id="img2" style="display: block" width="100" height="100" />? ? <img id="img3" />? ? <button onclick="draw()" id="btn">點(diǎn)擊下載</button>? ? ? ? <script>? ? ? ? function draw() {? ? ? ? ? ? var img1 = document.getElementById("img1"),? ? ? ? ? ? var img2 = document.getElementById("img2"),? ? ? ? ? ? var img3 = document.getElementById("img3");? ? ? ? ? ? ? ? ? ? ? ? var img1.width = 1200;? ? ? ? ? ? var img1.height = 800;? ? ? ? ? ? var img2.width = 100;? ? ? ? ? ? var img2.height = 100;? ? ? ? ? ? ? ? ? ? ? ? var canvas = document.createElement("canvas"),? ? ? ? ? ? ? ? context = canvas.getContext("2d");? ? ? ? ? ? // 繪制寬度? ? ? ? ? ? canvas.width = img1.width;? ? ? ? ? ? // 繪制高度? ? ? ? ? ? canvas.height = img1.height;? ? ? ? ? ? /**? ? ? ? ? ? * context.drawImage(image,x,y,w,h)? ? ? ? ? ? * var img=new Image(); img.src="url(...)";? ? ? ? ? ? * x:繪制圖像的x坐標(biāo)? ? ? ? ? ? * y:繪制圖像的y坐標(biāo)? ? ? ? ? ? * w:繪制圖像的寬度? ? ? ? ? ? * h:繪制圖像的高度? ? ? ? ? ? */? ? ? ? ? ? ? ? ? ? ? ? context.drawImage(img1, 0, 0, img1.width, img1.height);? ? ? ? ? ? // 將 img2 加入畫布? ? ? ? ? ? context.drawImage(img2, 100, 100, img2.width, img2.height);? ? ? ? ? ? // 文字填充顏色? ? ? ? ? ? context.fillStyle = '#333';? ? ? ? ? ? // 文字字體? ? ? ? ? ? context.font = 'bold 45px 黑體';? ? ? ? ? ? // 設(shè)置文字? ? ? ? ? ? var name_text = '達(dá)達(dá)前端,魔王哪吒';? ? ? ? ? ? // 獲取文字的寬度? ? ? ? ? ? var name_width = context.measureText(name_text).width;? ? ? ? ? ? // 獲取除去文本后的一半的寬度? ? ? ? ? ? var x = (canvas.width - name_width) / 2;? ? ? ? ? ? ? ? ? ? ? ? /**? ? ? ? ? ? * context.font:設(shè)置字體樣式? ? ? ? ? ? * context.textAlign:水平對(duì)齊方式? ? ? ? ? ? * context.textBaseline:垂直對(duì)齊方式? ? ? ? ? ? * context.measureText(text):計(jì)算字體長度(px)? ? ? ? ? ? */? ? ? ? ? ? context.fillText(name_text, x, 450);? ? ? ? ? ? context.fillStyle = '#333'; // 文字填充顏色? ? ? ? ? ? context.font = '25px bold 黑體';? ? ? ? ? ? var con_1 = 'dadaqianduan';? ? ? ? ? ? var con_2 = '達(dá)達(dá)';? ? ? ? ? ? /**? ? ? ? ? ? * text:要繪制的文字? ? ? ? ? ? * x:文字起點(diǎn)的x坐標(biāo)軸? ? ? ? ? ? * y:文字起點(diǎn)的y坐標(biāo)軸? ? ? ? ? ? */? ? ? ? ? ? context.fillText(con_1, x, 400);? ? ? ? ? ? var con_width_2 = context.measureText(con_2).width;? ? ? ? ? ? context.fillText(con_2, canvas.width - x - con_width_2, 400);? ? ? ? ? ? context.stroke();? ? ? ? ? ? // 將畫布內(nèi)容導(dǎo)出? ? ? ? ? ? var src = canvas.toDataURL();? ? ? ? ? ? img3.src = src;? ? ? ? ? ? const a = document.createElement("a");? ? ? ? ? ? a.href = src;? ? ? ? ? ? a.download = '自定義.png';? ? ? ? ? ? a.click();? ? ? ? }? ? </script></body>

html5繪圖操作(html2canvas)

script引入文件html2canvas(content, { //content是將要截圖的div元素? ? scale: 2,? ? logging: false,? //在console中輸出信息? ? useCORS: true? //允許跨域? ? //proxy: string,? //代理地址? ? //timeout: number? //超時(shí)時(shí)間}).then(function(canvas) {? ? let dataUrl = canvas.toDataURL()? ? console.log(dataUrl)})

crossOrigin屬性設(shè)置成Anonymous就可以跨域? - 并不可以的哦遣蚀!

后臺(tái)解決跨域問題

轉(zhuǎn)成base64格式(后端矾麻,前端,建議前端)

html5移動(dòng)端生成海報(bào)

大致效果:

<script>varcode_model ='<div id="qrcode" style="position: fixed; opacity: 0;"></div>',// 放置二維碼canvas_model ='<canvas width="1200" height="800" style="position: fixed;opacity:0;" id="myCanvas"></canvas>',// 放置canvasposter_model ='<div class="poster_container"><div class="poster"><img src="" alt="" class="poster_img"><p class="save_poster">長按保存圖片至手機(jī)相冊(cè)</p><p style="margin-top: 0.5rem" class="aaaa"></p></div></div>';//poster_model為效果圖$("body").append(code_model, canvas_model, poster_model);$.ajax({url:"/photo/dada",data: {id: id? ? },success:function(res){? ? ? ? $.hideLoading();if(res.e ="1111") {if(!res.data.is_buy) {? ? ? ? ? ? ? ? location.href = res.data.jump_url;returnfalse;? ? ? ? ? ? }$(".poster").show();? ? ? ? ? ? vardata_base = res.data.poster_info;newQRCode('qrcode', {text: data_base.url,width:100,height:100,colorDark:'#000000',colorLight:'#ffffff',correctLevel: QRCode.CorrectLevel.H? ? ? ? ? ? });varc =document.getElementById("myCanvas"),cxt = c.getContext("2d");varimg =newImage(), imgUrl, personName = data_base.name;//跨域問題img.crossOrigin ='anonymous';? ? ? ? ? ? img.src = data_base.image;img.onload =function(){//圖片加載為異步加載cxt.drawImage(img,0,0);? ? ? ? ? ? ? ? cxt.save();? ? ? ? ? ? ? ? cxt.beginPath();cxt.arc(100,200,33,0,2*Math.PI,true);cxt.strokeStyle ='#fff';? ? ? ? ? ? ? ? cxt.stroke();? ? ? ? ? ? ? ? cxt.clip();varimg_head =newImage();img_head.crossOrigin ='anonymous';varavatar_height = data_base.avatar_height, avatar_width = data_base.avatar_width;? ? ? ? ? ? ? ? img_head.src = data_base.avatar;img_head.onload =function(){cxt.drawImage(img_head,0,0, avatar_height, avatar_width,54,520,80,80);? ? ? ? ? ? ? ? ? ? cxt.restore();varimg_code =newImage();img_code.crossOrigin ='anonymous';cxt.lineWidth ="4";cxt.strokeStyle ='#FFF';cxt.rect(80,80,400,400);? ? ? ? ? ? ? ? ? ? cxt.stroke();setTimeout(function(){img_code.src = $("#qrcode").find("img").attr("src");img_code.onload =function(){cxt.drawImage(img_code,0,0,100,100,450,450,80,80);cxt.font ='21px 黑體';cxt.fillStyle ="#000";cxt.fillText(personName,250,520);imgUrl = c.toDataURL("image/png",1);$(".poster_img").attr("src", imgUrl);$(".poster_container").show();? ? ? ? ? ? ? ? ? ? ? ? };},0);? ? ? ? ? ? ? ? };? ? ? ? ? ? };}else{$.toast(res.m,"text");? ? ? ? }? ? }});

微信小程序所使用的繪圖api

CanvasContext``canvas?組件的繪圖上下文

CanvasContext?是舊版的接口芭梯, 新版?Canvas 2D?接口與?Web?一致险耀。

string|CanvasGradient fillStyle?- 填充顏色

string|CanvasGradient strokeStyle?- 邊框顏色

number shadowOffsetX?- 陰影相對(duì)于形狀在水平方向的偏移

number shadowOffsetY?- 陰影相對(duì)于形狀在豎直方向的偏移

number shadowColor?- 陰影的顏色

number shadowBlur?- 陰影的模糊級(jí)別

number lineWidth?- 線條的寬度

string lineCap?- 線條的端點(diǎn)樣式

string lineJoin?- 線條的交點(diǎn)樣式

lineJoin

值說明

bevel斜角

round圓角

miter尖角

number miterLimit?- 最大斜接長度

number lineDashOffset?- 虛線偏移量,初始值為0

幾個(gè)相關(guān)的畫圖api 點(diǎn)這里

<view class="photoCan">? <canvas style="width: 375px; height: 612px; position:fixed; top:9999px; left:0; z-index:223;" canvas-id="mycanvas"></canvas>? <image src="{{imagePath}}" mode="widthFix"></image></view>

const app = getApp()const setText = (context, fs, color, x, y, c) => {? context.setFontSize(fs);? context.setFillStyle(color);? context.setTextAlign('left');? context.fillText(c, x, y);? context.restore();};Page({? data: {? ? imagePath:''? },? onLoad(){? ? var that=this;? ? wx.downloadFile({? ? ? url: 'https://xxxx.com/image',? ? ? success: function (res) {? ? ? ? ? that.setData({? ? ? ? ? ? ? path: res.tempFilePath? ? ? ? ? })? ? ? ? }? ? })? ? var ctx = wx.createCanvasContext('mycanvas');? ? var c_avatar = '../image/timg2.jpg';? ? var wechat = '../image/wechat.png';? ? var path = that.data.path;? ? ctx.fillStyle = "#ffe200";? ? ctx.fillRect(0, 0, 375, 612);? ? setText(ctx, 16, '#xxx', 90, 45, '達(dá)達(dá));? ? // 繪制畫報(bào)背景圖? ? ctx.drawImage(path, 30, 95, 400, 500);? ? //頭像? ? ctx.arc(45, 45, 25, 0, 2 * Math.PI)? ? ctx.strokeStyle = "#fff";? ? ctx.clip();? ? ctx.drawImage(c_avatar, 20, 20, 50, 50);? ? // 繪制生成畫報(bào)? ? ctx.draw(true, setTimeout(function () {? ? ? // 保存? ? ? wx.canvasToTempFilePath({? ? ? ? canvasId: 'mycanvas',? ? ? ? success: function (res) {? ? ? ? ? console.log(res)? ? ? ? ? var tempFilePath = res.tempFilePath;? ? ? ? ? that.setData({? ? ? ? ? ? imagePath: tempFilePath? ? ? ? ? });? ? ? ? },? ? ? ? fail: function (res) {? ? ? ? ? console.log(res);? ? ? ? }? ? ? })? ? }, 1000));? }})

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末玖喘,一起剝皮案震驚了整個(gè)濱河市甩牺,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌累奈,老刑警劉巖贬派,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異澎媒,居然都是意外死亡搞乏,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門戒努,熙熙樓的掌柜王于貴愁眉苦臉地迎上來查描,“玉大人,你說我怎么就攤上這事《” “怎么了匀油?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長勾笆。 經(jīng)常有香客問我敌蚜,道長,這世上最難降的妖魔是什么窝爪? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任弛车,我火速辦了婚禮,結(jié)果婚禮上蒲每,老公的妹妹穿的比我還像新娘纷跛。我一直安慰自己,他們只是感情好邀杏,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布贫奠。 她就那樣靜靜地躺著,像睡著了一般望蜡。 火紅的嫁衣襯著肌膚如雪唤崭。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天脖律,我揣著相機(jī)與錄音谢肾,去河邊找鬼。 笑死小泉,一個(gè)胖子當(dāng)著我的面吹牛芦疏,可吹牛的內(nèi)容都是我干的佃牛。 我是一名探鬼主播涛救,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼缚甩!你這毒婦竟也來了柒桑?” 一聲冷哼從身側(cè)響起弊决,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤噪舀,失蹤者是張志新(化名)和其女友劉穎魁淳,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體与倡,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡界逛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了纺座。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片息拜。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出少欺,到底是詐尸還是另有隱情喳瓣,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布赞别,位于F島的核電站畏陕,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏仿滔。R本人自食惡果不足惜惠毁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望崎页。 院中可真熱鬧鞠绰,春花似錦、人聲如沸飒焦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽荒给。三九已至丈挟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間志电,已是汗流浹背曙咽。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留挑辆,地道東北人例朱。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像鱼蝉,于是被迫代替她去往敵國和親洒嗤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353