zoukankan      html  css  js  c++  java
  • 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 }

  • 相关阅读:
    Atitit 集团与个人的完整入口列表 attilax的完整入口 1. 集团与个人的完整入口列表 1 2. 流量入口概念 2 3. 流量入口的历史与发展 2 1.集团与个人的完整入口列表
    atitit 每季度日程表 每季度流程 v3 qaf.docx Ver history V2 add diary cyar data 3 cate V3 fix detail 3cate ,
    Atitit react 详细使用总结 绑定列表显示 attilax总结 1. 前言 1 1.1. 资料数量在百度内的数量对比 1 1.2. 版本16 v15.6.1 1 1.3. 引入js 2
    Atitit r2017 r3 doc list on home ntpc.docx
    Atitit r2017 ra doc list on home ntpc.docx
    Atiitt attilax掌握的前后技术放在简历里面.docx
    Atitit q2016 qa doc list on home ntpc.docx
    Atitit r7 doc list on home ntpc.docx 驱动器 D 中的卷是 p2soft 卷的序列号是 9AD0D3C8 D:\ati\r2017 v3 r01\
    Atitit 可移植性之道attilax著
    Atitit q2016 q5 doc list on home ntpc.docx
  • 原文地址:https://www.cnblogs.com/hzj680539/p/5060101.html
Copyright © 2011-2022 走看看