html5Canvas的知識點,是程序員開發者必備技能,在實際工做中也經常會涉及到。css
最近熬夜總結html5Canvas相關的知識點,你們一塊兒看一下吧:html
Canvas使用的場景有:1,動畫;2,H5遊戲;3,圖表。前端
效果動畫,加載Loading:
html5
H5遊戲效果:
git
對於Canvas須要掌握:程序員
使用Canvas畫基本圖形
Canvas座標體系
畫直線,矩形和原型
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
描邊和填充樣式
Canvas中的圖形變換,漸變,文字和圖片
Canvas中的圖形變換
圖形變換都是針對座標系來講的:github
ctx.translate(x,y)
ctx.rotate(rad)
ctx.scale(x,y)
save和restore
用來保存和恢復上下文的環境ctx,通常成對出現ajax
ctx.save()
,保存當前上下文環境。ctx.restore()
,恢復到上一次的上下文環境Canvas中的漸變
ctx.createLinearGradient(xStart,yStart,xEnd,yEnd)
(xStart,yStart)
是線段的起點,(xEnd,yEnd)
是線段終點。起點到終點之間的顏色呈漸變。canvas
gradient.addColorStop
能夠來控制漸變的顏色ctx.createRadialGradient(xStart,yStart, radiusStart,xEnd,yEnd,radiusEnd);
小程序
(xStart,yStart)
是第一個圓的原心,radiusStart
是第一個圓的半徑,(xEnd,yEnd)
是第二個圓的原心,radiusEnd
是第二個圓的半徑
第一圓到第二個圓之間的顏色呈現漸變。
Canvas中的文字
描邊文字:ctx.strokeText(text,x,y)
填充文字:ctx.fillText(text,x,y);
設置字體樣式:ctx.font
ctx.font="bold 100px sans-serif"
ctx.textAlign
設置垂直對齊方式:ctx.textBaseline
ctx.measuerText(text).width
須在設置字體樣式以後計算Canvas圖片
繪製圖片3種方法
ctx.drawImage(image,x,y)
,該方法把圖片繪製在(x,y)
處ctx.drawImage(image,x,y,w,h)
,該方法把圖片繪製在(x,y)
處,並縮放爲寬w,高hctx.drawImage(image,sx,sy,sw,sh,dx,dy,dw,dh)
,該方法把圖片中(sx,sy)
處的寬sw,高sh的區域,繪製到(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圖形畫刷
ctx.createPattern
能夠建立一個畫刷模式,進而能夠設置到fillStyle裏,進行畫刷的填充。
ctx.createPattern(image,type)
type取值:
no-repeat
不平鋪repeat-x
橫方向平repeat-y
縱方向平鋪repeat
全方向平鋪Canvas像素操做
var imageData = ctx.getImageData(x,y,w,h) 返回的是一維數組:[r1,g1,b1,a1,r2,g2,b2,a2...]
ctx.putImageData(imageData,x,y) 把imageData放在(x,y)處
ctx.putImageData(imageData, x, y, dirtyX, dirtyY, dirtyW, dirtyH) 只顯示(dirtyX,dirtyY)處的寬dirtyW,dirtyH的區域
Canvas陰影繪製
ctx.shadowOffsetX:
陰影x方向的偏移距離ctx.shadowOffsetY:
陰影y方向的偏移距離ctx.shadowColor:
陰影的顏色ctx.shadowBlur:
陰影的模糊半徑效果圖:
Canvas剪輯區域
Canvas繪製曲線
狐線:
context.arc(x,y,radius, starAngle,endAngle, anticlockwise) 圓心(x,y) 半徑radius 從starAngle到endAngle anticlockwise表明是否逆時針方向
生成工具
Canvas Quadratic Curve Example
http://blogs.sitepointstatic....
http://blogs.sitepointstatic....
二次樣條曲線:
context.quadraticCurveTo(qcpx,qcpy, qx,qy)
貝塞爾曲線:
context.bezierCurveTo(cp1x,cp1y, cp2x, cp2y, x,y)
ctx.clearRect(x,y, width,height)
清除(x,y)
點起, 寬width,高height的區域,用於從新繪製
離屏技術是什麼:經過在離屏Canvas中繪製元素,再複製到顯示Canvas中,從而大幅提升性能的一種技術。
使用離屏技術:
離屏技術:
一個Canvas中的圖形繪製到另外一個Canvas方法:
ctx.drawImage(canvas,x,y),該方法把canvas繪製在(x,y)處 ctx.drawImage(canvas,x,y, w,h),該方法把canvas繪製在(x,y)處,並縮放爲寬w,高h ctx.drawImage(canvas, sx, sy, sw, sh, dx, dy, dw, dh),該方法把canvas中(sx, sy)處的寬sw,高sh的區域,繪製到(dx,dy)處,並縮放爲寬dw, 高dh
對canvas插件的相關了解
什麼是Canvas插件,掌握Chart.js插件,瞭解Chartist.js和HighCharts.js插件
(圖表)Chart.js插件:https://www.chartjs.org/
Chartist.js插件是一個簡單的響應式圖表插件:支持SVG格式(http://gionkunz.github.io/cha...)
HighCharts.js插件:方便快捷的HTML5交互性圖標庫:https://www.highcharts.com/
Chartist.js插件與HighCharts.js插件
響應式佈局,它的用戶體驗友好,響應式網站能夠根據不一樣終端,不一樣尺寸和不一樣應用環境,自動調整界面佈局,展現內容,提供很是好的視覺效果。響應式佈局就是一個網站可以兼容多個終端
示例:
<style> #canva { border: 1px solid red; } </style> <div> <canvas id="canva" width="200" height="200"></canvas> // 繪製寬高200的canvas </div>
在開始繪圖時,先要獲取Canvas元素的對象,在獲取一個繪圖的上下文。
獲取Canvas對象 ,使用document對象的getElementById()方法獲取。
var canvas = document.getElementById("canvas") 可使用經過標籤名稱來獲取對象的getElementsByTagName方法
使用getContext()方法來獲取
var context = canvas.getContext("2d")
context.font="98px 黑體"; // 文字樣式 context.fillStyle="red"; // 文字顏色 context.textAlign = "center"; // 文字對齊方式 // 繪製文字 context.fillText("達達前端",100, 123, 234);
繪製圖像:
使用drawImage()方法能夠將圖像添加到Canvas畫布中,繪製一幅圖像,須要有三個重載的方法:
使用:
drawImage(image, x, y) // 在畫布上定位圖像 // 方法在畫布上繪製圖像、畫布或視頻。 // 方法也可以繪製圖像的某些部分,以及/或者增長或減小圖像的尺寸。 drawImage(image, x, y, width, height) // 在畫布上定位圖像,並規定圖像的寬度和高度 drawImage(image, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight) // 剪切圖像,並在畫布上定位被剪切的部分
參數:
參數 | 描述 |
---|---|
image | 規定要使用的圖像,畫布或視頻 |
sourceX | 開始剪切的x座標位置 |
sourceY | 開始剪切的y座標位置 |
sourceWidth | 被剪切圖像的寬度 |
sourceHeight | 被剪切圖像的高度 |
destX | 在畫布上放置圖像的 x 座標位置 |
destY | 在畫布上放置圖像的 y 座標位置 |
destWidth | 要使用的圖像的寬度 |
destHeight | 要使用的圖像的高度 |
插入圖像:
function Draw() { // 獲取canvas對象 var canvas = document.getElementById("canvas"); // 獲取2d上下文繪圖對象 var context = canvas.getContext("2d"); // 使用Image()構造函數建立圖像對象 var newImg = new Image(); // 指定圖像的文件地址 newImg.src = "../images/dadaqianduan.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); } }
在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"); // 設置字體 context.font="98px 黑體"; // 填充 context.fillStyle="#036"; // 文本水平位置 context.textAlign="center"; // 執行繪製 context.fillText("達達前端",100, 120, 200); </script>
兩個方法:
繪製矩形邊框,使用strokeStyle方法:
// 繪製矩形邊框 strokeRect(x,y, width, height);
填充矩形區域,使用fillRect()方法:
// 填充矩形區域 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方法,能夠擦除指定的矩形區域:
// 擦除指定的矩形區域 context.clearRect(x,y,width,height)
在實際開發中,畫布是默認300*150的大小。
示例:
// 爲畫布設置邊框 canvas { border: 1px solid #ccc; } // 準備畫布,默認是300*150 // 設置畫布的大小 <canvas width="1200" height="800"></canvas> // 準備繪製工具 <script> // 獲取元素 var myCanvas = document.querySelector('canvas'); // 獲取上下文,繪製工具箱 var ctx = myCanvas.getContext('2d'); // 移動畫筆 ctx.moveTo(100,100); // 繪製直線,軌跡 ctx.lineTo(200,100); // 描邊 ctx.stroke()
向 HTML5 頁面添加 canvas 元素
// 規定元素的 id、寬度和高度 <canvas id="myCanvas" width="200" height="100"></canvas>
須要理解些概念:
路徑的繪製
stroke()
fill()
閉合路徑
closePath()
beginPath()
畫筆的狀態
1px
(butt默認)、round、square
miter(默認)、round、bevel
setLineDash()
設置虛線getLineDash()
獲取虛線寬度集合lineDashOffset
設置虛線偏移量(負值向右偏移)rect(x,y,w,h)
沒有獨立路徑strokeRect(x,y,w,h)
有獨立路徑,不影響別的繪製fillRect(x,y,w,h)
有獨立路徑,不影響別的繪製clearRect(x,y,w,h)
擦除矩形區域arc()
startAngle
開始角度endAngle
結束角度anticlockwise
是否逆時針方向繪製(默認false表示順時針;true表示逆時針)ctx.font
= '微軟雅黑' 設置字體strokeText()
fillText(text,x,y,maxWidth)
ctx.textAlign
文本水平對齊方式,相對繪製座標來講的
ctx.direction
屬性css(rtl ltr) start和end
於此相關
ltr,start和left
表現一致rtl,start和right
表現一致ctx.textBaseline
設置基線(垂直對齊方式 )
measureText()
獲取文本寬度obj.widthdrawImage()
三個參數drawImage(img,x,y)
五個參數drawImage(img,x,y,w,h)
九個參數drawImage(img,x,y,w,h,x1,y1,w1,h1)
平移 移動畫布的原點
translate(x,y)
參數表示移動目標點的座標縮放
scale(x,y)
參數表示寬高的縮放比例旋轉
rotate(angle)
參數表示旋轉角度建立繪圖路徑
使用方法:beginPath()和closePath()
,分別表示開始一個新的路徑和關閉當前的路徑
rect(x,y, width, height)
:xy,起點座標,矩形的寬高,繪製矩形路徑closePath方法關閉當前路徑
stokeStyle
屬性設置矩形邊框的顏色lineWidth
屬性設置邊框的寬度fillStyle
屬性設置填充的顏色繪製網格,網格大小
var grid = 10; // 畫多少條x軸方向的線,橫向的條數,畫布的高度 var canvasHeight = myCanvas.height var canvasWidth = myCanvas.width // 畫布寬高 ctx.canvas.width ctx.canvas.height // 網格大小 var gridSize = 10; var canvasHeight = ctx.canvas.height; var xLineTotal = canvasHeight / gridSize // 總線條 var xLineTotal = Math.floor(canvasHeight / gridSize); for (var i=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軸方向的線 var yLineTotal = canvasWidth / gridSize var yLineTotal = Math.floor(canvasWidth / gridSize); for (var i=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(); }
繪製座標系,肯定圓點,肯定離畫布旁邊的距離,肯定座標軸的長度,肯定箭頭的大小,繪製箭頭填充。
// 繪製座標系 var space = 20; var arrowSize = 10; // 畫布寬高 var canvasWidth = ctx.canvas.width; var canvasHeight = ctx.canvas.height; // 座標系 var x0 = space; var y0 = 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(); // 繪製點 var coordinate = { x: 146, y: 356 } // 點尺寸 var dottedSize = 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建立一個矩形,最後調用stroke()方法和fill()方法
// 圓形 context.arc(100,100,30,0,Math.PI*2,true);
使用beginPath()方法能夠新建立一個子路徑,closePath()方法用來閉合路徑的。
繪製兩條直線
function DrawLine() { var canvas = document.getElementById("canvas"); var context = canvas.getContext("2d"); // 建立繪製過程 context.beginPath(); context.moveTo(50,50); context.lineTo(120,120); context.lineTo(120,60); context.closePath(); context.strokeStyle="#000"; // 執行繪製 context.stroke(); }
若是不用beginPath()
方法,繪製圖形時再也不建立子路徑,第一次的圖形在執行過程當中會被繪製填充兩次。
圖形組合
屬性 globalCompositeOperation
設置如何在畫布上組合顏色
12中組合類型:
值 | 說明 |
---|---|
copy | 只繪製新圖形,刪除其餘全部內容 |
darker | 在圖形重疊的地方,顏色由兩個顏色值相減後決定 |
destination-atop | 已有的內容只在它和新的圖形重疊的地方保留,新圖形繪製在內容後 |
destination-in | 在新圖形和已有畫布重疊的地方,已有內容都保留,全部其餘內容成爲透明 |
destination-out | 在新圖形和已有內容不重疊的地方,已有內容保留全部其餘內容成爲透明 |
destination-over | 新圖形繪製於已有內容的後面 |
lighter | 在圖形重疊的地方,顏色由兩種顏色值的疊加值來決定 |
source-atop | 只在新圖形和已有內容重疊的地方纔繪製新圖形 |
source-in | 在新圖形和已有內容重疊的地方,新圖形纔會被繪製,全部其餘內容成爲透明 |
source-out | 只在和已有圖形不重疊的地方繪製新圖形 |
source-over | 新圖形繪製於已有圖形的頂部 |
xor | 在重置和正常繪製的其餘地方,圖形都成爲透明 |
繪製曲線
// 圓形,曲線 arc(x, y, radius, startAngle, endAngle, counterclockwise);
x,y
表示弧的圓形的圓心座標radius
表示弧的圓形的半徑startAngle
表示圓弧的開始點的角度endAngle
表示圓弧的結束點的角度counterclockwise
若true表示逆時針,false反之順時針<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); // 關閉 context.closePath(); // 填充顏色 context.fillStyle = 'rgb(255,255,255)'; context.fill(); </script>
若是使用css
設置寬高,畫布會按照300*150
的比例進行縮放,將300*150
的頁面顯示在400*400
的容器中。
// 設置畫布寬度 var cx = canvas.width = 400; var cy = canvas.height = 400;
使用js動態設置寬高。
建議使用HTML中的width和height,或者js動態設置寬高
建立一個canvas標籤,第一步:
// 獲取這個canvas的上下文對象 var canvas = document.getElementById('canvas'); var context = canvas.getContext('2d');
方法:
fill()
填充路徑stroke()
描邊arc()
建立圓弧rect()
建立矩形fillRect()
繪製矩形路徑區域strokeRect()
繪製矩形路徑描邊clearRect()
在給定的矩形內清除指定的像素beginPath()
起始一條路徑,或重置當前路徑moveTo()
把路徑移動到畫布中的指定點,不建立線條lineTo()
添加一個新點,在畫布中建立從該點到最後指定點的線條clip()
從原始畫布剪切任意形狀和尺寸的區域arcTo()
建立兩切線之間的弧/曲線quadraticCurveTo()
建立二次方貝塞爾曲線bezierCurveTo()
建立三次方貝塞爾曲線isPointInPath()
若是指定的點位於當前路徑中,則返回 true,不然返回 false輔助線繪製弧線:arcTo()
方法
語法:
// 輔助線繪製弧線 arcTo(x1, y1, x2, y2, radius)
arcTo()方法繪製一條弧線
代碼:
// 繪製一條弧線 function draw() { var canvas = document.getElementById('canvas'); var context = canvas.getContext('2d'); // 開始繪製 context.beginPath(); // 移動點 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描述了控制點的座標,x, y描述了曲線的終點座標
bezierCurveTo()
方法:它是應用於二維圖形應用程序的數學曲線。
bezierCurveTo(cp1X, cp1Y, cp2X, cp2Y, x, y); // cp1X, cp1Y 表示第一個控制點的座標 // cp2X, cp2Y 表示第二個控制點的座標 // x, y表示曲線的終點座標
繪製曲線:
function draw() { // 繪製曲線 var canvas = document..getElementById('canvas'); var context = canvas.getContext('2d'); // 開始繪製 context.beginPath(); // 移動 context.moveTo(100,180); // 連線 context.lineTo(110,80); context.moveTo(260,100); context.lineTo(300,200); // 描邊 context.strokeStyle="rgba(0,0,0,0.4)"; // 設置寬度 context.lineWidth=3; context.stroke(); context.beginPath(); context.moveTo(100,180); // 繪製貝濟埃曲線 context.bezierCurveTo(110,80,260,100,300,200); // 設置寬度 context.lineWidth = 3; context.strokeStyle="rgba(255,135,0,1)"; context.stroke(); }
var canvas = document.getElementById('canvas'); var context = canvas.getContext('2d'); // 畫布寬度200 var canX = canvas.width = 200 var canY = 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
設置或返回線條的結束斷點樣式lineJoin
設置或返回兩條線相交時,產生拐角類型lineWidth
設置或返回當前的線條寬度miterLimit
設置或返回最大斜接長度fillRect()
繪製一個實心矩形strokeRect()
繪製一個空心矩形設置陰影,shadowBlur
-context.shadowBlur
= 20
createLinearGradient()
建立線性漸變createPattern()
在指定的方向上重複指定的元素createRadialGradient()
建立放射狀/環形的漸變addColorStop()
規定漸變對象中的顏色和中止位置gradient.addColorStop(stop,color)
scale()
縮放當前繪圖變大或變小rotate()
旋轉當前繪圖translate()
從新映射畫布的(0,0)位置使用三種方法插入圖像
function draw() { var canvas = document.getElementById('canvas'); var context = canvas.getContext('2d'); // image實例 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); } }
在插入圖像以前,須要考慮 圖像加載的時間,若是圖像沒加載完成就已經執行drawImage()方法,就不會顯示任何圖片。
提供了兩種漸變的建立的方法:
// 建立線性漸變 createLinearGradient()方法 // 建立徑向漸變 createRadialGradient()方法
設置漸變顏色和過渡方式
語法以下:
表示漸變的開始點和結束點之間的一部分
addColorStop(offset, color);
function draw() { var canvas = document.getElementById('canvas') var context = canvas.getContext('2d') // 建立漸變對象,線性漸變 var grd = context.createLinearGradient(0,0,300,0) // 設置漸變顏色 grd.addColorStop(0, '#xxx'); // 設置顏色 grd.addColorStop(1, '#xxx'); // 設置顏色 // 將填充樣式設置爲線性漸變對象 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); // 設置漸變顏色以及方式 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
,當線條具備必定的寬度才能表現出來。
butt // 定義了線段沒有線帽 round // 定義了線段的末端爲一個半圓形的線帽 square // 定義了線段的末端爲一個矩形的線帽
線條的鏈接屬性lineJoin
,用於兩條線條到的鏈接方式:
miter
兩條線段的外邊緣一直延伸到它們相交,屬性miterLimit是用來描述如何繪製兩條線段的交點,是表示延伸長度和線條長度的比值。
默認爲10,只有miter
使用時有效
lineJoin = [value]; round // 兩條線段的外邊緣應該和一個填充的弧結合 bevel // 兩條線段的外邊緣應該和一個填充的三角形相交
語法以下:
createPattern(image, repetitionStyle)
repeat
表示圖像在各個方向上循環平鋪repeat-x
表示圖像在橫向上循環平鋪repeat-y
表示圖像在縱向上循環平鋪no-repeat
表示圖像只使用一次function draw() { var canvas = document.getElementById('canvas') var context = canvas.getContext('2d') var img = new Image(); // 使用Image()構造函數建立圖像對象 img.src='../images/xxx' // 指定圖像的文件地址 img.onload = function() { // 繪圖模式 var ptrn = context.createPattern(img, 'repeat'); // 填充樣式 context.fillStyle = ptrn; // 填充矩形 context.fillReat(0,0,500,200); } }
移動變化:
// 移動 translate(dx,dy); // 繪製 function draw() { var canvas = document.getElementById('canvas') var context = canvas.getContext('2d') // 設置移動偏移量 context.translate(200, 200); // 繪製一個圓形 ArcFace(context); } // 繪製一個圓形 function ArcFace(context) { // 繪製一個圓形邊框 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') // 移動 context.translate(200,200); // 縮放 context.scale(0.5,0.5); ArcFace(context); }
旋轉變換:
rotate(angle)
// 旋轉例子 function draw() { var canvas = document.getElementById('canvas'); var context = canvas.getContext('2d') context.translate(200,200); // 旋轉 context.rotate(Math.PI/6); context.scale(0.5, 0.5) ArcFace(context) }
矩形變形,語法以下:
transform(m1x,m1y,m2x,m2y,dx,dy); // 移動,縮放,旋轉 1. 移動translate (dx, dy) 2. 縮放scale (sx,sy) 3. 旋轉rotate (A)
繪製文本的方法:
fillText(text, x, y, maxwidth)
strokeText(texxt, x, y, maxwidth)
text
表示要繪製的文本maxwidth
表示顯示文本的最大寬度文本屬性表:
屬性 | 說明 |
---|---|
font | 數組字體樣式 |
textAlign | start,end,left,right,center |
textBaseline | top,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('達達前端,魔王哪吒', 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 | 高斯模糊 |
狀態保存和恢復
save()
restore()
,恢復最後一次保存的狀態狀態的保存和恢復是經過數據棧進行的
ImageData
getImageData()
,用於從Canvas
上下文中獲取圖像數據。getImageData(sx, sy, sw, sh);
putImageData()
getImageData(imagedata,dx,dy[,..])
createImageData()
<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">長按圖片發送給朋友</view> <view class="boxDown"> <button class="flexBtn" hover-class="btnHover" @click="closeCans">關閉</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: { // 產品圖 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(); // 返回上一狀態 } 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(); } }, ); }
// canvas標籤的使用 <canvas width="100" height="100"></canvas> // 獲取canvas var canvas = document.getElementById('target') if(canvas.getContext) { var ctx = canvas.getContext('2d'); }else { alert('該瀏覽器版本太低,請更換') } // 矩形 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) 控制點 (x,y)結束點
bezierCurveTo( cp1x, cp1y ,cp2x , cp2y ,x , y )
(cp1x,cp1y)控制點1 (cp2x,cp2y) 控制點2 (x,y)結束點
<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">點擊下載</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座標 * y:繪製圖像的y座標 * 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 黑體'; // 設置文字 var name_text = '達達前端,魔王哪吒'; // 獲取文字的寬度 var name_width = context.measureText(name_text).width; // 獲取除去文本後的一半的寬度 var x = (canvas.width - name_width) / 2; /** * context.font:設置字體樣式 * context.textAlign:水平對齊方式 * context.textBaseline:垂直對齊方式 * context.measureText(text):計算字體長度(px) */ context.fillText(name_text, x, 450); context.fillStyle = '#333'; // 文字填充顏色 context.font = '25px bold 黑體'; var con_1 = 'dadaqianduan'; var con_2 = '達達'; /** * text:要繪製的文字 * x:文字起點的x座標軸 * y:文字起點的y座標軸 */ 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(); // 將畫布內容導出 var src = canvas.toDataURL(); img3.src = src; const a = document.createElement("a"); a.href = src; a.download = '自定義.png'; a.click(); } </script> </body>
script引入文件 html2canvas(content, { //content是將要截圖的div元素 scale: 2, logging: false, //在console中輸出信息 useCORS: true //容許跨域 //proxy: string, //代理地址 //timeout: number //超時時間 }).then(function(canvas) { let dataUrl = canvas.toDataURL() console.log(dataUrl) })
crossOrigin
屬性設置成Anonymous
就能夠跨域? - 並不能夠的哦!
base64
格式(後端,前端,建議前端)大體效果:
<script> var code_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>', // 放置canvas poster_model = '<div class="poster_container"><div class="poster"><img src="" alt="" class="poster_img"><p class="save_poster">長按保存圖片至手機相冊</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; return false; } $(".poster").show(); var data_base = res.data.poster_info; new QRCode('qrcode', { text: data_base.url, width: 100, height: 100, colorDark: '#000000', colorLight: '#ffffff', correctLevel: QRCode.CorrectLevel.H }); var c = document.getElementById("myCanvas"), cxt = c.getContext("2d"); var img = new Image(), 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(); var img_head = new Image(); img_head.crossOrigin = 'anonymous'; var avatar_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(); var img_code = new Image(); 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"); } } }); </script>
CanvasContext
`canvas` 組件的繪圖上下文
CanvasContext
是舊版的接口, 新版 Canvas 2D
接口與 Web
一致。
string|CanvasGradient fillStyle
- 填充顏色string|CanvasGradient strokeStyle
- 邊框顏色number shadowOffsetX
- 陰影相對於形狀在水平方向的偏移number shadowOffsetY
- 陰影相對於形狀在豎直方向的偏移number shadowColor
- 陰影的顏色number shadowBlur
- 陰影的模糊級別number lineWidth
- 線條的寬度string lineCap
- 線條的端點樣式string lineJoin
- 線條的交點樣式lineJoin
值 | 說明 |
---|---|
bevel | 斜角 |
round | 圓角 |
miter | 尖角 |
number miterLimit
- 最大斜接長度number lineDashOffset
- 虛線偏移量,初始值爲0幾個相關的畫圖api 點這裏
<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, '達達); // 繪製畫報背景圖 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); // 繪製生成畫報 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)); } })
好了各位,以上就是這篇文章的所有內容,能看到這裏的人都是人才。我後面會不斷更新網絡技術相關的文章,若是以爲文章對你有用,歡迎給個「贊」,也歡迎分享,感謝你們 !!