Canvas上のグラフィック/画像バインドイベントのリスニング方法

13290 ワード

どのようにCanvas上のグラフィック/画像バインドイベントをリスニングしますか?
HTMLでは要素/ラベルにのみリスニング関数をバインドできます.Canvas図面には1つの要素-canvasしかありません.各グラフィック/画像は要素ではなく、イベントバインドを直接行うことはできません.
解決策:「イベント委任」--canvasにすべてのイベントをリスニングさせ、イベント発生座標点がグラフィック/画像の範囲内にあるかどうかを計算します.
標準ジオメトリではイベントバインドが可能です.非標準ジオメトリでイベントバインドを行うのは面倒です.

<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>canvas       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/  _  .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";//    //    img1,img2   ,     
    img1.src="img/loop.jpg";
    img2.src="img/play1.png";
    var progress=0;//    ,            
    img.onload=function(){//        ,            , -->    
        progress+=20;
        (progress==60)&&star();
    }
    img1.onload=function(){//        ,            , -->    
                progress+=20;
        (progress==60)&&star();
    }
    img2.onload=function(){//        ,            , -->    
                progress+=20;
        (progress==60)&&star();
    }
    //    
    function star(){
        ctx1.drawImage(img,0,0,300,500);//    
        loop();//      img1
        ctx1.drawImage(img2,100,350,100,100);//  2
    }

    //    ,         
    var i=0;
    var time=null;
    var ispause=true;
    //    
    function loop(){
        ctx1.save();//        
        ctx1.translate(150,165);//  
        ctx1.rotate(i*Math.PI/180);//  
        ctx1.drawImage(img1,-65,-65);//  
        ctx1.restore();//         
        //     
        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);
    }
    //    
    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("   ");
            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";
            }
        }

        //   ,          ,            
        setInterval(function(){
            if(audio.paused){
                ispause=true;
                clearInterval(time);
                img2.src="img/play1.png";
            }
        },5);
    }

    //       --  
    range1.onchange=function(){//    =     *range   /range  value 
        audio.currentTime=parseFloat(range1.value*audio.duration/range1.max);
    }
    //          ,            (     )
    setInterval("range1.value=parseFloat(range1.max*audio.currentTime/audio.duration);",400);
    //       --  
    audio.volume=0.3;
    range2.onchange=function(){
        audio.volume=range2.value/10;
    }
script>
html>