We can make working with the HTML canvas easier in Vue apps with the Vue Konva library.
In this article, we’ll take a look at how to use Vue Konva to make working with the HTML canvas easier in a Vue app.
Animation
We can animation shapes with the Konva.Animation constructor.
For example, we can write:
<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,
}"
/>
<v-regular-polygon
ref="octagon"
:config="{
x: 200,
y: 200,
sides: 8,
radius: 20,
fill: 'red',
stroke: 'black',
strokeWidth: 4,
}"
/>
</v-layer>
</v-stage>
</template>
<script>
import Konva from "konva";
const width = window.innerWidth;
const height = window.innerHeight;
export default {
data() {
return {
stageSize: {
width: width,
height: height,
},
};
},
methods: {
changeSize(e) {
e.target.to({
scaleX: Math.random() + 0.8,
scaleY: Math.random() + 0.8,
duration: 0.2,
});
},
},
mounted() {
const vm = this;
const amplitude = 100;
const period = 5000;
const centerX = vm.$refs.stage.getNode().getWidth() / 2;
const octagon = this.$refs.octagon.getNode();
const anim = new Konva.Animation((frame) => {
octagon.setX(
amplitude * Math.sin((frame.time * 2 * Math.PI) / period) + centerX
);
}, octagon.getLayer());
anim.start();
},
};
</script>
We call the Konva.Animation constructor with a callback to change the x coordinate of the item with setX .
Then we call anim.start to start the animation.
The changeSize method is called when we’re dragging the rectangle.
It changes the position when we drag on the object.
Cache
We can cache the items rendered with the cache method.
For example, we can write:
<template>
<div>
<v-stage ref="stage" :config="stageConfig">
<v-layer ref="layer">
<v-group ref="group">
<v-star
v-for="item in list"
:key="item.id"
:config="{
x: item.x,
y: item.y,
rotation: item.rotation,
id: item.id,
numPoints: 5,
innerRadius: 30,
outerRadius: 50,
fill: 'lightgreen',
opacity: 0.8,
shadowColor: 'black',
shadowBlur: 10,
shadowOpacity: 0.6,
scaleX: item.scale,
scaleY: item.scale,
}"
/>
</v-group>
</v-layer>
</v-stage>
<div class="cache">
<input type="checkbox" @change="handleCacheChange" /> cache shapes
</div>
</div>
</template>
<script>
const width = window.innerWidth;
const height = window.innerHeight;
export default {
data() {
return {
list: [],
dragItemId: null,
stageConfig: {
width: width,
height: height,
draggable: true,
},
};
},
methods: {
handleCacheChange(e) {
const shouldCache = e.target.checked;
if (shouldCache) {
this.$refs.group.getNode().cache();
} else {
this.$refs.group.getNode().clearCache();
}
},
},
mounted() {
for (let n = 0; n < 300; n++) {
this.list.push({
id: n.toString(),
x: Math.random() * width,
y: Math.random() * height,
rotation: Math.random() * 180,
scale: Math.random(),
});
}
},
};
</script>
<style>
body {
margin: 0;
padding: 0;
}
.cache {
position: absolute;
top: 0;
left: 0;
}
</style>
to add 300 stars.
In the handleCacheChange method, we call cache on the v-group ‘s ref to cache the content if the checkbox is checked.
Otherwise, we clear the cache with clearCache .
Conclusion
We can animate shapes and cache them with Vue Konva.