JavaScript 练手小技巧:canvas 中 beginPath() 的重要性

例1:

<canvas id="cvs" width="400" height="400"></canvas>
var ctx = document.getElementById('cvs').getContext('2d');
ctx.beginPath();
ctx.moveTo(100,50);
ctx.lineTo(250,50);
ctx.stroke();
ctx.moveTo(100,150);
ctx.lineTo(250,150);
ctx.strokeStyle = '#f00';
ctx.stroke();

从代码来看,第一次stroke() ,画黑线。第二次 stroke() ,画红线。所以结果应该是一黑一红,两根线条。

但是,实际上是 两根红线~!!!

因为:canvas中的绘制方法(如stroke,fill),都会以“上一次beginPath”之后的所有路径为基础进行绘制。

也就是说第一条路径我们stroke了两次,第一次是黑色,第二次是红色,所以最终也是红色。

例2:

在canvas 上移动鼠标,画一根连接起点到鼠标的线条。

let c ={};
// 获取鼠标坐标
c.getPosition = function(ele){
    let mouse = {x:0,y:0};
    ele.addEventListener("mousemove",function(e){
        let { clientX,clientY }=e;
        mouse.x = clientX - ele.getBoundingClientRect().x;
        mouse.y = clientY - ele.getBoundingClientRect().y;
    });
    return mouse ;
};
let pos =  c.getPosition(cvs);     // 获取鼠标坐标

cvs.addEventListener("mousemove",function(){
        ctx.clearRect(0,0,400,400);   // 清空画布 
        ctx.moveTo(200,200);
        ctx.lineTo(pos.x,pos.y);
        ctx.stroke();
});

虽然 mousemove 的时候,情空了画布,但是 stroke 的时候,依然把以前的路径画了出来。因为,如果么有 beginPath(),stroke 会绘制之前的所有路径

但是,在 mousemove 的时候,添加了 beginPath,每次就只画 beginPath 之后的一根线条。

let c ={};
// 获取鼠标坐标
c.getPosition = function(ele){
    let mouse = {x:0,y:0};
    ele.addEventListener("mousemove",function(e){
        let { clientX,clientY }=e;
        mouse.x = clientX - ele.getBoundingClientRect().x;
        mouse.y = clientY - ele.getBoundingClientRect().y;
    });
    return mouse ;
};
let pos =  c.getPosition(cvs);     // 获取鼠标坐标

cvs.addEventListener("mousemove",function(){
        ctx.clearRect(0,0,400,400);   // 清空画布 
        ctx.beginPath();  // 重要:启动路径
        ctx.moveTo(200,200);
        ctx.lineTo(pos.x,pos.y);
        ctx.stroke();
});

总结:

每次 canvas 绘图之前,建议都加上 beginPath() 。

说到beginPath,就不得不提到closePath。

初学者会往往会认为两者有很“紧密”的联系。一个开始,一个“闭合”。可惜,实际上它们几乎没有关系。

closePath的意思不是结束路径,而是“闭合”路径,它会试图从当前路径的终点连到当前路径的起点,让整个路径闭合起来。

但是,这并不意味着它之后的路径就是新路径了!

猜你喜欢

转载自blog.csdn.net/weixin_42703239/article/details/113576246