Skip to main content

如何使用 Vue 和 Konva 应用画布动画?

Konva 提供了两种动画方法:TweenAnimation。对于简单的用例,我们推荐使用 node.to() 方法,它是 Tween 的简化版。

使用说明:尝试拖动绿色矩形,观察它随机缩放,并观察红色六边形以正弦波模式移动。

<template>
  <v-stage ref="stage" :config="stageSize">
    <v-layer ref="layer">
      <v-rect
        ref="rect"
        @dragstart="changeSize"
        @dragend="changeSize"
        :config="{
          width: 50,
          height: 50,
          fill: 'green',
          draggable: true,
          x: 100,
          y: 100
        }"
      />
      <v-regular-polygon
        ref="hexagon"
        :config="{
          x: 200,
          y: 200,
          sides: 6,
          radius: 20,
          fill: 'red',
          stroke: 'black',
          strokeWidth: 4
        }"
      />
    </v-layer>
  </v-stage>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import Konva from 'konva';

const stageSize = {
  width: window.innerWidth,
  height: window.innerHeight
};

const stage = ref(null);
const hexagon = ref(null);

const changeSize = (e) => {
  // to() 是 `Konva.Node` 实例的方法
  e.target.to({
    scaleX: Math.random() + 0.8,
    scaleY: Math.random() + 0.8,
    duration: 0.2
  });
};

onMounted(() => {
  const amplitude = 100;
  const period = 5000; // 单位为毫秒
  const centerX = stage.value.getNode().getWidth() / 2;
  const hexagonNode = hexagon.value.getNode();

  // Konva.Animation 的示例
  const anim = new Konva.Animation((frame) => {
    hexagonNode.setX(
      amplitude * Math.sin((frame.time * 2 * Math.PI) / period) + centerX
    );
  }, hexagonNode.getLayer());

  anim.start();
});
</script>

上述演示展示了两种类型的动画:

  1. 使用 node.to() 方法(Tween)来在拖动时动画化绿色矩形的缩放
  2. 使用 Konva.Animation 创建红色六边形的连续正弦波运动

node.to() 方法非常适合简单的过渡,而 Konva.Animation 更适合需要在每一帧上运行的复杂连续动画。