zoukankan      html  css  js  c++  java
  • canvas之图形的变化(平移,缩放,旋转)

    1、保存与恢复canvas状态

    ctx.save();暂时将当前的状态保存到堆中

    ctx.restore();该方法用于将上一个保存的状态从堆中再次取出,恢复该状态的所有设置。

     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4 <meta charset="utf-8">
     5 <title></title>
     6 <style type="text/css">
     7 *{padding: 0;margin:0;}
     8 body{background: #1b1b1b;}
     9 #div1{margin:50px auto; width:300px; height: 300px;}
    10 canvas{background: #fff;}
    11 </style>
    12 <script type="text/javascript">
    13 window.onload = function(){
    14     var c = document.getElementById('myCanvas');
    15     var context = c.getContext('2d');
    16     
    17     //开始绘制矩形
    18     context.fillStyle = '#f0f';
    19     context.strokeStyle = 'blue';
    20     context.fillRect(20,20,100,100);
    21     context.strokeRect(20,20,100,100);
    22     context.fill();
    23     context.stroke();
    24     
    25     //保存当前canvas状态
    26     context.save();    
    27     
    28     //绘制另外一个矩形
    29     context.fillStyle = '#f00';
    30     context.strokeStyle = 'green';
    31     context.fillRect(140,20,100,100);
    32     context.strokeRect(140,20,100,100);
    33     context.fill();
    34     context.stroke();
    35     
    36     //恢复第一个矩形的状态
    37     context.restore();
    38     
    39     //绘制两个矩形
    40     context.fillRect(20,140,50,50);
    41     context.strokeRect(80,140,50,50);
    42     
    43 };
    44 </script>
    45 </head>
    46 <body>
    47     <div id="div1">
    48         <canvas id="myCanvas" width="300" height="200"></canvas>
    49     </div>
    50 </body>
    51 </html>

    效果展示:

    2、移动坐标空间

    context.translate(dx,dy); dx,dy分别表示坐标原点沿水平和垂直两个方向的偏移量。(在图形变换之前,最好使用save()方法保存当前状态的好习惯。使用restore()方法恢复原来的状态)。

     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4 <meta charset="utf-8">
     5 <title></title>
     6 <style type="text/css">
     7 *{padding: 0;margin:0;}
     8 body{background: #1b1b1b;}
     9 #div1{margin:50px auto; width:300px; height: 300px;}
    10 canvas{background: #fff;}
    11 </style>
    12 <script type="text/javascript">
    13 window.onload = function(){
    14     draw();    
    15 };
    16 function drawTop(ctx,fillStyle){
    17     ctx.fillStyle = fillStyle;
    18     ctx.beginPath();
    19     ctx.arc(0,0,30,0,Math.PI,true);
    20     ctx.closePath();
    21     ctx.fill();
    22 }
    23 
    24 function drawGrip(ctx){
    25     ctx.save();
    26     ctx.fillStyle = 'blue';
    27     ctx.fillRect(-1.5,0,1.5,40);
    28     ctx.beginPath();
    29     ctx.arc(-5,40,4,Math.PI,Math.PI*2,true);
    30     ctx.stroke();
    31     ctx.closePath();
    32     ctx.restore();
    33 }
    34 
    35 function draw(){
    36     
    37     var ctx = document.getElementById('myCanvas').getContext('2d');
    38     ctx.translate(80,80);
    39     
    40     for(var i=0; i<10; i++){
    41         ctx.save();
    42         ctx.translate(60*i,0);
    43         drawTop(ctx,'rgb('+(30*i)+','+(255-30*i)+',255)');
    44         drawGrip(ctx);
    45         ctx.restore();
    46     }
    47     
    48 }
    49 </script>
    50 </head>
    51 <body>
    52     <div id="div1">
    53         <canvas id="myCanvas" width="700" height="300"></canvas>
    54     </div>
    55 </body>
    56 </html>

    效果展示:

    3、旋转坐标空间

    context.rotate(angle);  该方法只有一个参数 旋转角度angle,旋转角度以顺时针方向为正方向,以弧度为单位,旋转中心为canvas的原点

     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4 <meta charset="utf-8">
     5 <title></title>
     6 <style type="text/css">
     7 *{padding: 0;margin:0;}
     8 body{background: #1b1b1b;}
     9 #div1{margin:50px auto; width:300px; height: 300px;}
    10 canvas{background: #fff;}
    11 </style>
    12 <script type="text/javascript">
    13 window.onload = function(){
    14     draw();    
    15 };
    16 function drawTop(ctx,fillStyle){
    17     ctx.fillStyle = fillStyle;
    18     ctx.beginPath();
    19     ctx.arc(0,0,30,0,Math.PI,true);
    20     ctx.closePath();
    21     ctx.fill();
    22 }
    23 function drawGrip(ctx){
    24     ctx.save();
    25     ctx.fillStyle = 'blue';
    26     ctx.fillRect(-1.5,0,1.5,40);
    27     ctx.beginPath();
    28     ctx.strokeStyle = 'blue';
    29     ctx.arc(-5,40,4,Math.PI,Math.PI*2,true);
    30     ctx.stroke();
    31     ctx.closePath();
    32     ctx.restore();
    33 }
    34 function draw(){
    35     var c = document.getElementById('myCanvas');
    36     var ctx = c.getContext('2d');
    37     ctx.translate(150,150);
    38     
    39     for(var i=0; i<8; i++){
    40         ctx.save();
    41         ctx.rotate(Math.PI*(2/4+i/4));
    42         ctx.translate(0,-100);
    43         drawTop(ctx,'rgb('+(30*i)+','+(255-30*i)+',255)');
    44         drawGrip(ctx);
    45         ctx.restore();
    46     }
    47 }
    48 </script>
    49 </head>
    50 <body>
    51     <div id="div1">
    52         <canvas id="myCanvas" width="300" height="300"></canvas>
    53     </div>
    54 </body>
    55 </html>

    效果展示:

    4、缩放图形

    ctx.scale(x,y); 其中x为x轴的缩放,y为y轴的缩放,如果要缩小,值为小于1的数值,如果要放大,值为大于1的数值。

     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4 <meta charset="utf-8">
     5 <title></title>
     6 <style type="text/css">
     7 *{padding: 0;margin:0;}
     8 body{background: #1b1b1b;}
     9 #div1{margin:50px auto; width:300px; height: 300px;}
    10 canvas{background: #fff;}
    11 </style>
    12 <script type="text/javascript">
    13 window.onload = function(){
    14     draw();    
    15 };
    16 
    17 function draw(){
    18     var c = document.getElementById('myCanvas');
    19     var ctx = c.getContext('2d');
    20     ctx.translate(180,20);
    21     
    22     for(var i=0; i<80; i++){
    23         ctx.save();
    24         ctx.translate(30,30);
    25         ctx.scale(0.95,0.95);
    26         ctx.rotate(Math.PI/12);
    27         ctx.beginPath();
    28         ctx.fillStyle = 'red';
    29         ctx.globalAlpha = '0.4';
    30         ctx.arc(0,0,50,0,Math.PI*2,true);
    31         ctx.closePath();
    32         ctx.fill();
    33     }
    34 }
    35 </script>
    36 </head>
    37 <body>
    38     <div id="div1">
    39         <canvas id="myCanvas" width="300" height="300"></canvas>
    40     </div>
    41 </body>
    42 </html>

    效果展示:

    5、矩阵变换

    transform方法用于直接对变形矩阵作修改,即进行矩阵变形。

    context.transform(m11,m12,m21,m22,dx,dy);   该方法必须将当前的变换矩阵与下面的矩阵进行乘法运算。

    即:

    m11(默认为1) m21(默认为0) dx
    m12(默认为0) m22(默认为1) dy
    0 0 1

    也就是说假设A(x,y)要变换成B(x’,y’)可以通过乘以上述矩阵即可得到。

    一:平移(translate), translate可以用下面的方法替代

     

    如上图所示:

    x’=x+dx

    y’=y+dy

    即:

    其中dx为原点沿着x轴移动的数值,y为原点沿着y轴移动的数值。

    context.translate(x,y)可以用下面的transform方法来替代:

    context.transform(0,1,1,0,dx,dy); 或 context.transform(1,0,0,1,dx,dy);

     

    二、缩放:  scale(x,y) 

    x’=m11*x

    y’=m22*y

    x'=m12*x

    y'=m21*y 

    (其中,m11、m22 和m12、m21分别表示在x轴和y轴上的缩放倍数)

    则:scale(x,y); 可以通过下面的transform发放来替代:

    context.transform(m11,0,0,m22,0,0);  或 context.transform(0,m12,m21,0,0,0);

     


    三、旋转: rotate(angle);

    可以用下面的transform方法来替代:

    context.transform(cosΘ,sinΘ,-sinΘ,cosΘ,0,0);

    其中Θ为旋转的角度,dx,dy都为0表示坐标原点不变。

    如图:x' = x*cosΘ - y*sinΘ

            y' = x*sinΘ + y*cosΘ

    也即是[转载]Html5 <wbr>Canvas <wbr>变换矩阵与坐标变形之间的关系(

     

    则:

    context.transform(Math.cos(θ*Math.PI/180),Math.sin(θ*Math.PI/180),

    -Math.sin(θ*Math.PI/180),Math.cos(θ*Math.PI/180),0,0)可以替代context.rotate(θ)。

    也可以使用

    context.transform(-Math.sin(θ*Math.PI/180),Math.cos(θ*Math.PI/180),

    Math.cos(θ*Math.PI/180),Math.sin(θ*Math.PI/180), 0,0)替代。

    eg: context.transform(0.95,0,0,0.95,30,30); 可以替代 context.translate(30,30); context.scale(0.95.0.95);

    setTransform方法用于将当前的变化矩阵 重置 为最初的矩阵,然后以相同的参数调用transform方法,即先set(重置),再transform(变换)

    用法: context.setTransform(m11,m12,m21,m22,dx,dy);

     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4 <meta charset="utf-8">
     5 <title></title>
     6 <style type="text/css">
     7 *{padding: 0;margin:0;}
     8 body{background: #1b1b1b;}
     9 #div1{margin:50px auto; width:300px; height: 300px;}
    10 canvas{background: #fff;}
    11 </style>
    12 <script type="text/javascript">
    13 window.onload = function(){
    14     draw();    
    15 };
    16 
    17 function draw(){
    18     var c = document.getElementById('myCanvas');
    19     var ctx = c.getContext('2d');
    20     ctx.translate(200,20);
    21     
    22     for(var i=0; i<80; i++){
    23         ctx.save();
    24         ctx.transform(0.95,0,0,0.95,30,30);
    25         ctx.rotate(Math.PI/12);
    26         ctx.beginPath();
    27         ctx.fillStyle = 'red';
    28         ctx.globalAlpha = '0.4';
    29         ctx.arc(0,0,50,0,Math.PI*2,true);
    30         ctx.closePath();
    31         ctx.fill();
    32     }
    33     
    34     ctx.setTransform(1,0,0,1,10,10);    //将前面的矩阵恢复为最初的矩阵,即恢复最初的原点,然后将坐标原点改为(10,10),并以新的坐标绘制一个蓝色的矩形
    35     ctx.fillStyle = 'blue';
    36     ctx.fillRect(0,0,50,50);
    37     ctx.fill();
    38     
    39 }
    40 </script>
    41 </head>
    42 <body>
    43     <div id="div1">
    44         <canvas id="myCanvas" width="700" height="300"></canvas>
    45     </div>
    46 </body>
    47 </html>

     效果显示:

  • 相关阅读:
    函数声明例子
    税收工资分级
    attribute函数
    输出结果有误
    scanf_s()函数与数组,运行环境VS2013
    格式化输出
    功能点介绍和用户场景
    第二次作业合作版
    word count
    第一次作业
  • 原文地址:https://www.cnblogs.com/wxydigua/p/4205908.html
Copyright © 2011-2022 走看看