Vue.js 1000 SVG dots
by ChangJoo Park
HTML
<script src="https://cdn.jsdelivr.net/stats.js/r11/stats.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<div id="app">
<svg>
<circle v-for='point in model.points' :cx='point.x' :cy='point.y' r='2px' fill='#FC309D'></circle>
</svg>
</div>
CSS
html,
body {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
overflow: hidden;
}
svg {
width: 400px;
height: 400px;
}
Vue
var stats = new Stats()
stats.setMode(2)
stats.domElement.style.position = 'absolute'
stats.domElement.style.right = '0px'
stats.domElement.style.top = '0px'
document.body.appendChild(stats.domElement)
var WIDTH = 400
var HEIGHT = 400
new Vue({
el: '#app',
data: {
model: createModel(1000),
optimized: true
},
created: function() {
var self = this
requestAnimationFrame(render)
stats.begin()
function render() {
stats.end()
stats.begin()
requestAnimationFrame(render)
self.model.step()
if (self.optimized) {
self.$forceUpdate()
}
}
},
methods: {
toggleOptimization: function() {
this.model = this.optimized ?
createModel(1000) :
Object.freeze(createModel(1000))
this.optimized = !this.optimized
}
}
});
function createModel(count) {
var points = []
for (var i = 0; i < count; ++i) {
points.push({
x: Math.random() * WIDTH,
y: Math.random() * HEIGHT,
vx: Math.random() * 4 - 2,
vy: Math.random() * 4 - 2
})
}
return {
points: points,
step: step
}
function step() {
points.forEach(move)
}
function move(p) {
if (p.x > WIDTH || p.x < 0) p.vx *= -1
if (p.y > HEIGHT || p.y < 0) p.vy *= -1
p.y += p.vy
p.x += p.vx
}
}