天天看点

CanvasDay04 曲线的绘制

目录

0x00 圆弧和圆角矩形

0x01 artTo() 另一种弧线绘制方法

0x02 贝塞尔曲线

0x00 圆弧和圆角矩形

思路:

CanvasDay04 曲线的绘制

代码:

window.onload = function(){
        var canvas = document.getElementById('canvas');
    
        canvas.width = 1024;
        canvas.height = 689;
    
        var ctx = canvas.getContext('2d');
        fillRoundRect(ctx,100,100,100,100,10,'red');
        strokeRoundRect(ctx,400,400,100,100,10);
    }

    function fillRoundRect(ctx,x,y,width,height,radius,fillColor){
        
        if(2*radius > width || 2*radius >height){
            return;
        }

        ctx.save();
        ctx.translate(x,y);
        pathRoundRect(ctx,width,height,radius);
        ctx.fillStyle = fillColor || "black";
        ctx.fill();
        ctx.restore();
    }

    function strokeRoundRect(ctx,x,y,width,height,radius,lineWidth,strokeColor){
        if(2*radius > width || 2*radius >height){
            return;
        }

        ctx.save();
        ctx.translate(x,y);
        pathRoundRect(ctx,width,height,radius);
        ctx.lineWidth = lineWidth || 1;
        ctx.strokeStyle = strokeColor || "black";
        ctx.stroke();
        ctx.restore(); 
    }

    function pathRoundRect(ctx,width,height,radius){

        ctx.beginPath();
        ctx.arc(width-radius,height-radius,radius,0,Math.PI/2);
        ctx.lineTo(radius,height);
        ctx.arc(radius,height-radius,radius,Math.PI/2,Math.PI);
        ctx.lineTo(0,radius);
        ctx.arc(radius,radius,radius,Math.PI,Math.PI*3/2);
        ctx.lineTo(width-radius,0);
        ctx.arc(width-radius,radius,radius,Math.PI * 3/2,Math.PI*2);
        ctx.closePath();
    }
           

0x01 artTo() 另一种弧线绘制方法

ctx.arcTo(x1,y1,x2,y2,radius);

将当前点坐标作为x0,y0的位置,开发者传入(x1,y1) (x2,y2)之后

将会形成由两个线段组成的折线。然后绘制一个和两个线段相切且半径为radius的弧线

CanvasDay04 曲线的绘制

注意:绘制的起始点坐标是(x0,y0)这时圆弧还没有开始,绘制的终止点坐标不是(x2,y2),而是线段2与圆弧的相切处

绘制一轮弯月:

效果:

思路:外圆用arc函数画,内圆用arcTo函数画

arcTo函数的半径 利用初中数学知识算出来即可

CanvasDay04 曲线的绘制

代码:

<!DOCTYPE html>
<html >
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        #canvas{
            border:1px solid black;
            position:absolute;
            left:50%;
            top:50%;
            transform: translate(-50%,-50%);
        }
    </style>
</head>
<body>
    <canvas id='canvas'></canvas>
</body>


<script>
window.onload = function(){
    var canvas = document.getElementById('canvas');
    
    canvas.width = 1024;
    canvas.height = 689;
    
    var ctx = canvas.getContext('2d');

   fillMoon(ctx,2,400,400,50,20);
}
/**
 * 绘制一轮填充的弯月
 * @ ctx 绘图上下文 
 * @ d 控制点坐标的横坐标值
 * @ x,y  弯月的位置
 * @ R 弯月的半径
 * @ rot 旋转角度 角度值
 * @ fillColor 可选
*/

function fillMoon(ctx,d,x,y,R,rot,fillColor){
    ctx.save();
    ctx.translate(x,y);
    ctx.rotate(rot * Math.PI / 180);
    ctx.scale(R,R);
    pathMoon(ctx,d);
    ctx.fillStyle = fillColor || "#fb5";
    ctx.fill();
    ctx.restore();
}
/**
 * 规划弯月的路径
 * 
*/
function pathMoon(ctx,d){
    ctx.beginPath();
    ctx.arc(0,0,1,0.5*Math.PI,1.5*Math.PI,true);
    ctx.moveTo(0,-1);
    ctx.arcTo(d,0,0,1,dis(0,-1,d,0)/d);
    ctx.closePath();
}
// 计算两点间的距离
function dis(x1,y1,x2,y2){
    return Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
}


   


</script>
</html>
           

0x02 贝塞尔曲线

二次贝塞尔曲线

ctx.moveTo(x0,y0)

ctx.quadraticCurveTo(x1,y1,x2,y2)

(x0,y0) 曲线的起始点 (x1,y1)控制点

(x2,y2)曲线的终止点

CanvasDay04 曲线的绘制

贝塞尔三次曲线:

ctx.moveTo(x0,y0);

ctx.bezierCurveTo(x1,y1,x2,y2,x3,y3);

(x1,y1)

(x2,y2)

为两个控制点

CanvasDay04 曲线的绘制
CanvasDay04 曲线的绘制