• html5 canvas 笔记四(变形 Transformations)


    绘制复杂图形必不可少的方法

    • save()  保存 canvas 状态
    • restore()  恢复 canvas 状态

    Canvas 的状态就是当前画面应用的所有样式和变形的一个快照。

    Canvas 的状态是以堆(stack)的方式保存的,每一次调用 save 方法,当前的状态就会被推入堆中保存起来。

    实例:

     1 function draw() {
     2   var ctx = document.getElementById('canvas').getContext('2d');
     3 
     4   ctx.fillRect(0,0,150,150);   // Draw a rectangle with default settings
     5   ctx.save();                  // Save the default state
     6 
     7   ctx.fillStyle = '#09F'       // Make changes to the settings
     8   ctx.fillRect(15,15,120,120); // Draw a rectangle with new settings
     9 
    10   ctx.save();                  // Save the current state
    11   ctx.fillStyle = '#FFF'       // Make changes to the settings
    12   ctx.globalAlpha = 0.5;    
    13   ctx.fillRect(30,30,90,90);   // Draw a rectangle with new settings
    14 
    15   ctx.restore();               // Restore previous state
    16   ctx.fillRect(45,45,60,60);   // Draw a rectangle with restored settings
    17 
    18   ctx.restore();               // Restore original state
    19   ctx.fillRect(60,60,30,30);   // Draw a rectangle with restored settings
    20 }

    移动 Translating

    • translate(x, y)  x 是左右偏移量,y 是上下偏移量

    实例:调用 drawSpirograph 方法 9 次,用了 2 层循环。每一次循环,先移动 canvas ,画螺旋图案,然后恢复到原始状态。

     1 function draw() {
     2   var ctx = document.getElementById('canvas').getContext('2d');
     3   ctx.fillRect(0,0,300,300);
     4   for (var i=0;i<3;i++) {
     5     for (var j=0;j<3;j++) {
     6       ctx.save();
     7       ctx.strokeStyle = "#9CFF00";
     8       ctx.translate(50+j*100,50+i*100);
     9       drawSpirograph(ctx,20*(j+2)/(j+1),-8*(i+3)/(i+1),10);
    10       ctx.restore();
    11     }
    12   }
    13 }
    14 function drawSpirograph(ctx,R,r,O){
    15   var x1 = R-O;
    16   var y1 = 0;
    17   var i  = 1;
    18   ctx.beginPath();
    19   ctx.moveTo(x1,y1);
    20   do {
    21     if (i>20000) break;
    22     var x2 = (R+r)*Math.cos(i*Math.PI/72) - (r+O)*Math.cos(((R+r)/r)*(i*Math.PI/72))
    23     var y2 = (R+r)*Math.sin(i*Math.PI/72) - (r+O)*Math.sin(((R+r)/r)*(i*Math.PI/72))
    24     ctx.lineTo(x2,y2);
    25     x1 = x2;
    26     y1 = y2;
    27     i++;
    28   } while (x2 != R-O && y2 != 0 );
    29   ctx.stroke();
    30 }

    旋转 Rotating

    • rotate(angle)  旋转的角度(angle),它是顺时针方向的。

      旋转的中心点始终是 canvas 的原点,如果要改变它,我们需要用到 translate 方法。

    1.  角度转弧度: π/180×角度
    2.  弧度变角度: 180/π×弧度

    实例:

     1 function draw() {
     2   var ctx = document.getElementById('canvas').getContext('2d');
     3   ctx.translate(75,75);
     4 
     5   for (var i=1;i<6;i++){ // Loop through rings (from inside to out)
     6     ctx.save();
     7     ctx.fillStyle = 'rgb('+(51*i)+','+(255-51*i)+',255)';
     8 
     9     for (var j=0;j<i*6;j++){ // draw individual dots
    10       ctx.rotate(Math.PI*2/(i*6));
    11       ctx.beginPath();
    12       ctx.arc(0,i*12.5,5,0,Math.PI*2,true);
    13       ctx.fill();
    14     }
    15 
    16     ctx.restore();
    17   }
    18 }

    缩放 Scaling

    • scale(x, y)  增减图形在 canvas 中的像素数目,对形状,位图进行缩小或者放大。

      x,y 分别是横轴和纵轴的缩放因子,它们都必须是正值。值比 1.0 小表示缩小,比 1.0 大则表示放大,值为 1.0 时什么效果都没有。

    变形 Transforms

    • transform(m11, m12, m21, m22, dx, dy)
    • setTransform(m11, m12, m21, m22, dx, dy)

      这个方法必须重置当前的变形矩阵为单位矩阵,然后以相同的参数调用 transform 方法。如果任意一个参数是无限大,那么变形矩阵也必须被标记为无限大,否则会抛出异常。

    实例:

     1 function draw() {
     2   var canvas = document.getElementById("canvas");
     3   var ctx = canvas.getContext("2d");
     4 
     5   var sin = Math.sin(Math.PI/6);
     6   var cos = Math.cos(Math.PI/6);
     7   ctx.translate(200, 200);
     8   var c = 0;
     9   for (var i=0; i <= 12; i++) {
    10     c = Math.floor(255 / 12 * i);
    11     ctx.fillStyle = "rgb(" + c + "," + c + "," + c + ")";
    12     ctx.fillRect(0, 0, 100, 10);
    13     ctx.transform(cos, sin, -sin, cos, 0, 0);
    14   }
    15   
    16   ctx.setTransform(-1, 0, 0, 1, 200, 200);
    17   ctx.fillStyle = "rgba(255, 128, 255, 0.5)";
    18   ctx.fillRect(0, 50, 100, 100);
    19 }

  • 相关阅读:
    数组的一些经典案例(循环)(max=score[0])(冒泡)(flag标志)(杨辉三角)
    冒泡排序
    C语言之数组
    循环结构的一些案例:倒等腰三角形、菱形、暴力破解
    break和contine关键字
    循环嵌套(打印*** ***)
    循环的经典案例(李白买酒)
    C语言循环结构-while/do...while/for--逢3过,阶乘,九九乘法表
    WordPress部署踩坑记
    Symbol
  • 原文地址:https://www.cnblogs.com/hzj680539/p/5060101.html
Copyright © 2020-2023  润新知