Skip to content

Instantly share code, notes, and snippets.

@zezic
Created July 9, 2018 08:31
Show Gist options
  • Save zezic/c6d6e77bb1da853339e8f821455fd3b6 to your computer and use it in GitHub Desktop.
Save zezic/c6d6e77bb1da853339e8f821455fd3b6 to your computer and use it in GitHub Desktop.
Draw and animate SVG with Vue.js and Tween.js
<template lang='pug'>
.svg-chart
button(@click='randomize') Randomize
transition-group(name='list', tag='div')
svg.chart(
v-for='item in list',
:width='width',
:height='height',
:key='item.key'
)
path(
:d='pathD',
fill='transparent',
stroke='#0088ff',
stroke-width='3'
)
</template>
<script>
import TWEEN from '@tweenjs/tween.js'
const getDataSet = () => {
return [...Array(15)].map(() => Math.random())
}
const getUUID = () => Math.random().toString()
export default {
name: 'svg-chart',
data () {
return {
height: 200,
width: 500,
dataSet: getDataSet(),
tweenedSet: [],
tween: null,
key: getUUID()
}
},
created () {
this.tweenedSet = [...this.dataSet]
},
computed: {
list () {
return [{key: this.key}]
},
stepSize () {
return this.width / (this.dataSet.length - 1)
},
points () {
return this.tweenedSet.map((item, idx) => {
return {
y: this.height * item,
x: idx * this.stepSize
}
})
},
pathD () {
return this.points.reduce((acc, point, idx) => {
let op = idx === 0 ? 'M' : 'L'
return `${acc} ${op} ${point.x},${point.y}`
}, '')
}
},
methods: {
randomize () {
this.dataSet = getDataSet()
}
},
watch: {
dataSet (newSet, oldSet) {
if (this.tween) {
this.tween.stop()
}
this.key = getUUID()
function animate () {
if (TWEEN.update()) {
requestAnimationFrame(animate)
}
}
this.tween = new TWEEN.Tween(
oldSet
).to(
newSet,
1000
).onUpdate(set => {
this.tweenedSet = [...set]
}).start()
animate()
}
}
}
</script>
<style scoped lang='sass'>
.svg-chart
position: relative
.chart
position: absolute
left: 0
.list-enter-active, .list-leave-active
transition: all 1s
.list-leave-to
opacity: 0
.list-enter-active
stroke-dasharray: 1300
stroke-dashoffset: 1300
.list-enter-to
stroke-dashoffset: 0
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment