在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ HTML/ Ch21 非零環(huán)繞原則
Ch22 最后的API
Ch14 旋轉變換
Ch19 全局陰影與圖像合成
Ch12 三次貝塞爾曲線
Ch4 多線條組成圖形
Ch7 填充顏色
Ch6 線條的屬性
Ch20 裁剪和繪制圖像
CANVAS——Draw on the Web
Ch18 文本對齊與度量
Ch8 填充樣式
Ch15 縮放變換
Ch9 繪制標準圓弧
Ch2 開始前的準備
Ch16 矩陣變換
Ch3 從線段開始
Ch10 使用切點繪制圓弧
Ch21 非零環(huán)繞原則
Ch11 二次貝塞爾曲線
Ch5 繪制矩形
Ch17 文本顯示與渲染
Ch1 HTML5簡介
Ch13 平移變換

Ch21 非零環(huán)繞原則

路徑方向與非零環(huán)繞原則

平時我們畫的圖形都是規(guī)規(guī)矩矩的,那么如果我們用線條畫了個抽象派作品,就像下面這圖一樣,童鞋們知道怎么用fill()染色呢?

不規(guī)則圖形

這里就要用到數(shù)學上的一個方法——非零環(huán)繞原則,來判斷哪塊區(qū)域是里面,哪塊區(qū)域是外面。接下來,我們具體來看下什么是非零環(huán)繞原則。

非零環(huán)繞原則

首先,我們得給圖形確定一條路徑,只要“一筆畫”并且“不走重復路線”就可以了。如圖,標出的是其中的一種路徑方向。我們先假定路徑的正方向為1(其實為-1啥的也都可以,正負方向互為相反數(shù),不是0就行),那么反方向就是其相反數(shù)-1。

然后,我們在子路徑切割的幾塊區(qū)域內的任意一點各取一條方向任意的射線,這里我只取了三個區(qū)域的射線為例,來判斷這三塊區(qū)域是“里面”還是“外面”。

接下來,我們就來判斷了。S1中引出的射線L1,與S1的子路徑的正方向相交,那么我們就給計數(shù)器+1,結果為+1,在外面。

S2中引出的射線L2,與兩條子路徑的正方向相交,計數(shù)器+2,結果為+2,在外面。

S3中引出的射線L3,與兩條子路徑相交,但是其中有一條的反方向,計數(shù)器+1-1,結果為0,在里面。沒錯,只要結果不為0,該射線所在的區(qū)域就在外面。

繪制圓環(huán)

記得我們之前學過的arc方法嗎?它的最后一個參數(shù)就是判斷是路徑方向的,如果是路徑相反的兩個同心圓在一起,圖上色會有什么神奇的效果呢?

圓環(huán)

下面我們通過代碼來實現(xiàn)它。

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>圓環(huán)</title>
    <style>
        body { background: url("./images/bg3.jpg") repeat; }
        #canvas { border: 1px solid #aaaaaa; display: block; margin: 50px auto; }
    </style>
</head>
<body>
<div id="canvas-warp">
    <canvas id="canvas">
        你的瀏覽器居然不支持Canvas?!趕快換一個吧!!
    </canvas>
</div>

<script>
    window.onload = function(){
        var canvas = document.getElementById("canvas");
        canvas.width = 800;
        canvas.height = 600;
        var context = canvas.getContext("2d");
        context.fillStyle = "#FFF";
        context.fillRect(0,0,800,600);

        context.shadowColor = "#545454";
        context.shadowOffsetX = 5;
        context.shadowOffsetY = 5;
        context.shadowBlur = 2;

        context.arc(400, 300, 200, 0, Math.PI * 2 ,false);
        context.arc(400, 300, 230, 0, Math.PI * 2 ,true);
        context.fillStyle = "#00AAAA";
        context.fill();
    };
</script>
</body>
</html>

演示 21-1

運行結果:

繪制圓環(huán)

結合我們上一節(jié)學到了陰影效果,這個圓環(huán)看上去是不是特別的有立體感?

鏤空剪紙效果

接下來,我們利用非零環(huán)繞原則和陰影來繪制一個鏤空的剪紙效果。

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>鏤空剪紙效果</title>
    <style>
        body { background: url("./images/bg3.jpg") repeat; }
        #canvas { border: 1px solid #aaaaaa; display: block; margin: 50px auto; }
    </style>
</head>
<body>
<div id="canvas-warp">
    <canvas id="canvas">
        你的瀏覽器居然不支持Canvas?!趕快換一個吧!!
    </canvas>
</div>

<script>
    window.onload = function(){
        var canvas = document.getElementById("canvas");
        canvas.width = 800;
        canvas.height = 600;
        var context = canvas.getContext("2d");
        context.fillStyle = "#FFF";
        context.fillRect(0,0,800,600);

        context.beginPath();
        context.rect(200,100,400,400);
        drawPathRect(context, 250, 150, 300, 150);
        drawPathTriangle(context, 345, 350, 420, 450, 270, 450);
        context.arc(500, 400, 50, 0, Math.PI * 2, true);
        context.closePath();

        context.fillStyle = "#058";
        context.shadowColor = "gray";
        context.shadowOffsetX = 10;
        context.shadowOffsetY = 10;
        context.shadowBlur = 10;
        context.fill();

    };

    //逆時針繪制矩形
    function drawPathRect(cxt, x, y, w, h){
        /**
         * 這里不能使用beginPath和closePath,
         * 不然就不屬于子路徑而是另一個全新的路徑,
         * 無法使用非零環(huán)繞原則
         */
        cxt.moveTo(x, y);
        cxt.lineTo(x, y + h);
        cxt.lineTo(x + w, y + h);
        cxt.lineTo(x + w, y);
        cxt.lineTo(x, y);

    }

    //逆時針繪制三角形
    function drawPathTriangle(cxt, x1, y1, x2, y2, x3, y3){
        cxt.moveTo(x1,y1);
        cxt.lineTo(x3,y3);
        cxt.lineTo(x2,y2);
        cxt.lineTo(x1,y1);
    }

</script>
</body>
</html>

演示 21-3

運行結果:

鏤空剪紙效果

這里手動繪制矩形的原因是我們想要得到逆時針路徑的矩形,而且API提供的rect()方法繪制是順時針矩形。另外,需要注意的是,這個剪紙是一個圖形,一個路徑。不能在繪制鏤空三角形和繪制鏤空矩形的方法里使用beginPath()closePath(),不然它們就會是新的路徑、新的圖形,而不是剪紙的子路徑、子圖形,就無法使用非零環(huán)繞原則。


好了,這一節(jié)的內容就到這里,內容相對來說還是比較簡單實用的。下一節(jié)就是Canvas API的最后一節(jié)了,大家已經(jīng)掌握了這么多的繪制方法,是不是躍躍欲試了呢?那么,就揚起手中的筆,繪出自己的藝術家之魂吧~