pixijs入门-移动端click
pixi.js在移动端用touch事件,pc端用mouse事件,引擎内没有做转换。开发和测试会有很多不方便。
移动端,只实现了touchstart、touchmove、touchend,大多数情况下是不够用的,还需要自己来扩展。
比如,即使是移动端,点击一个按钮的逻辑,也应该是在按钮上按下手指,然后在按钮上抬起手指,如果直接用touchstart事件是不合适的,因为用户可以在按钮上按下,然后返回了,把手指移出按钮在弹起,这时不应该响应点击事件,同样用touchend也是不合适的。
按钮点击还是要用click,pixi.js没有提供click,就需要我们自己实现了。
demo:
浏览器切换到手机测试模式,然后点击小兔子,控制台会有输出。
html代码如下:
<html>
<head>
<title>pixijs入门-click</title>
<script type="text/javascript" src="http://hanyeah.com/js/pixi.min.js"></script>
<script type="text/javascript" src="js/MouseEventManager.js"></script>
<script type="text/javascript">
var frameRate=100;
var renderer;
var stage;
var tf;
var fps=0;
var ticker;
window.onload = function() {
renderer = new PIXI.WebGLRenderer(600, 400);
document.body.appendChild(renderer.view);
stage = new PIXI.Container();
var sprite = new PIXI.Sprite.fromImage('bunny.png');
stage.addChild(sprite);
sprite.y=200;
sprite.scale.x=4;
sprite.scale.y=4;
sprite.interactive = true;
MouseEventManager.add(sprite);
sprite.addListener("click",function(e){
console.log(e);
});
tf = new PIXI.Text("fps:0", {
font: '24px Arial',
fill: 0xff1010,
align: 'left'
});
stage.addChild(tf);
ticker=PIXI.ticker.shared;
ticker.autoStart=false;
ticker.start();
ticker.add(function(time){
renderer.render(stage);
});
setInterval(showFps, 1000);
}
function showFps(){
tf.text="fps:"+Math.round(ticker.FPS);
}
</script>
</head>
<body>
</body>
</html>关键在于这句:
MouseEventManager.add(sprite);
MouseEventManager在MouseEventManager.js中定义,通过touch事件实现click事件。
MouseEventManager.js代码如下:
//------------------------MouseEventManager.js--------------------------
//参考:https://developer.mozilla.org/zh-CN/docs/Web/API/TouchEvent
var MouseEventManager=new (function(){
var s=this;
var list=[];
s.add=function(dis){
s.remove(dis);
var item=new MouseEventItem(dis);
list.push(item);
}
s.remove=function(dis){
for(var i=0,len=list.length;i<len;i++){
var item=list[i];
if(item.dis==dis){
item.distroy();
list.splice(i,1);
break;
}
}
}
});
var MouseEventItem=function(dis){
var clicked=false;
dis.addListener("touchstart",touchStartHandler);
var interval=0;
var lastE=null;
function touchStartHandler(e){
lastE=e;
clicked=false;
dis.addListener("touchend",touchEndHandler);
document.addEventListener("touchend",touchCancel);
document.addEventListener("touchcancel",touchCancel);
document.addEventListener("touchmove",touchMove);
interval=setTimeout(longTouch,2000);
}
function touchMove(){
document.removeEventListener("touchmove",touchMove);
if(interval)clearTimeout(interval);
lastE=null;
}
function longTouch(){
dis.emit("longtouch",lastE,dis);
removelistener01();
}
function touchEndHandler(e){
clicked=true;
dis.emit("click",e,dis);
removelistener01();
}
function touchCancel(e){
if(!clicked){
dis.emit("cancel",e,dis);
removelistener01();
}
}
function removelistener01(){
dis.removeListener("touchend",touchEndHandler);
document.removeEventListener("touchend",touchCancel);
document.removeEventListener("touchcancel",touchCancel);
document.removeEventListener("touchmove",touchMove);
if(interval)clearTimeout(interval);
lastE=null;
}
this.distroy=function(){
dis.removeListener("touchstart",touchStartHandler);
removelistener01();
dis=null;
}
}pixi.js中事件只有一个target属性,相当于as中的currenttarget,没有as中的target属性。直接给事件添加属性,然后通过emit发送是不行的。后来我发现,emit方法可以指定多个参数,我们可以通过发送多个参数来实现target的传递。