评论

canvas

canvas

canvas

1 基本用法

使用<canvas></canvas>元素,必须先设置width height ,指定绘图区域的大小。
调用getContext(),传入2d,取得2d上下文对象。
toDataURL(),可以导出图像。

<canvas id="drawing" width="200" height="200">你的浏览器不支持canvas</canvas>

2 2D上下文

2.1 填充和描边

fillStyle
strokeStyle
设置这两个值后,之后的填充和描边都会采用这两个样式,直到重新设置这两个值

let drawing = document.getElementById("drawing");
let ctx = drawing.getContext("2d")
// 设置这两个值后,之后的填充和描边都会采用这两个样式,知道重新设置这两个值
ctx.fillStyle = "#0000ff"; // 填充 蓝色
ctx.strokeStyle = "red"; // 描边 红色

2.2 绘制矩形

fillRect() 填充
strokeRect() 边框
clearRect() 清楚矩形
这三个函数都可以接受四个参数 矩形的x坐标 y坐标 宽度 高度,这些参数的单位都是像素

// 绘制矩形
ctx.fillRect(0 , 0 , 10 , 10); //  x y 宽 高
ctx.fillStyle = "red"; // 重新设置填充颜色
ctx.fillRect(10 , 10 , 10 , 10);

// 只有边框的矩形
ctx.strokeRect(20 , 20 , 10 , 10);

// 清除
ctx.clearRect(0 , 0 , 5 , 5);
ctx.clearRect(20 , 20 , 10 , 10);

2.3 绘制路径

要绘制路径,首先必须调用beginPath()方法
然后再通过下列方法来实际绘制路径:

  • arc(x , y , radius, startAngle , endAngle , counterclockwise)
    以(x , y )为圆心,radius为半径, 起始角度,结束角度 , 最后一个参数false表示顺时针,true为逆时针
  • arcTo(x1 , y1 , x2 , y2 , radius)
    从上一点绘制一条弧线到(x2,y2),并且半径为radius跨过(x1 , y1)
  • bezierCurveTo(c1x , c1y , c2x, c2y , x , y)
    从上一点绘一条曲线到(x,y) , 并以(c1x , c1y) 和(c2x,c2y)为控制点
  • lineTo(x , y)
    从上一点绘制一条直线到(x,y)
  • moveTo(x , y)
    绘图游标移动到(x,y)不画线
  • quadraticCurveTo(cx,cy,x,y)
    从上一点绘制一条二次曲线 ,到(x,y) 并以(cx,cy)为控制点
  • rect(x,y, width,height)
    从(x,y)绘制一个矩形路径,路径

创建路径后,接下来有几种可能的选择

  • 如果想绘制一条连接到路径起点的线条,用closePath()
  • 如果路径已经完成,想用fillStyle填充它,可以调用fill()方法
  • 调用stroke()对路径描边
  • clip()创建一个剪切区域
let drawing = document.getElementById("drawing");
let ctx = drawing.getContext("2d")
// 绘制一个表盘
ctx.beginPath();
ctx.arc(100 , 100 , 99 , 0  ,  2 * Math.PI , false);
ctx.moveTo( 189 , 100)
ctx.arc(100 , 100 , 89 , 0 , 2 * Math.PI , false);
ctx.moveTo( 100 , 100)
ctx.lineTo(100 , 50)
ctx.moveTo( 100 , 100)
ctx.lineTo(70 , 100)
ctx.stroke(); // 路径描边

2.4 绘制文本

主要有两个方法
fillText()
strokeText()
这些方法都接受四个参数: 文本 , x , y ,可选的最大像素宽度

这两个方法以下三个属性为基础

  • font 表示 文本样式 , 大小 ,字体 。格式类似于CSS “10px Arial”
  • textAlign 表示文本对齐方式:“start” “end” “left” “right” “center”
    建议使用"start" “end”
  • textBaseline 表示文本的基线,可能的值有
    “top” “hanging” “middle” “alphabetic” “ideographic” “bottom”
    这几个属性都有默认值。
let drawing = document.getElementById("drawing");
let ctx = drawing.getContext("2d")
ctx.strokeStyle = "#0092D8"
// 绘制一个表盘
ctx.beginPath();
ctx.arc(100 , 100 , 99 , 0  ,  2 * Math.PI , false);
ctx.moveTo( 189 , 100)
ctx.arc(100 , 100 , 90 , 0 , 2 * Math.PI , false);
// 绘制指针
ctx.moveTo( 100 , 100)
ctx.lineTo(100 , 50)
ctx.moveTo( 100 , 100)
ctx.lineTo(70 , 100)
ctx.stroke(); // 路径描边

// 文本样式
let twelve = calcNity(12);
let three = calcNity(3);
let six = calcNity(6);
let nine = calcNity(9);

ctx.font = "10px bold";
ctx.strokeText("12" , twelve.x , twelve.y , 14);

ctx.strokeText("3" , three.x , three.y , 14)
ctx.strokeText("6" , six.x , six.y , 14)
ctx.strokeText("9" , nine.x , nine.y , 14)

