ArrowFlow.ts 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  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. origin: THREE.Vector3;
  11. /** 流线终点 */
  12. destiny: THREE.Vector3;
  13. /** 流线 */
  14. path: THREE.LineCurve3;
  15. /** 重复次数 */
  16. repeat: THREE.Vector2;
  17. /** 图形偏移量 */
  18. offset: THREE.Vector2;
  19. /** 动画控制器 */
  20. tween: gsap.core.Tween | null = null;
  21. constructor(
  22. texturePath: '/model/img/blueArrow.png' | '/model/img/greenArrow.png' | '/model/img/redArrow.png',
  23. origin: THREE.Vector3,
  24. destiny: THREE.Vector3,
  25. {
  26. repeatX = 20,
  27. repeatY = 1,
  28. /** 0-1 */
  29. offsetX = 0,
  30. /** 0-1 */
  31. offsetY = 0.5,
  32. } = {}
  33. ) {
  34. const t = new THREE.TextureLoader().load(texturePath);
  35. t.wrapS = THREE.RepeatWrapping;
  36. t.wrapT = THREE.RepeatWrapping;
  37. t.repeat = new THREE.Vector2(repeatX, repeatY);
  38. t.offset = new THREE.Vector2(offsetX, offsetY);
  39. super({ map: t, transparent: true });
  40. this.path = new THREE.LineCurve3(origin, destiny);
  41. this.texture = t;
  42. this.origin = origin;
  43. this.destiny = destiny;
  44. this.repeat = t.repeat;
  45. this.offset = t.offset;
  46. }
  47. /**
  48. * 启动动画效果
  49. * @param speed number 类型,配合 offset 使用,越小速度越慢,大于 0
  50. * @param offsetX
  51. * @param offsetY
  52. */
  53. startAnimation(speed: number = 1, offsetX: number = -0.01, offsetY: number = 0) {
  54. if (this.tween) {
  55. this.tween.kill();
  56. }
  57. this.tween = gasp.to(this, {
  58. duration: 1,
  59. repeat: -1,
  60. onUpdate: () => {
  61. this.texture.offset.setX(this.texture.offset.x + offsetX * speed);
  62. this.texture.offset.setY(this.texture.offset.y + offsetY * speed);
  63. },
  64. });
  65. }
  66. pauseAnimation() {
  67. if (!this.tween) return;
  68. this.tween.pause();
  69. }
  70. stopAnimation() {
  71. if (!this.tween) return;
  72. this.tween.kill();
  73. }
  74. }