canvas - 可点击、可触摸的矩形动画和播放声音
canvas - clickable, touchable rectangles that animate and play sounds
I made this with DOM events and CSS transitions 我真的很难弄清楚如何用 canvas 制作这样的东西。我希望能够有触摸事件并最终播放声音。
我正在查看 phaser.js,它看起来很有希望,但是在形状上创建事件处理程序不是内置的。
这个想法似乎是绘制一堆矩形,监听整个 canvas 上的触摸和单击事件,然后找出要为哪个相应的矩形设置动画...但我迷路了考虑一下。
DOM 这么简单,canvas 这么难?非常感谢所有帮助。
当您知道 canvas 是一个包含多个绘图的单个元素时,这并不难。只有 canvas 元素本身会触发事件。 canvas 上的多个绘图中的每一个都不会触发单独的事件。
因此,要对 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>
I made this with DOM events and CSS transitions 我真的很难弄清楚如何用 canvas 制作这样的东西。我希望能够有触摸事件并最终播放声音。
我正在查看 phaser.js,它看起来很有希望,但是在形状上创建事件处理程序不是内置的。
这个想法似乎是绘制一堆矩形,监听整个 canvas 上的触摸和单击事件,然后找出要为哪个相应的矩形设置动画...但我迷路了考虑一下。
DOM 这么简单,canvas 这么难?非常感谢所有帮助。
当您知道 canvas 是一个包含多个绘图的单个元素时,这并不难。只有 canvas 元素本身会触发事件。 canvas 上的多个绘图中的每一个都不会触发单独的事件。
因此,要对 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>