Canvas 学习笔记

404 阅读4分钟

1.基本使用

<canvas width="600" height="400" id="mycanvas">
       当前浏览器版本不支持,请升级浏览器
</canvas>
<script type="text/javascript">
    //1.获取canvas元素
    const mycanvas=document.querySelector('#mycanvas')
    //2.获取画笔(上下文)
    const ctx=mycanvas.getContext('2d')
    //3.开始路径
    ctx.beginPath()
    //4.移动绘制点
    ctx.moveTo(100,100)
    //5.描述行进路径
    ctx.lineTo(200,300);
    ctx.lineTo(300,230);
    ctx.lineTo(440,290);
    ctx.lineTo(380,50);
    //6.封闭路径
    ctx.closePath()
    // 设置画笔颜色
    ctx.strokeStyle="#91d5ff"
    // 设置画笔宽度
    ctx.lineWidth=10
    //7.绘制
    ctx.stroke()
    //8.填充
    ctx.fill()
    //填充颜色
    ctx.fillStyle="#91d5ff"
</script>

2 基本设置

路径两端的样式和连接点的样式

//1.两端样式
ctx.lineCap='butt'      //默认,不突出
ctx.lineCap='round'     //圆角
ctx.lineCap='square'    //突出直角
//2.连接点
ctx.lineJoin="miter"    //默认
ctx.lineJoin="round"    //圆角
ctx.lineJoin="miter"    //直角

3 绘制图形

3.1矩形

ctx.rect(100,100,300,200)   /前2个参数是原点,后2个参数是矩形宽高
const mycanvas=document.querySelector('#mycanvas')
const ctx=mycanvas.getContext('2d')
ctx.beginPath()
ctx.rect(100,100,300,200)   //绘制了一个宽300,高200的矩形,默认填充的颜色为黑色
ctx.fill()

快速绘制矩形

const mycanvas=document.querySelector('#mycanvas')
const ctx=mycanvas.getContext('2d')
ctx.strokeRect(100,100,300,200) //路径和描边一起进行,不需要开启路径
ctx.fillRect(100,100,300,200)   //路径和填充一起进行,不需要开启路径
//清空矩形
ctx.clearRect(100,100,300,200)  //需要注意:描边的时候因为是向2边描,所有清空的时候会有残留(多清一点就好了)ctx.clearRect(90,90,400,300)

3.2 签字板

<canvas id="mycanvas" width="600" height="400"></canvas>
        <script type="text/javascript">
            const mycanvas=document.querySelector('#mycanvas')
            const ctx=mycanvas.getContext('2d')
            //绑定鼠标按下事件
            mycanvas.onmousedown=function(e){
                ctx.beginPath()
                ctx.moveTo(e.offsetX,e.offsetY)
            //绑定鼠标移动事件
            document.onmousemove=function move(e) {
                    ctx.lineTo(e.clientX-mycanvas.offsetLeft,e.clientY-mycanvas.offsetTop)
                    ctx.stroke()
                }
            }
            //绑定鼠标离开事件
            document.onmouseup=function(){
                //解绑鼠标移动事件
                document.onmousemove=null
            }
</script>

3.3 五角形

const mycanvas=document.querySelector('#mycanvas')
const ctx=mycanvas.getContext('2d')
ctx.beginPath()
let r=40    //小半径   (小半径是大半径的5分之2最合适)
let R=100   //大半径
let x=300   //中心点横坐标
let y=200   //中心点纵坐标
for (var i = 0; i < 5; i++) {
    ctx.lineTo(Math.cos((18 + i * 72 ) / 180 * Math.PI) * R + x, -Math.sin((18 + i * 72 ) / 180 * Math.PI) * R + y);
    ctx.lineTo(Math.cos((54 + i * 72 ) / 180 * Math.PI) * r + x, -Math.sin((54 + i * 72 ) / 180 * Math.PI) * r + y);
}
ctx.closePath();
ctx.fillStyle = 'red';
ctx.strokeStyle = "#fd5";
ctx.lineWidth=4
ctx.fill();
ctx.stroke();

3.4 任意多边形

/**
    * 实现任意多边形
    * x,y 中心点坐标
    * r  中心到每个角的距离
*/
function poly(ctx, x, y, r, n=5) {
    var angle = 360 / n; // 每次变化的角度
    // 开启路径
    ctx.beginPath();
    // 循环绘制 顶点
    for (var i = 0; i < n; i ++) {
        var deg = (90 + angle * i) / 180 * Math.PI;
        ctx.lineTo(x + Math.cos(deg) * r, y - Math.sin(deg) * r);
    }
    // 关闭路径
    ctx.closePath();
    // 设置颜色宽度
    ctx.lineWidth = 2;
    ctx.strokeStyle = '#000';
    ctx.fillStyle = 'transparent';
    // 填充描边
    ctx.fill();
    ctx.stroke();
}
poly(ctx, 200, 200, 100);

3.5 任意多角形

