Pointer 事件

基础用法:事件里,我们介绍了sprite事件的基本原理和用法。

在 SpriteJS Next 里,元素的事件点击区域是由 isPointCollision(x, y) 方法决定的,我们可以通过改写它,来改变元素事件可点击区域。

这个方法的改写会影响所有的鼠标和touch事件判定。

其他事件

在 SpriteJS Next 里,除了Pointer事件,还有一些默认的绘图和其他事件,主要有:

  • beforerender 元素开始绘制
  • afterrender 元素结束绘制
  • preload Scene加载资源

其中preload前面我们已经见过,这里我们看一下 beforerender/afterrender 的用法。

  1. const {Scene, Sprite} = spritejs;
  2. const container = document.getElementById('adaptive');
  3. const scene = new Scene({
  4. container,
  5. width: 1200,
  6. height: 600,
  7. });
  8. const layer = scene.layer();
  9. const s1 = new Sprite({
  10. pos: [600, 300],
  11. size: [200, 200],
  12. anchor: 0.5,
  13. bgcolor: 'red',
  14. });
  15. const s2 = new Sprite({
  16. pos: [600, 300],
  17. size: [200, 200],
  18. anchor: 0.5,
  19. bgcolor: 'blue',
  20. rotate: 45,
  21. });
  22. s2.addEventListener('beforerender', ({detail}) => {
  23. const gl = detail.context;
  24. gl.blendFuncSeparate(gl.ONE, gl.ZERO, gl.ZERO, gl.ONE);
  25. });
  26. s2.addEventListener('afterrender', ({detail}) => {
  27. const gl = detail.context;
  28. gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
  29. });
  30. layer.append(s1, s2);

自定义事件

SpriteJS Next 的 Scene 默认代理了点击事件(Pointer Events)包括鼠标和触屏事件,要响应其他事件比如键盘事件或者与页面上的其他元素交互,我们可以通过元素的dispatchEvent方法将事件派发给对应元素。

  1. const {Scene, Label} = spritejs;
  2. const container = document.getElementById('adaptive');
  3. const scene = new Scene({
  4. container,
  5. width: 1200,
  6. height: 600,
  7. });
  8. const layer = scene.layer();
  9. const keys = [
  10. 'qwertyuiop',
  11. 'asdfghjkl',
  12. 'zxcvbnm',
  13. ];
  14. for(let i = 0; i < 3; i++) {
  15. const keyButtons = [...keys[i]];
  16. for(let j = 0; j < keyButtons.length; j++) {
  17. const key = new Label({
  18. id: keyButtons[j],
  19. text: keyButtons[j],
  20. pos: [250 + j * 80, 200 + i * 100],
  21. font: '42px Arial',
  22. borderWidth: 4,
  23. borderColor: 'black',
  24. size: [50, 50],
  25. anchor: [0.5, 0.5],
  26. textAlign: 'center',
  27. lineHeight: 50,
  28. });
  29. layer.append(key);
  30. }
  31. }
  32. document.addEventListener('keydown', (event) => {
  33. const key = event.key;
  34. const button = scene.getElementById(key);
  35. button.attr({
  36. bgcolor: 'grey',
  37. fillColor: 'white',
  38. });
  39. });
  40. document.addEventListener('keyup', (event) => {
  41. const key = event.key;
  42. const button = scene.getElementById(key);
  43. button.attr({
  44. bgcolor: '',
  45. fillColor: 'black',
  46. });
  47. });

事件穿透

与DOM元素一样,SpriteJS Next 的可见元素之间默认会互相遮挡,但是有以下几种情况不会遮挡:

  • 事件目标元素的pointerEvents属性设置为none
  • 事件目标元素不可见且pointerEvents属性不为all
  • 事件目标元素是Layer元素

另外如果pointerEvents设为visibleStroke,那么块元素的border或Path元素的stroke部分会遮挡事件;如果pointerEvents设为visibleFill,那么块元素不包含border和Path元素fill的部分会遮挡事件。

不派发事件

与旧版本的SpriteJS一样,可以给Layer设置参数handleEventfalse,那么Scene将不向该Layer派发事件,这么做能够提升性能纯展示Layer的渲染性能。