ホームページ  >  記事  >  ウェブフロントエンド  >  html5 Canvas描画のサンプルコードの詳細説明(2)

html5 Canvas描画のサンプルコードの詳細説明(2)

黄舟
黄舟オリジナル
2017-03-28 15:38:091518ブラウズ


この記事では、html5 canvasにおけるクリッピング領域(clip領域)、レイヤー化、合成、変形(回転、拡大縮小)機能の適用方法を中心に説明します。

まず、以下のすべての操作を実装する基本的なコードセグメントを投稿します:

Base Code

<!DOCTYPE html>
<html>
<head>        
<meta charset="utf-8" />       
<script type="text/javascript" src="modernizr-latest.js"></script>        <script type="text/javascript">
window.addEventListener("load", eventWindowLoaded, false);           
var Debugger = function() {};            
Debugger.log = function(message) {                
try {                   
 console.log(message);                
} 
catch (exception) {   return;   }           
}
                        
function eventWindowLoaded() { canvasApp();   }     
       
function canvasSupport() {                
return Modernizr.canvas;            
}
           
function canvasApp() {                
//是否支持CANVAS判断
if(!canvasSupport()) {                    
return;                
}               
 //取Canvas
var theCanvas = document.getElementById("canvasOne");               
 //获取绘图环境
contextvar context = theCanvas.getContext("2d");               
 //绘图方法的实现
function drawScreen() {}               
 //绘图方法调用执行                
drawScreen(); 
 }  
      
</script>    
</head>    
<body>        
<div style="position: absolute; top: 50px; left: 50px; border:1px solid #0000ff">           
 <canvas id="canvasOne" width="550" height="400">
 Your browser does not support HTML5 Canvas.            
</canvas>        
</div>    
</body>
</html>

以下のすべてのサンプルコードについては、上記の関数drawScreen()を置き換えるだけです。

クリップ領域 クリッピング領域

クリップ領域では、.save と .restore を使用して、現在の描画 状態 をスタックにプッシュし、スタックから復元します。 .save を使用して、トリミング前の描画状態を確認します。

context.rect() を介してトリミングする領域の位置を決定します。

Canvas 上に描画する場合、トリミングされた領域のグラフィックのみを表示できます。

トリミング前の状態に戻すには context.restore() を使用します。

Canvas 上でのグラフィックの合成とは、キャンバス上のグラフィックの透明度とレイヤー効果の処理を改善することを指します。

合成操作には 2 つの重要な属性があります。まず、globalAlpha と globalCompositeOperation です。

globalAlpha: Canvas の透明度を指します。デフォルト値は 1.0、範囲は [0.0-1.0] です。

globalCompositeOperation: 「アルファ」と「変換」が適用された複数のグラフィックが Canvas 上に描画される方法。

コピー先-atopdestination-indestination-outdestination-over Lightersource-atopsource-insource-outsource-overxor

この11種類の中には「source」と「destination」という2つの特別な単語があります。タイプ ":

"source": Canvas に描画されるグラフィック (新しいグラフィック);

"destination": Canvas に現在表示されているグラフィック (古いグラフィック);

copy:新しいグラフィックは保持され、その他はクリアされます

destination-atop: 新しいグラフィックと重なっている部分を表示する古いグラフィックを参照します。 古いグラフィック (重なっている部分) が表示されます。上層

destination-in : 古いグラフィックの重なり部分のみを表示するグラフィックを指します

  1. destination-out: 古いグラフィックの重ならない部分のみを表示するグラフィックを指します

  2. destination-over: 古いグラフィックを残したまま、古いグラフィックと新しいグラフィックの両方を表示することを指します 上のレイヤーに表示されます

  3. lighter: 新旧のグラフィックの両方が表示されることを意味し、新旧グラフィックの重なっている部分に色を付けていきます

  4. source-atop:指显示旧图表与重叠部分的新图形,新图形(重叠部分)显示在上层

  5. source-in:指只显示新图形重叠部分的图形

  6. source-out:指只显示新图形中不重叠部分的图形

  7. source-over:指新旧图形都显示,新图形显示在上层

  8. xor:指新旧图形都显示,新旧图形重叠的部分会变成透明。

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>test</title>
        <script type="text/javascript" src="../script/modernizr-latest.js"></script>
        <script type="text/javascript">
            window.addEventListener("load", eventWindowLoaded, );
 Debugger = () {
            };
            Debugger.log = (message) {
 {
                    console.log(message);
                }  (exception) {
;
                }
            }
 eventWindowLoaded() {
                canvasApp();
            }

 canvasSupport() {
 Modernizr.canvas;
            }

 canvasApp() {

(!canvasSupport()) {
;
                }

 drawScreen(compositing, num) {
 name = "c" + num;
 theCanvas = document.getElementById(name);
                    theCanvas.width=100;
                    theCanvas.height=100;
 context = theCanvas.getContext("2d");
                    context.fillStyle = "blue";
                    context.fillRect(10, 10, 50, 50);
                    context.globalCompositeOperation = compositing;
                    context.fillStyle = "red";
                    context.fillRect(30, 30, 50, 50);
                }

                drawScreen("copy", 1);
                drawScreen("destination-atop", 2);
                drawScreen("destination-in", 3);
                drawScreen("destination-out", 4);
                drawScreen("destination-over", 5);
                drawScreen("lighter", 6);
                drawScreen("source-atop", 7);
                drawScreen("source-in", 8);
                drawScreen("source-out", 9);
                drawScreen("source-over", 10);
                drawScreen("xor", 11);
            }
        </script>
        <style>
            td {
                border: 1px solid #000000;
            }
        </style>
    </head>
    <body>
        <p style="position: absolute; top: 50px; left: 50px; border:1px solid #0000ff">
            <table>
                <tr>
                    <td><canvas id="c1"></canvas></td>
                    <td><canvas id="c2"></canvas></td>
                    <td><canvas id="c3"></canvas></td>
                    <td><canvas id="c4"></canvas></td>
                    <td><canvas id="c5"></canvas></td>
                </tr>
                <tr>
                    <td><canvas id="c6"></canvas></td>
                    <td><canvas id="c7"></canvas></td>
                    <td><canvas id="c8"></canvas></td>
                    <td><canvas id="c9"></canvas></td>
                    <td><canvas id="c10"></canvas></td>
                    <td><canvas id="c11"></canvas></td>
                </tr>
            </table>
        </p>
    </body>
