canvasで画像にマスクをかけて動かしてみる

画像にかけるマスクを少し特殊に動かしたいということがあったので、canvasでマスクを動かす方法を試してみました。

サンプルコード

今回は例として、円形でマスクをかけて左右から中央に移動する動きを実装してみます。

HTML

1
<canvas id="canvas" width="480" height="360"></canvas>

JavaScript

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
var w = 480; // canvasの幅
var h = 360; // canvasの高さ
var c = 0;
window.onload = function() {
    draw();
}
function draw() {
    var canvas = document.getElementById('canvas');
    if(!canvas || !canvas.getContext) return false;
    var ctx = canvas.getContext('2d');
 
    var img = new Image();
    img.src = 'image.jpg';
    img.onload = function() {
        setInterval(function() {
            // マスク設定前の状態に戻す
            ctx.restore();
            // マスク設定前の状態を保存
            ctx.save();
            // canvasを白紙に戻す
            ctx.clearRect(0, 0, w, h);
 
            // マスク
            ctx.beginPath();
            ctx.arc(c, 180, 100, 0, Math.PI * 2, false);
            ctx.arc(w - c, 180, 100, 0, Math.PI * 2, false);
            ctx.clip();
 
            // 画像の描画
            ctx.drawImage(img, 0, 0);
 
            // 次回表示の設定
            c += 1;
            if(c > w) {
                c = 0;
            }
        }, 20);
    }
}

画像読み込み後にsetInterval()でマスクを動かしてアニメーションさせています。
マスクを動かすデモページ

マスクをアニメーションさせる際のポイントとしては、save()とrestore()でマスクを解除している点です。
最初は以下のようにclearRect()しかしていなかったのですが、これだとマスクが解除されず、最初にマスクした円の中で動く感じになってしまいました。

JavaScript

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
var w = 480; // canvasの幅
var h = 360; // canvasの高さ
var c = 0;
window.onload = function() {
    draw();
}
function draw() {
    var canvas = document.getElementById('canvas');
    if(!canvas || !canvas.getContext) return false;
    var ctx = canvas.getContext('2d');
 
    var img = new Image();
    img.src = 'image.jpg';
    img.onload = function() {
        setInterval(function() {
            // canvasを白紙に戻す
            ctx.clearRect(0, 0, w, h);
 
            // マスク
            ctx.beginPath();
            ctx.arc(c, 180, 100, 0, Math.PI * 2, false);
            ctx.arc(w - c, 180, 100, 0, Math.PI * 2, false);
            ctx.clip();
 
            // 画像の描画
            ctx.drawImage(img, 0, 0);
 
            // 次回表示の設定
            c += 1;
            if(c > w) {
                c = 0;
            }
        }, 20);
    }
}

マスクを解除しなかった場合のデモページ

最初の想定とは違いますが、clearRect()でcanvasを白紙に戻さないようにすると、画像が徐々に表にされていく感じにもすることができます。

JavaScript

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
var w = 480; // canvasの幅
var h = 360; // canvasの高さ
var c = 0;
window.onload = function() {
    draw();
}
function draw() {
    var canvas = document.getElementById('canvas');
    if(!canvas || !canvas.getContext) return false;
    var ctx = canvas.getContext('2d');
 
    var img = new Image();
    img.src = 'image.jpg';
    img.onload = function() {
        setInterval(function() {
            // マスク設定前の状態に戻す
            ctx.restore();
            // マスク設定前の状態を保存
            ctx.save();
 
            // マスク
            ctx.beginPath();
            ctx.arc(c, 180, 100, 0, Math.PI * 2, false);
            ctx.arc(w - c, 180, 100, 0, Math.PI * 2, false);
            ctx.clip();
 
            // 画像の描画
            ctx.drawImage(img, 0, 0);
 
            // 次回表示の設定
            c += 1;
            if(c > w) {
                c = 0;
            }
        }, 20);
    }
}

画像が徐々に表示されるパターンのデモページ
 

【参考サイト】

 

関連記事

コメントを残す

メールアドレスが公開されることはありません。
* が付いている欄は必須項目です

CAPTCHA


コメントが承認されるまで時間がかかります。

2025年4月
 12345
6789101112
13141516171819
20212223242526
27282930