#vue.js #animation #svg #nuxt.js #konva
Вопрос:
работа с vue-konva (библиотека холстов на основе svg) прямо сейчас. Я пытаюсь анимировать все фигуры, которые определяются v-образным контуром. При попытке использовать функции библиотеки анимации Konva я получаю ошибку «Не удается прочитать свойство ‘getNode’ неопределенного». Я предполагаю, что это связано с тем фактом, что ссылка должна содержать один конкретный элемент и не должна быть адресована внутри цикла v-for. Как я могу одновременно анимировать все полигоны?
SVG / элемент холста:
<v-regular-polygon
v-for="el in results"
ref="hexagon"
:key="el.index"
:config="{
x: 200 * Math.abs(el.land),
y: 200,
sides: 6,
radius: 20,
fill: 'red',
stroke: 'black',
strokeWidth: 4,
}"
/>
функция, отвечающая за анимацию
mounted() {
this.fetchTemperature()
const vm = this
const amplitude = 100
const period = 5000
// in ms
const centerX = vm.$refs.stage.getNode().getWidth() / 2
const hexagon = this.$refs.hexagon.getNode()
// example of Konva.Animation
const anim = new Konva.Animation(function (frame) {
hexagon.setX(amplitude * Math.sin((frame.time * 2 * Math.PI) / period) centerX)
}, hexagon.getLayer())
anim.start()
},
Ответ №1:
Вы можете задать уникальную ссылку для каждого полигона, добавив индекс.
<v-regular-polygon
v-for="(el, i) in results"
:ref="`hexagon_${i}`"
...
Вот пример:
<template>
<div id="app">
<v-stage :config="configKonva">
<v-layer>
<v-circle
v-for="(item, i) in items"
:config="item"
:key="i"
:ref="`circle_${i}`"
></v-circle>
</v-layer>
</v-stage>
</div>
</template>
<script>
import Konva from "konva";
export default {
name: "App",
data() {
return {
items: [
{
x: 30,
y: 100,
radius: 20,
fill: "red",
stroke: "black",
strokeWidth: 2,
},
{
x: 100,
y: 100,
radius: 20,
fill: "red",
stroke: "black",
strokeWidth: 2,
},
],
configKonva: {
width: 200,
height: 200,
},
};
},
mounted() {
for (let i = 0; i < this.items.length; i ) {
const node = this.$refs[`circle_${i}`][0].getNode();
const period = 1000;
const amplitude = 10;
const anim = new Konva.Animation((frame) => {
node.setX(
amplitude * Math.sin((frame.time * 2 * Math.PI) / period)
this.items[i].x
);
}, node.getLayer());
anim.start();
}
},
};
</script>
Комментарии:
1. Большое спасибо! Попробовал, но я получаю ту же ошибку. По вашему предложению, должен ли я изменить ссылку в методе анимации? Внутри здесь: const hexagon = this.$refs.hexagon.getNode() Учитывая, что новая ссылка :ref=»
hexagon_${i}
»2. Конечно, вам также следует изменить метод получения ссылок, например
const hexagon = this.$refs[
, hexagon_${i}].getNode()
, гдеi
находится индекс в вашем цикле в массиве полигонов.3. Можете ли вы привести мне пример? Если я хочу «массово» анимировать все шестиугольники сразу, то все они должны иметь одинаковую анимацию. Танки!
4. Я добавил пример с парой кругов, анимированных с помощью фреймворка Konva