ArrowFlow.ts 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. import * as THREE from 'three';
  2. import gasp from 'gsap';
  3. /**
  4. * 箭头流工具类,用于创建箭头流动的相关材质、几何、动画并管理其生命周期
  5. */
  6. export default class ArrowFlow extends THREE.MeshBasicMaterial {
  7. /** 箭头流材质 */
  8. texture: THREE.Texture;
  9. /** 重复次数 */
  10. repeat: THREE.Vector2;
  11. /** 图形偏移量 */
  12. offset: THREE.Vector2;
  13. /** 动画控制器 */
  14. tween: gsap.core.Tween | null = null;
  15. constructor(
  16. texturePath: '/model/img/blueArrow.png' | '/model/img/greenArrow.png' | '/model/img/redArrow.png',
  17. {
  18. repeatX = 20,
  19. repeatY = 1,
  20. /** 0-1 */
  21. offsetX = 0,
  22. /** 0-1 */
  23. offsetY = 0.5,
  24. } = {}
  25. ) {
  26. const t = new THREE.TextureLoader().load(texturePath);
  27. t.wrapS = THREE.RepeatWrapping;
  28. t.wrapT = THREE.RepeatWrapping;
  29. t.repeat = new THREE.Vector2(repeatX, repeatY);
  30. t.offset = new THREE.Vector2(offsetX, offsetY);
  31. super({ map: t, transparent: true });
  32. this.texture = t;
  33. this.repeat = t.repeat;
  34. this.offset = t.offset;
  35. }
  36. /**
  37. * 启动动画效果
  38. * @param speed number 类型,配合 offset 使用,越小速度越慢,大于 0
  39. * @param offsetX
  40. * @param offsetY
  41. */
  42. startAnimation(speed: number = 1, offsetX: number = -0.01, offsetY: number = 0) {
  43. if (this.tween) {
  44. this.tween.kill();
  45. }
  46. this.tween = gasp.to(this, {
  47. duration: 1,
  48. repeat: -1,
  49. onUpdate: () => {
  50. this.texture.offset.setX(this.texture.offset.x + offsetX * speed);
  51. this.texture.offset.setY(this.texture.offset.y + offsetY * speed);
  52. },
  53. });
  54. }
  55. pauseAnimation() {
  56. if (!this.tween) return;
  57. this.tween.pause();
  58. }
  59. resumeAnimation() {
  60. if (!this.tween) return;
  61. this.tween.resume();
  62. }
  63. stopAnimation() {
  64. if (!this.tween) return;
  65. this.tween.kill();
  66. }
  67. hideElement() {
  68. this.visible = false;
  69. if (!this.tween) return;
  70. this.pauseAnimation();
  71. }
  72. showElement() {
  73. this.visible = true;
  74. if (!this.tween) return;
  75. this.resumeAnimation();
  76. }
  77. }