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.