基本介紹
創(chuàng)建<canvas>元素的時(shí)候至少要設(shè)置width height屬性康谆。這樣才能告訴瀏覽器在多大的地方進(jìn)行繪制陪每。在繪制之前首先要取到繪制的上下文态辛,使用getContext()方法可以獲取到繪制的上下文潜叛。為了確保瀏覽器對(duì)canvas的支持絮爷,最好先判斷一下瀏覽器是否支持canvas.
2D 繪制上下文
2D繪制圖形的方法包括矩形咬腕,弧形欢峰,路勁。2D上下文的坐標(biāo)原點(diǎn)在(0,0)即canvas的左上角涨共。所以的坐標(biāo)都是基于這一點(diǎn)進(jìn)行計(jì)算的纽帖。默認(rèn)情況下x的最大值是width y最大值為height
填充和描邊
2D上下文的基本繪制操作:填充和描邊即fillStyle和strokeStyle
fillSyle:代表填充的顏色,類似于backgroundColor
strokeStyle:代表邊框的顏色
繪制矩形
矩形是唯一一個(gè)可以直接在2D在上下文中繪制的圖形举反。與矩形繪制相關(guān)的方法有fillRect() strokeRect() clearRect(),這些方法都接受4個(gè)參數(shù):矩形的X參數(shù)懊直,矩形y參數(shù),矩形的寬度照筑,矩形的高度吹截。單位都是像素點(diǎn)。strokeRect創(chuàng)建的矩形有輪廓凝危,clearRect()清楚某一個(gè)區(qū)域例如
function rect() {
let drawing = document.querySelector("canvas")
if (drawing.getContext) {
console.log("11111111")
let context = drawing.getContext("2d")
context.lineWidth = 5
// context.fillStyle ="red"
context.strokeStyle = "red"
context.fillStyle = "orange"
context.fillRect(10, 10, 50, 50)
context.fillStyle = "rgba(0,0,255,0.5)"
context.fillRect(30, 30, 50, 50)
context.clearRect(40, 40, 10, 10)
}
}
繪制路徑
2D繪制上下文支持很多在畫布繪制路勁的方法波俄。通過(guò)繪制路徑和繪制復(fù)雜的形狀和圖形,繪制路徑之前必須先調(diào)用beginPath方法表示開始繪制路勁蛾默,然后在調(diào)用一下方法
arc(x,y,radius,startAngle,endAngle,counterclockwise),已坐標(biāo)(x,y)為圓心懦铺,已radius為半徑繪制一條弧線,開始角度為startAngle支鸡,結(jié)束角度為endAngle冬念,counterclockwise表示順時(shí)針還是逆時(shí)針。默認(rèn)為順時(shí)針
lineTo(x,y) 繪制一條從上一點(diǎn)到(x,y)的直線
moveTo(x,y) 不繪制線牧挣,只是把光標(biāo)繪制點(diǎn)移動(dòng)到(x,y)點(diǎn)
以上三個(gè)方法實(shí)例如下
function path() {
console.log("2222222")
let drawing = document.querySelector("canvas")
if (drawing.getContext) {
let context = drawing.getContext("2d")
context.fillStyle = "orange"
context.beginPath()
context.arc(200,200,99,0,2*Math.PI,false)
context.moveTo(294,200)
context.arc(200,200,94,0,2*Math.PI,false)
let fz = 100
context.font = fz +"px Arial"
while(context.measureText("hello wolrd").width >140) {
fz--
context.font = fz +"px Arial"
}
context.fillText("hello wolrd",10,10)
context.fillText("Font size is" +fz +"px",10,50)
context.translate(200,200)
context.rotate(2)
context.moveTo(0,0)
context.lineTo(0,-50)
context.moveTo(0,0)
context.lineTo(50,0)
context.stroke()
}
}
arcTo(x1,y1,x2,y2,ranius):以給定的半徑急前,經(jīng)由(x1,y1)繪制一條從上一點(diǎn)到(x2,y2)的弧線
function basicPathDraw(){
let drawing = document.querySelector("canvas")
if (drawing.getContext) {
var ctx=drawing.getContext("2d");
ctx.beginPath();
ctx.moveTo(20,20); // 創(chuàng)建開始點(diǎn)
ctx.lineTo(100,20); // 創(chuàng)建水平線
ctx.arcTo(150,20,150,70,50); // 創(chuàng)建弧
ctx.lineTo(150,120); // 創(chuàng)建垂直線
ctx.stroke();
}
}
bezierCurveTo
bezierCurveTo(clx,cly,c2x,c2y,x,y)以(clx,cly)和(c2x,c2y)為控制點(diǎn),繪制一條從上一點(diǎn)到(x,y)的弧線(三次曲線)
function bezierCurveTo(){
let drawing = document.querySelector("canvas")
if (drawing.getContext) {
var ctx=drawing.getContext("2d");
ctx.beginPath();
ctx.moveTo(20,20);
ctx.bezierCurveTo(20,100,200,100,200,20);
ctx.stroke();
}
}
quadraticCurveTo
quadraticCurveTo(cx瀑构,cy,x,y)以(cx,cy)為控制點(diǎn)裆针,繪制一條上一點(diǎn)到(x,y)的弧線(二次曲線)
路徑是2D上下文的主要繪制機(jī)制。通過(guò)isPointInPath(x,y)方法來(lái)判斷(x寺晌,y)是否在當(dāng)前路勁上面
繪制文本
文本和圖形的混合是最常見(jiàn)的繪制需求世吨。文本的繪制通過(guò)上下文中的fillText 和strokeText。這兩個(gè)方法都接受4參數(shù)呻征。第一個(gè)是要繪制的字符串耘婚,x坐標(biāo),y坐標(biāo)和可選的最大像素寬度陆赋。而且這兩個(gè)方法最終繪制的結(jié)果取決于上下文中的以下三個(gè)屬性
font:Css語(yǔ)法指定字體的樣式 "blod 14px"
textAlign:文本的對(duì)齊方式 "start" "end"
textBaseLine:指定文本的基線
context.fillText("Font size is" +fz +"px",10,50)
對(duì)于復(fù)雜文本的繪制是一件很難得事情沐祷,比如在特定文字繪制到指定區(qū)域嚷闭。因此2D上下文提供了用戶輔助確定文本大小的measureText()方法,該方法接受一個(gè)參數(shù)戈轿,返回一個(gè)TextMetrics對(duì)象凌受,返回對(duì)象只有一個(gè)屬性width。用法如下
let fz = 100
context.font = fz +"px Arial"
while(context.measureText("hello wolrd").width >140) {
fz--
context.font = fz +"px Arial"
}
context.fillText("hello wolrd",10,10)
context.fillText("Font size is" +fz +"px",10,50)
變換
上下文變換可以操作繪制在畫布的圖像思杯。以下方法用于改變繪制上下文圖像的變換矩陣
rotate(ange):圍繞原點(diǎn)把圖像旋轉(zhuǎn)angle弧度
scale(scaleX,scaleY) :x上乘上scaleX胜蛉,y上乘上scaleY
translate(x,y):把原點(diǎn)移動(dòng)到(x,y)。執(zhí)行這個(gè)操作之后原點(diǎn)變成了(x,y)
可以使用save()方法保存context上下文設(shè)置色乾,restroe()方法恢復(fù)之前的上下文設(shè)置
陰影
2D上下文可以根據(jù)以下屬性自動(dòng)改變相關(guān)或者路徑上面的陰影
shadowColor:CSS屬性值誊册,表示要繪制的陰影顏色
shadowOffsetX/Y:陰影相對(duì)x/y坐標(biāo)上面的偏移
shadowBlur:陰影的模糊程度
var ctx=drawing.getContext("2d");
ctx.shadowOffsetX = 5
ctx.shadowOffsetY = 5
ctx.shadowBlur = 4
ctx.shadowColor = "rgba(0,0,0,0.5)"
ctx.fillStyle = "#ff0000"
ctx.fillRect(30,30,50,50)
漸變
漸變通過(guò)CanvasGradient的實(shí)例表示。要?jiǎng)?chuàng)建一個(gè)新的線性漸變暖璧,可以調(diào)用上下文的createLinearGradient()方法案怯,該方法需要4個(gè)參數(shù),開始x坐標(biāo)澎办,開始y坐標(biāo)嘲碱,終點(diǎn)x坐標(biāo),終點(diǎn)y坐標(biāo)局蚀。調(diào)用之后會(huì)創(chuàng)建一個(gè)實(shí)例對(duì)象麦锯。有了實(shí)例對(duì)象之后,使用addColorStop()方法為漸變指定色標(biāo)琅绅。這個(gè)方法接受兩個(gè)參數(shù)扶欣,第一個(gè)參數(shù)為色標(biāo),取值為0~1,0代表第一種顏色千扶,1代表最后一種顏色料祠。
還有一種漸變使用createRadiaGradient方法創(chuàng)建。這種漸變也叫放射性漸變澎羞。這個(gè)方法接受三個(gè)參數(shù)髓绽,前三個(gè)參數(shù)賽表一個(gè)圓的圓心x,y,半徑妆绞,后三個(gè)參數(shù)代表后一個(gè)圓 圓心x,y和半徑
function radialGradient(){
let drawing = document.querySelector("canvas")
if (drawing.getContext) {
var ctx=drawing.getContext("2d");
let gradient = ctx.createRadialGradient(80,80,10,80,80,30)
gradient.addColorStop(0,"white")
gradient.addColorStop(1,"black")
ctx.fillStyle = "#ff0000"
ctx.fillRect(10,10,50,50)
ctx.fillStyle =gradient
ctx.fillRect(30,30,100,100)
}
}
數(shù)據(jù)圖像
2D上下文可以通過(guò)getImageData()方法獲取到原始圖像的數(shù)據(jù)
實(shí)例如下
function imgData(){
// let img =
// console.log(img)
let drawing = document.querySelector("canvas")
if (drawing.getContext) {
var ctx=drawing.getContext("2d");
let image = document.images[0],imageData,data,i,len,average,red,green,blue,alpha
ctx.drawImage(image,0,0)
imageData = ctx.getImageData(0,0,image.width,image.height)
data = imageData.data
for ( i = 0; i < data.length; i+=4) {
red = data[i]
green = data[i+1]
blue = data[i+2]
alpha = data[i+3]
average = Math.floor((red+green+blue)/3)
data[i] = average
data[i+1]= average
data[i+2] =average
}
imageData.data = data
ctx.putImageData(imageData,0,0)
}
}
圖形的合成
兩個(gè)圖像重疊可以使用globalCompositeOperation方法對(duì)兩個(gè)圖形進(jìn)行重疊
function gloab(){
let drawing = document.querySelector("canvas")
if (drawing.getContext) {
let ctx=drawing.getContext("2d");
ctx.fillStyle = "#ff0000"
ctx.fillRect(10,10,50,50)
ctx.globalAlpha = 0.5
// ctx.globalCompositeOperation = "source-in" //只繪制重疊部分(其他部分透明)
// ctx.globalCompositeOperation = "source-out" //只繪制新圖形不重疊部分(其他部分透明
// ctx.globalCompositeOperation = "source-atop" //舊圖不受影響梧宫,新圖只繪制重疊部分
// ctx.globalCompositeOperation = "destination-over" //新圖在舊圖s面,透明度根據(jù)舊圖決定
// ctx.globalCompositeOperation = "destination-in" //新圖在舊圖下面摆碉,只顯示重疊部分,其他部分隱藏
// ctx.globalCompositeOperation = "destination-out" //新圖和舊圖重疊部分完全透明
// ctx.globalCompositeOperation = "destination-atop" //新圖在舊圖下面脓豪,舊圖不重疊的地方透明
// ctx.globalCompositeOperation = "lighter" //新圖形與原有圖形重疊部分像素相加巷帝,變得更加亮
ctx.globalCompositeOperation = "copy" //新圖形講被擦除
ctx.fillStyle = "#00ff00"
ctx.fillRect(10,40,50,50)
ctx.globalAlpha = 0.5
}
}