(第四天)HTML5之Canvas图形绘制:图形、moveTo&lineTo&beginPath&closePath、贝塞尔曲线、渐变、缩放平移旋转及上下文状态保存及还原

Canvas图形绘制 API参考


  • 开始创建路径ctx.beginPath(),通过此方法避免前面的图形重复绘制。
  • (以圆形为例)创建圆形路径ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise)
    • x:圆心X坐标;
    • y:圆心Y坐标;
    • radius:圆半径;
    • startAngle:起始弧度,一般为0;根据情况而定;
    • endAngle:结束弧度,2 * Math.PI 表示360°;
    • anticlockwise:可选值;默认为false,即顺时针绘制;如果为 true,逆时针绘制圆弧。
  • 关闭路径ctx.closePath():将笔点返回到当前子路径起始点的方法;它尝试从当前点到起始点绘制一条直线。 如果图形已经是封闭的或者只有一个点,那么此方法不会做任何操作。

若不需要封闭非整圆,请勿使用该方法;否则会在非整圆终点至起始点绘制一条直线。

  • 设置画笔绘制样式(填充ctx.fillStyle;划线ctx.strokeStyle,线宽ctx.lineWidth。)
  • 开始绘制图形(填充ctx.fill(),划线ctx.stroke()

    
    

moveTo & lineTo & beginPath & closePath


  • moveTo(x,y):将画笔移动到x,y坐标(该坐标为第一个子路径的终点);
  • lineTo(x,y):直线连接子路径的终点到x,y坐标(只连接,不绘制);
  • beginPath():通过清空子路径列表开始一个新路径的方法。 当你想创建一个新的路径时,调用此方法;
  • closePath():从当前点到起始点绘制一条直线。 如果图形已经是封闭的或者只有一个点,那么此方法不会做任何操作。

重点:没有子路径时(即没有moveTo或lineTo时),lineTo作用与moveTo相同

代码示例:




(第四天)HTML5之Canvas图形绘制:图形、moveTo&lineTo&beginPath&closePath、贝塞尔曲线、渐变、缩放平移旋转及上下文状态保存及还原_第1张图片
上述代码示例效果图

绘制贝塞尔曲线 bezierCurve API参考


  • 参数
    • cp1x:第一个控制点的 x 轴坐标;
    • cp1y:第一个控制点的 y 轴坐标;
    • cp2x:第二个控制点的 x 轴坐标;
    • cp2y:第二个控制点的 y 轴坐标;
    • x:结束点的 x 轴坐标;
    • y:结束点的 y 轴坐标。
  • 重点:绘制beziercurve重点在于掌握cp1和cp2两个点的控制;曲线的起点为画笔的起点,曲线的终点为参数x,y的坐标,曲线的弯曲度由cp1和cp2两个点位置的牵引力决定。

    
    
    

效果图如下:


(第四天)HTML5之Canvas图形绘制:图形、moveTo&lineTo&beginPath&closePath、贝塞尔曲线、渐变、缩放平移旋转及上下文状态保存及还原_第2张图片
贝塞尔曲线示例图

Canvas的渐变


渐变过程中的颜色均使用渐变对象.addColorStop(offset,color)方法设置,多少种颜色渐变就添加多少次此方法。

  • 线性渐变LinearGradient

该渐变对象只定义渐变的起始与终点位置及渐变的角度,在该两点位置之间实现对应角度的渐变。
渐变的有效范围:在canvas范围内根据两点位置及角度决定了渐变范围。关于渐变色的角度:渐变色位于两点构成直线的垂直线范围内

1. 创建LinearGradient对象
  `var lgradient = ctx.createLinearGradient(xstart,ystart,xend,yend)`
2. 添加渐变颜色`lgradient.addColorStop(offset,color)`多少种颜色渐变就添加多少次此方法
3. 将图形绘制(`ctx.fillRect等`)在渐变对象有效的canvas范围内(非渐变对象的参数范围)


    
    

以上代码效果图如下所示:

(第四天)HTML5之Canvas图形绘制:图形、moveTo&lineTo&beginPath&closePath、贝塞尔曲线、渐变、缩放平移旋转及上下文状态保存及还原_第3张图片
LinearGradient示例图(二色渐变)
  • 径向渐变RadialGradient

该渐变对象实现射线式径向渐变,其有效范围为:通过起始圆形两边射线到结束圆形两边并相汇处

1. 创建RadialGradient对象
  `var lgradient = ctx.createRadialGradient(xstart,ystart,rstart,xend,yend,rend)`
2. 添加渐变颜色`lgradient.addColorStop(offset,color)`多少种颜色渐变就添加多少次此方法
3. 将图形绘制(`ctx.fillRect等`)在渐变对象有效范围内(非渐变对象的参数范围)


    
    

以上代码效果图如下:

(第四天)HTML5之Canvas图形绘制:图形、moveTo&lineTo&beginPath&closePath、贝塞尔曲线、渐变、缩放平移旋转及上下文状态保存及还原_第4张图片
径向渐变示例图(三色渐变)

Canvas的缩放、平移、旋转与ctx的状态保存及还原


  • 缩放:scale(x,y):x,y为缩放因子,会影响缩放对象的所有参数(如宽高、坐标、偏移量,但不影响角度);
  • 平移:translate(x,y):x,y为坐标轴的偏移量,即x表示目标x轴与当前x轴的距离,y表示目标y轴与当前y轴的距离;
  • 旋转:rotate(angle):旋转的弧度;angle = degree * (Math.PI / 180) ;degree为角度。旋转后,ctx的原坐标轴也会随着旋转,旋转后的ctx状态会导致后期绘制的图形其坐标轴也是基于旋转后的坐标轴绘制的;

注意三个方法前后顺序的变化所产生的影响。
1.translate、rotate、scale作用的是整个ctx
2.rotate的旋转的是ctx环境,是根据ctx的当前坐标轴x轴进行的,正弧度表示顺时针,反之逆时针;旋转后起始坐标轴更新到旋转后的坐标轴状态
3.translate的参数为距x轴的距离,距y轴的距离;即起始点x,y的偏移量;同样是根据ctx的当前状态坐标轴进行
translate、rotate、scale会被ctx记录状态,值会被叠加

  • ctx.save():将当前上下文状态保存,以便后期使用;以便某状态被覆盖的时候使用;
  • ctx.restore():还原至最近save的上下文状态。


    
    

以上代码效果图如下:

(第四天)HTML5之Canvas图形绘制:图形、moveTo&lineTo&beginPath&closePath、贝塞尔曲线、渐变、缩放平移旋转及上下文状态保存及还原_第5张图片
缩放、平移、旋转及状态保存还原的示例
/* translate rotate 重要知识点 */
/* 重点:
 * 1.translate、rotate、scale作用的是整个ctx
 * 2.rotate的旋转的是ctx环境,是根据ctx的当前坐标轴x轴进行的,正弧度表示顺时针,反之逆时针;旋转后起始坐标轴更新到旋转后的坐标轴状态
 * 3.translate的参数为距x轴的距离,距y轴的距离;即起始点x,y的偏移量;同样是根据ctx的当前状态坐标轴进行
 * translate、rotate、scale会被ctx记录状态,值会被叠加
 * */
var secCanvas = document.getElementById("secCanvas");
secCanvas.style.backgroundColor = "#ccc";
ctx = secCanvas.getContext("2d");
for(var i = 0; i < 2; i++) {
    ctx.beginPath();
    //标识ctx的起始点 beigin (蓝色原点)
    ctx.arc(0, 0, 5, 0, 2 * Math.PI, false);
    ctx.fill();
    //标识ctx的起始点 end
    ctx.fillStyle = "royalblue";
    //scale不影响角度,只影响宽高、坐标、偏移量
    //ctx.scale(0.9,0.9);
    var angle = 45 * (Math.PI / 180);
    //基于起点坐标轴x轴顺时针旋转45度角
    //rotate后,ctx的整个坐标轴就旋转了45度角(图中的红线为旋转后的x轴)
    ctx.rotate(angle);/*因为ctx会更新状态,所以会作用到第二次循环*/
    ctx.save(); /*保存旋转后的状态,以便下方划坐标轴用*/

    //划旋转angle弧度后的线条 beigin
    ctx.beginPath();
    ctx.moveTo(0, 0);
    //ctx已经旋转,这里获取旋转角度后对应100半径的坐标点,角度只需0即可
    var dx = Math.cos(0) * 500;
    var dy = Math.sin(0) * 500;
    ctx.lineTo(dx, dy);
    ctx.strokeStyle = "#FF0000";
    ctx.stroke();
    ctx.font = "14px Consolas";
    ctx.strokeStyle = "#228B22";
    ctx.strokeText("第"+(i+1)+"个循环旋转45度后的x坐标轴", dx, dy)
        //划旋转angle弧度后的线条 end

    //标识未translate(50,0)前的rect起始点(红色点)
    ctx.strokeText("第"+(i+1)+"个循环旋转45度后的100,0坐标点", 100, 0)
    ctx.beginPath();
    ctx.arc(100, 0, 5, 0, 2 * Math.PI, false);
    ctx.fillStyle = "#FF0000";
    ctx.fill();
    //基于起点坐标轴x,y轴的偏移距离
    ctx.translate(50, 0);
    ctx.fillRect(100, 0, 100, 50);

    //标识translate(50,0)后的rect起始点(黄色点)
    ctx.strokeText("第"+(i+1)+"个循环旋转45度且偏移50,0后的100,0坐标点", 100, 20)
    ctx.beginPath();
    ctx.arc(100, 0, 5, 0, 2 * Math.PI, false);
    ctx.fillStyle = "#ff0";
    ctx.fill();

    //旋转45度后的坐标轴
    ctx.restore(); /*还原到未translate前*/
    ctx.beginPath();
    //划第一个100,0坐标点的y轴
    //移动到第一个100,0坐标点(红色)
    ctx.moveTo(100, -100);
    ctx.lineTo(100, 100);
    ctx.stroke();
    ctx.font = "14px Arial";
    ctx.strokeText("第"+(i+1)+"个循环旋转45度后的y坐标轴", 110, -100);

    //划第二个100,0坐标点的y轴
    ctx.beginPath();
    //基于第一个100,0坐标点,x轴方向偏移50
    ctx.translate(50, 0)/*将作用于第二次循环的ctx起始点*/
        //实际moveTo(150,-100)
    ctx.moveTo(100, -100);
    ctx.lineTo(100, 100);
    ctx.stroke();
}
(第四天)HTML5之Canvas图形绘制:图形、moveTo&lineTo&beginPath&closePath、贝塞尔曲线、渐变、缩放平移旋转及上下文状态保存及还原_第6张图片
循环2次的效果图

你可能感兴趣的:((第四天)HTML5之Canvas图形绘制:图形、moveTo&lineTo&beginPath&closePath、贝塞尔曲线、渐变、缩放平移旋转及上下文状态保存及还原)