/**
    * 实现任意多角星
    * x,y 中心点坐标
    * r1  中心到每个远端的距离
    * r2  中心到每个近端的距离
    * n  边数
*/
function star(ctx, x, y, r1, r2, n=5) {
    var angle = 360 / n;  // 间隔角度
    // 开启路径
    ctx.beginPath();
    // 循环绘制
    for (var i = 0; i < n; i ++) {
        // 绘制远端点
        var angle1 = (90 + i * angle) / 180 * Math.PI;  //远端角
        ctx.lineTo(x + Math.cos(angle1) * r1, y - Math.sin(angle1) * r1);
​
        // 绘制近端点
        var angle2 = (90 + angle/2 + i * angle) / 180 * Math.PI;
        ctx.lineTo(x + Math.cos(angle2) * r2, y - Math.sin(angle2) * r2);
    }
    // 关闭路径
    ctx.closePath();
    // 设置颜色宽度
    ctx.lineWidth = 2;
    ctx.strokeStyle = '#000';
    ctx.fillStyle = 'transparent';
    // 填充描边
    ctx.fill();
    ctx.stroke();
}
star(ctx, 200, 200, 100, 40, 5, 'yellow', 6, 'red');

3.6 圆形

ctx.arc(x,y,r,startangle,endangle,是否顺时针)    
--------------------------------------------------------
ctx.beginPath()
ctx.arc(200,200,100,0,Math.PI *2)   //默认顺时针
ctx.arc(200,200,100,0,Math.PI *2,true)  //逆时针
ctx.stroke()

3.7 绘制圆角

// 绘制圆弧
ctx.beginPath();
ctx.lineTo(400, 100);// 三个点   必须加上lineTo   
ctx.arcTo(550, 100, 550, 200, 50);  //第一对参数是直角交点   第二对为圆弧终点, 最后参数为圆弧半径。

4 变换

变换都是以坐标系为参考

4.1 位移

// 位移: 位移的是坐标体系 想要对图形影响,先位移再绘制
ctx.translate(100, 100);  //x轴,y轴
ctx.fillRect(100, 100, 100, 100);

4.2 缩放

//缩放的是坐标体系 想要对图形影响,先位移再绘制
ctx.scale(2, 2);    //x轴,y轴
ctx.fillRect(0, 0, 200, 100);

4.3 旋转

// 旋转的是坐标体系 想要对图形影响,先位移再绘制
ctx.rotate(45 / 180 * Math.PI); //弧度
ctx.fillRect(0, 0, 100, 100);

4.4 绘图环境的保存和还原

一般来说,使用变换的时候,都要先保存绘图环境,然后进行操作,操作完成后在恢复绘图环境
// 1.在变换之前 保存当前的绘图环境(坐标体系)
ctx.save();
// 2.绘制图形
ctx.beginPath();
ctx.fillrect(0, 0, 200, 100);
// 3.变换之后, 恢复之前保存的坐标体系
ctx.restore();

5 案例

5.1加载图片

1.语法:ctx.drawImage(imgEle, x, y, w, h)  //imgEle:图片元素 x,y:图片原点   w,h:图片宽高
​
2.基本步骤:
① 创建 img 元素
② 指定 src 属性
③ 监听 img 元素的 load 事件
④ 触发 load 事件, 使用 ctx.drawImage(imgEle, x, y, w, h)
​
3.代码:
const imgNode=document.createElement('img')
imgNode.src='./img/aa.jpg'
imgNode.onload=function(){
    ctx.drawImage(imgNode, 0, 0, imgNode.width, imgNode.height)
}

5.2 渐变和阴影

线性渐变

//ctx.createLinearGradient(x1, y1, x2, y2);  2个坐标点决定渐变的位置
let g = ctx.createLinearGradient(100, 100, 100, 400);   
g.addColorStop(0, 'red');   //参数1:0-1   参数2:颜色值
g.addColorStop(1, 'green');ctx.fillStyle = g;      //使用渐变色填充和描边
ctx.strokeStyle = g;
ctx.fillRect(100,100,200,200)   //绘制图形

径向渐变

let g = ctx.createRadialGradient(100,200, 50, 100, 200, 100); 
//前3个参数:圆心,半径   后3个参数:圆心,半径
g.addColorStop(0, 'red');
g.addColorStop(1, 'green');
ctx.fillStyle = g; 
ctx.strokeStyle = g;
ctx.beginPath()
ctx.arc(100,200,50,0,Math.PI*2)
ctx.arc(100,200,100,0,Math.PI*2)
ctx.fill()

阴影

ctx.shadowOffsetX=10    //阴影x轴
ctx.shadowOffsetY=10    //阴影y轴
ctx.shadowColor="red"   //阴影颜色
ctx.shadowBlur=5        //阴影半径
ctx.fillRect(100,100,200,200)

5.3 文字4

ctx.font = '30px 黑体'; // 跟css font 属性相同,至少写2个
ctx.textAlign = 'center';  //start/ end / center
ctx.textBaseline = 'middle';  // middle  top  bottom
ctx.fillText('哈哈', 100, 200);

5.4 图像合成

// 目标图像: 前面就是目标图像 (代码...)
ctx.globalCompositeOperation = 'destination-out';   //值参考官网
// 源图像 :后面的图像(代码...)

\