// 计算12 3 6 9
function calcNity(num){
    let N = 27;
    let x , y ;
    switch (num) {
        case 12 : {
            x = 100 ;
            y = N; 
            break;
        };
        case 3 : {
            x = 200 - N ;
            y = 100; 
            break;
        };
        case 6 : {
            x = 100 ;
            y = 200 - N;
            break;
        };
        case 9 : {
            x = N ;
            y = 100;
            break;
        };
    }
    return {
        x , y
    }

}

2.5 变换

可以通过如下方法修改变换矩阵。

  • ratate(angle), 围绕原点旋转图像angle角度
  • scale(scaleX , scaleY) ,缩放图像 x方向乘以scaleX , y方向乘以scaleY
  • translate(x , y) 将坐标原点移动到(x,y)
  • transform(m1_1, m1_2 , m2_1 , m2_1 , dx , dy)
    直接修改变换矩阵
  • setTransform(m1_1, m1_2 , m2_1 , m2_1 , dx , dy)

2.6 绘制图像

drawImage(image , x, y , weight , height)

2.7 阴影

2D上下文会根据一下几个属性的值,自动为形状或路径绘制出阴影

  • shadowColor
  • shadowOffsetX
  • shadowOffsetY
  • shadowBlur
let img = document.getElementById("img");
let drawing = document.getElementById("drawing");
let ctx = drawing.getContext("2d");
ctx.strokeStyle = "black";
ctx.strokeRect(0 , 0 , 200 , 200)
ctx.moveTo(0 ,100);
ctx.shadowColor = "red";
ctx.shadowOffsetX = 5;
ctx.shadowOffsetY = 5;
ctx.shadowBlur = 5;
ctx.lineTo(200 , 100);
ctx.stroke()

2.8 渐变

渐变由CanvasGradient实例表示,很容易通过2D上下文来创建和修改。

  1. 创建渐变对象
    调用createLinearGradient(startX , startY , endX , endY)
    他会创建指定大小的渐变,并返回CanvasGradient的一个实例
let grad = ctx.createLinearGradient( 0 , 0 , 100 ,100);
  1. addColorStop()指定色标
    两个参数 0~1的数值 , css颜色值
grad.addColorStop(0 , "white");
grad.addColorStop(0.5 , "red");
grad.addColorStop(1 , "red");
  1. 把fillStyle 或 strokeStyle设置为这个对象,从而使用渐变来描边或填充
ctx.strokeStyle = grad;
ctx.fillStyle = grad;
let drawing = document.getElementById("drawing");
let ctx = drawing.getContext("2d");
let grad = ctx.createLinearGradient( 50 , 50 , 100 ,100);
grad.addColorStop(0 , "white");
grad.addColorStop(0.5 , "red");
grad.addColorStop(1 , "red");
ctx.strokeStyle = grad;
ctx.fillStyle = grad;
ctx.fillRect(0 , 0 , 100 , 100)

径向渐变
createRadialGradient()
接受6个参数
起始圆的圆心(x,y),和半径
结束圆的圆心(x,y) 和半径

let img = document.getElementById("img");
let drawing = document.getElementById("drawing");
let ctx = drawing.getContext("2d");
// 同心圆
let grad = ctx.createRadialGradient(100 , 100 , 0 , 100 , 100 , 100);
grad.addColorStop(0 , "red");
grad.addColorStop(1 , "white");
ctx.fillStyle = grad;
ctx.fillRect(0 , 0 ,200 , 200)

2.9 模式

2.10 使用图像数据

getImageData(x,y,weight,height)
putImageData(imgData , 100 , 100 )

let img = document.getElementById("img");
let drawing = document.getElementById("drawing");
let ctx = drawing.getContext("2d");
let grad = ctx.createRadialGradient(100 , 100 , 0 , 100 , 100 , 100);
grad.addColorStop(0 , "red");
grad.addColorStop(1 , "white");
ctx.fillStyle = grad;
ctx.fillRect(0 , 0 ,200 , 200)

let imgData = ctx.getImageData(100 , 100, 10 , 10);
let data = imgData.data;
for(let i = 0 ; i < data.length ; i += 4){
    let red = data[i];
    let green = data[i+1];
    let blue = data[i+2];
    let alpha = data[i+3];
    let average = Math.floor((red + green + blue) / 3);

    data[i] = average;
    data[i+1] = average;
    data[i+2] = average;
}
imgData.data = data;
ctx.putImageData(imgData , 100 , 100 )

2.11 合成

globalAplha 0~1 指定所有绘制的透明度

let drawing = document.getElementById("drawing");
let ctx = drawing.getContext("2d");
ctx.fillStyle = "black";
ctx.globalAlpha = 0.5;
ctx.fillRect(0 , 0, 200 ,200)

globalCompositionOperation
表示后绘制的图形怎样与先绘制的图形结合
可能的值:

  • source-over
  • source-in
  • source-out
    等等。。。。
最后一次编辑于  2020-06-01  
点赞 0
收藏
评论

1 个评论

  • 思燕呀
    思燕呀
    2020-07-30

    绘制扇形的时候,会有概率出现fillStyle设置颜色填充不成功的情况,演变成默认填充成黑色,不知道是什么原因,你这边有遇到过吗?

    2020-07-30
    赞同
    回复
登录 后发表内容