</html>

实例效果图:从左到右、从上到下,分别表示1,2,……11,这11种类型生成的效果图

 

Transformations 变换

变换的本质就是指从数学(矩阵)的角度来调整图形的物理属性;当然,这是原理;我们在实现的时候,只需要调用方法即可;

移动translate、旋转rotation  、缩放scale  、变换transforms

Transformations are applied to shapes and paths drawn after the setTransform() or other transformation function is called

只有在应用context.setTransform()方法后,对图形的各种变换才能生效;

实例:

function drawScreen() {
context.fillStyle = "blue";
context.fillRect(210,210,50,50);
context.setTransform(1,0,0,1,0,0);//启动变换
var angleInRadians = 45 * Math.PI / 180;
context.rotate(angleInRadians);//旋转(参数为弧度)
context.fillStyle = "red";
context.fillRect(0,0,200,200);
}

效果如图:

蓝色的box并没有发生旋转;红的box是以Canvas的原点为中心顺时针旋转了45度(为何没有以红色box中心为原点旋转呢?);

Canvas的旋转原点,默认为Canvas的坐标系的(0,0)点,若不进行原点平移就旋转,自然是像整个画布做了旋转;

We must “translate” the point of origin to the center of our shape to rotate it around its own center 

我们必须通地context.translate()方法来平移原点,才能按绘制的图形中心来旋转图形自身;

平移原理:

实例:

translate

function drawScreen() {
context.fillStyle = "blue";
context.fillRect(210,210,50,50);
context.setTransform(1,0,0,1,0,0);
var angleInRadians = 45 * Math.PI / 180;
var x = 0;
var y = 0;
var width = 200;
var height = 200;
context.translate(x+.5*width, y+.5*height);//平移
context.rotate(angleInRadians);
context.fillStyle = "red";
context.fillRect(-.5*width,-.5*height , width, height);
}

效果图:

 

context.scale()实现图形的缩放,

此方法有两个参数: 一个是对X轴方向的缩放,一个是对Y轴方向的缩放,正常的图形参数默认都为1;

例如,我们要对图形放大两倍,则使用context.scale(2,2);

以(25,25)为顶点,长宽为50的正方形,放大2倍

function drawScreen() {
context.fillStyle = "blue";
context.fillRect(0, 0, 50, 50);
context.fillRect(150, 50, 50, 50);
context.fillRect(50, 150, 50, 50);        
context.setTransform(1, 0, 0, 1, 0, 0);
context.scale(2, 2);            
context.fillStyle = "red";
context.fillRect(25, 25, 50, 50);
}

效果图:

 

scale与ratation也存在相似问题,就是原点的问题;

如果我们在变换前不进行原点的平移的话,scale功能默认的原点也是canvas的原点;

相当于对整个画布进行scale 默认是延x轴正向(left),y轴正向进行缩放(down);

如果想图形依然在原来的位置,从图形的中心位置进行scale,就需要先进行原点的平移context.translate();

以(25,25)为顶点,长宽为50的正方形,为其中心为原点,放大二倍


以(25,25)为顶点,长宽为50的正方形,为其中心为原点,放大二倍

function drawScreen() {
                
context.setTransform(1, 0, 0, 1, 0, 0);
var x = 25;
var y = 25;
var width = 50;
var height = 50;                
context.translate(x + .5 * width, y + .5 * height);                
context.scale(2, 2);                
context.fillStyle = "red";                
context.fillRect(-.5 * width, -.5 * height, width, height);
}

以上がhtml5 Canvas描画のサンプルコードの詳細説明(2)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。