1. ホーム
  2. Web制作
  3. html5

Canvasでグラフィックス/イメージバインディングのイベントリスナーを実装する方法

2022-01-11 04:58:41

HTMLはリスナー関数を要素/タグにのみバインドすることができます。

キャンバス描画の要素は1つだけです - キャンバスです。各図形/画像は要素ではないので、直接イベントバインディングすることはできません。

解決策 「イベントデレゲーション」 - キャンバスにすべてのイベントをリッスンさせ、イベント発生の座標点、および特定のグラフィック/イメージの範囲内にあるかどうかを計算させる。

イベントバインディングは、標準的な幾何学図形に対して可能です。

非標準のジオメトリに対するイベントバインディングは非常に面倒である。

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>canvas draw music player</title>
    <style>
        #range1,#range2{
            height:3px;
            position: relative;
            border: 0;
            outline: 0;
            box-shadow: 0 3px #300 inset;
        }
        #range1{
            width:250px;
            left:-275px;
            top:-10px;
        }
        #range2{
            transform:rotate(-90deg);
            width:50px;
            left:-320px;
            top:-50px;
        }
    </style>
</head>
<body>
    <canvas id="can1" width="300px" height="500px"></canvas>
    <audio src="voice/ cherish_sunlu.mp3" id="audio"></audio>
    <input type="range" min="0" max="1000" value="0" id="range1"/>
    <input type="range" min="0" max="10" step="1" value="3" id="range2"/>
</body>

<script>
    var ctx1=can1.getContext('2d');
    var img=new Image();
    var img1=new Image();
    var img2=new Image();
    img.src="img/bg.jpg";// drawing background // must be placed in img1,img2 before the assignment, otherwise it will cover
    img1.src="img/loop.jpg";
    img2.src="img/play1.png";
    var progress=0;//set the weight to determine if all images are loaded
    img.onload=function(){//Background image is loaded, determine if all images are loaded, is --> start drawing
        progress+=20;
        (progress==60)&&star();
    }
    img1.onload=function(){//Background image is loaded, determine if all images are loaded, yes--> start drawing
                progress+=20;
        (progress==60)&&star();
    }
    img2.onload=function(){//Background image is loaded, determine if all images are loaded, yes--> start drawing
                progress+=20;
        (progress==60)&&star();
    }
    //Start drawing
    function star(){
        ctx1.drawImage(img,0,0,300,500);//draw the background image
        loop();//draw the loop image img1
        ctx1.drawImage(img2,100,350,100,100);//draw2
    }

    //loop event,click event global variable
    var i=0;
    var time=null;
    var ispause=true;
    //loop function
    function loop(){
        ctx1.save();//Save the current state of the brush
        ctx1.translate(150,165);//Pan
        ctx1.rotate(i*Math.PI/180);//rotate
        ctx1.drawImage(img1,-65,-65);//draw
        ctx1.restore();//reset the previous state of the brush
        //draw two circles
        ctx1.strokeStyle="#000";
        ctx1.lineWidth=20;
        ctx1.arc(150,165,85,0,2*Math.PI);
        ctx1.stroke();
        ctx1.beginPath();
        ctx1.strokeStyle="#303";
        ctx1.lineWidth=10;
        ctx1.arc(150,165,75,0,2*Math.PI);
        ctx1.stroke();

        i+=10;
        (i>=360)&&(i=0);
    }
    //click event
    can1.onclick=function(e){
        var x= e.offsetX;
        var y= e.offsetY;
        //console.log(x,y);
        if((x-150)*(x-150)+(y-400)*(y-400)<=50*50*Math.PI){
            //console.log("I am round");
            if(ispause){
                audio.play();
                ispause=false;
                img2.src="img/pause1.png";
                time=setInterval(loop,100);
            }else{
                audio.pause();
                //clearInterval(time);
                //ispause=true;
                //img2.src="img/play.png";
            }
        }

        // Timer to listen if the music is finished, mainly to stop the music when it's done
        setInterval(function(){
            if(audio.pused){
                ispause=true;
                clearInterval(time);
                img2.src="img/play1.png";
            }
        },5);
    }

    //Progress bar change event - progress
    range1.onchange=function(){//current progress=total music time*range current value/range max value
        audio.currentTime=parseFloat(range1.value*audio.duration/range1.max);
    }
    //listen to the current progress of music playback, time low progress bar change event failure (too late to change)
    setInterval("range1.value=parseFloat(range1.max*audio.currentTime/audio.duration);",400);
    //Progress bar change event - volume
    audio.volume=0.3;
    range2.onchange=function(){
        audio.volume=range2.value/10;
    }
</script>
</html>

Canvasでgraphics/image bindingイベントリスナーを実装する方法については、この記事にまとめています。Canvasの画像結合イベントリスナーについては、スクリプトハウスの過去記事を検索していただくか、引き続き以下の関連記事をご覧ください。