Просмотр исходного кода

feat: 五维沙盘粒子流动画

新增 FlowAnimation 粒子流覆盖层,五维能量沿星形路径流动

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
User 4 месяцев назад
Родитель
Сommit
fd61650573
1 измененных файлов с 56 добавлено и 1 удалено
  1. 56 1
      cfc-frontend/components/wuxing-sandbox.vue

+ 56 - 1
cfc-frontend/components/wuxing-sandbox.vue

@@ -15,6 +15,9 @@
     <!-- Canvas 2D 五行星图 -->
     <canvas id="starCanvas" type="2d" style="width:100%;height:100%;position:absolute;top:0;left:0;z-index:1"></canvas>
 
+    <!-- Canvas 粒子动画覆盖层 -->
+    <canvas id="flowCanvas" type="2d" style="width:100%;height:100%;position:absolute;top:0;left:0;z-index:1;pointer-events:none"></canvas>
+
     <!-- Canvas 点击感应层 -->
     <view class="canvas-tap-area" @click="onCanvasTap"></view>
 
@@ -76,6 +79,7 @@
 import { renderStar, calcStarVertices } from './wuxing-sandbox-helpers/render.js'
 import { FillAnimator } from './wuxing-sandbox-helpers/animation.js'
 import { detectHitArm, armIndexToDomain } from './wuxing-sandbox-helpers/hitdetect.js'
+import { FlowAnimation } from './wuxing-sandbox-helpers/flow-animation.js'
 
 var DIM_KEYS = ['body', 'mind', 'wisdom', 'action', 'wealth']
 
@@ -157,7 +161,9 @@ export default {
       animWisdom: 0,
       animAction: 0,
       animWealth: 0,
-      _animator: null
+      _animator: null,
+      _flowAnim: null,
+      _flowCanvasReady: false
     }
   },
   computed: {
@@ -295,6 +301,12 @@ export default {
       if (this.canvasReady) {
         this._startAnimation()
       }
+    },
+    sortedDimensions: function(newVal) {
+      if (this._flowAnim && this._flowCanvasReady) {
+        var dimOrder = newVal.map(function(d) { return d.code })
+        this._flowAnim.refreshPaths({ dimOrder: dimOrder })
+      }
     }
   },
   mounted: function() {
@@ -326,6 +338,10 @@ export default {
       this._animator.cancel()
       this._animator = null
     }
+    if (this._flowAnim) {
+      this._flowAnim.stop()
+      this._flowAnim = null
+    }
   },
   methods: {
     /* ===========================
@@ -411,6 +427,7 @@ export default {
           self.canvasReady = true
 
           self._startAnimation()
+          self._initFlowCanvas()
         })
     },
 
@@ -447,6 +464,44 @@ export default {
       this._animator.start(this.activeTs, 600)
     },
 
+    /* ===========================
+    粒子流量动画
+    =========================== */
+
+    _initFlowCanvas: function() {
+      var self = this
+      var dimOrder = this.sortedDimensions.map(function(d) { return d.code })
+
+      uni.createSelectorQuery().in(this).select('#flowCanvas')
+        .fields({ node: true, size: true })
+        .exec(function(res) {
+          if (!res || !res[0] || !res[0].node) return
+
+          var canvas = res[0].node
+          var width = res[0].width
+          var height = res[0].height
+          if (!width || !height) return
+
+          var pixelRatio = uni.getSystemInfoSync().pixelRatio || 2
+          canvas.width = width * pixelRatio
+          canvas.height = height * pixelRatio
+
+          var ctx = canvas.getContext('2d')
+          ctx.scale(pixelRatio, pixelRatio)
+
+          var outerR = Math.min(width, height) * 0.46
+          var vertices = calcStarVertices(width / 2, height / 2, outerR)
+
+          self._flowAnim = new FlowAnimation(ctx, width, height, {
+            outer: vertices.outer,
+            inner: vertices.inner,
+            dimOrder: dimOrder
+          })
+          self._flowAnim.start()
+          self._flowCanvasReady = true
+        })
+    },
+
     /* ===========================
     点击检测
     =========================== */