画布 - 可点击,可触摸的矩形,可播放和播放声音

时间:2015-03-07 20:50:45

标签: audio canvas multi-touch phaser-framework

I made this with DOM events and CSS transitions我真的很难弄清楚如何用帆布制作这样的东西。我希望能够有触摸事件并最终播放声音。

我在看phaser.js并且看起来很有希望,但是在形状上创建事件处理程序并不是内置的。

似乎这个想法是绘制一堆矩形,在整个画布上听取触摸和点击事件,然后找出哪个相应的矩形来制作动画......但我只是想到它而迷失了。

使用DOM很容易,画布很难?所有帮助非常感谢。

1 个答案:

答案 0 :(得分:2)

当您知道画布是包含多个绘图的单个元素时,并不难。只有canvas元素本身才会触发事件。画布上的每个多个绘图都不会触发单个事件。

因此,要在画布上起作用,您必须手动处理这些任务:

  • 保存每个条形音箱的定义:它的x,y位置及其宽度和宽度。高度

  • 收听鼠标事件

  • 通过在每个保存的条形音箱上点击鼠标来手动测试鼠标事件是否发生在其中一个条形音箱中

  • 如果鼠标位于特定的条形音箱内,请播放该条的声音并用该颜色突出显示该条。

以下是带注释的代码示例和演示:

// canvas related variables
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var $canvas=$("#canvas");
var canvasOffset=$canvas.offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;

// create an array of objects representing each sound to be played
var sounds=[];
for(var i=0;i<15;i++){
  sounds.push({
    element:document.createElement('audio'),
    src:'https://dl.dropboxusercontent.com/u/139992952/multple/Ticking_Clock-KevanGC-1934595011.mp3',
    isPlaying:false
  });
  document.body.appendChild(sounds[i].element);
  sounds[i].element.src=sounds[i].src;
}

// create an array of objects representing the hit area of each "sound-bar"
var hits=[];
for(var i=0;i<15;i++){
  hits.push({x:213,y:i*43+88,w:750,h:40,fill:randomColor()});
}

// load the sound board
var img=new Image();img.onload=start;img.src="https://dl.dropboxusercontent.com/u/139992952/multple/soundboard.png";
function start(){
  // resize the canvas to image size
  canvas.width=img.width;
  canvas.height=img.height;
  // draw the sound board image
  ctx.drawImage(img,0,0);
  // listen for mousedown events
  $("#canvas").mousedown(function(e){handleMouseDown(e);});
}

// handle mousedown events
function handleMouseDown(e){
  // tell the browser we're handling this event
  e.preventDefault();
  e.stopPropagation();

  // get mouse X&Y
  mx=parseInt(e.clientX-offsetX);
  my=parseInt(e.clientY-offsetY);

  // hit test each sound-bar
  for(var i=0;i<hits.length;i++){
    var h=hits[i];
    // define this sound-bar by drawing it (no stroke/fill)
    ctx.beginPath();
    ctx.rect(h.x,h.y,h.w,h.h);
    // is the mouse in this particular sound-bar
    if(ctx.isPointInPath(mx,my)){
      var s=sounds[i];
      // if this bar is playing sound, pause
      // and redraw the un-highlighted sound board
      if(s.isPlaying){
        s.element.pause();
        ctx.clearRect(0,0,cw,ch);
        ctx.drawImage(img,0,0);
        // if this bar is silent, start playing
        // and fill this bar with a highlight color
      }else{
        s.element.play();
        ctx.fillStyle=hits[i].fill;
        ctx.fill();
      }
      s.isPlaying=!s.isPlaying;
    }
  }
}

// adjust for window scrolling
window.onscroll=function(e){
  var BB=canvas.getBoundingClientRect();
  offsetX=BB.left;
  offsetY=BB.top;
}

// utility: get a random color
function randomColor(){ 
  return('#'+Math.floor(Math.random()*16777215).toString(16));
}
body{ background-color: ivory; }
#canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>Click on a sound-bar to play it's sound<br>Click again to pause its sound</h4>
<canvas id="canvas" width=300 height=300></canvas>