Introduction
Let's start with a simple interactive example: let's have a slider that controls the movement of a circle on x-axis.
Initial version
Using the default Vue / Vitepress format it would look like this:
<script setup>
import { ref } from "vue";
const x = ref(0);
</script>
<svg width="400" height="20">
<circle :cx="x" cy="10" r="10" />
</svg>
<input type="range" v-model.number="x" max="400" />
> {{ x }}
0
Slider component
Great, but can we simplify this? Out input slider feels a bit lengthy and requires intimate knowledge of HTML input elements and Vue model bindings.
Let's use a component provided by Visualia, <v-slider />
. It is a lightweight wrapper around the range input element. Visualia components are auto-loaded with app.use(Visualia)
plugin, so we can use it right away.
<script setup>
import { ref } from "vue";
const x = ref(0);
</script>
<svg width="400" height="20">
<circle :cx="x" cy="10" r="10" />
</svg>
<v-slider v-model="x" max="400" />
> {{ x }}
0
Global variables
Can we simplify this even more? <script setup>
is a powerful way to have Javascript / Typescript code in the Markdown but when we just need to define a reactive variable x
it seems a little too verbose.
Here's the trick: Visualia allows to use of reactive object v.
for getting and setting global values.
<svg width="400" height="20">
<circle :cx="v.x" cy="10" r="10" />
</svg>
<v-slider v-model="v.x" max="400" />
> v.x is {{ v.x }}
v.x is
Adding multiple circles
Now let's do something more interesting with a moving dot, or even better, moving dots.
We can use Vue v-for
directive to create multiple circles:
<svg width="400" height="20">
<circle
v-for="a in 10"
:cx="x + a * 20"
cy="10"
r="10"
/>
</svg>
Bring in color
Let's bring in some color! Let's use a hsl()
function to control the color of the circles:
<svg width="400" height="20">
<circle
v-for="a in 10"
:cx="x + a * 20"
cy="10"
:fill="hsl(a * 36,100,50)"
r="10"
/>
</svg>
Adding more movement
Finally, get some lifelike movement here. Buy using Javascript's Math.sin()
and some experimentation with coordinates we end up here:
<svg width="400" height="40">
<circle
v-for="a in 10"
:cx="x + a * 20"
:cy="Math.sin(a + x / 20) * 10 + 20"
:fill="hue(a * 36)"
r="10"
/>
</svg>