Vue.js is a framework with high potential. It’s easy to learn, fast, and light in terms of bytes. Now, I’m going to continue my journey through this framework with a more relaxing piece about Vue.js animations. We’ll implement some basic sorting algorithms and animate each sort move.
You’ll find the final result in my repository.
First of all, let’s create four new files:
index.html
app.js
style.css
sorting.js
Add the reference to the style sheet to index.html
, to our two JavaScripts file, and, of course, to Vue.js:
<head>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<link href="style.css" rel="stylesheet" />
</head>
<!-- ... -->
<script src="sorting.js"></script>
<script src="app.js"></script>
</body>
Then make a draft of our application appearance:
A draft look of our animation playground with Vue.js
As you can see, our application is composed of:
We need to implement a function
for each button. A little trick to slow down each sorting operation is to define a sleep
function in order to let the animation play in a visible time, otherwise it will be too fast to see the moves.
We’ll put each of these functions in the sorting.js
file.
function sleep() {
return new Promise(resolve => setTimeout(resolve, 550));
}
The sleep function that’ll wait 550 milliseconds
Then, we’ll need two methods to let Vue.js notify that the array is changed. The solution is to not use the [x]
operator to swap items but use splice()
. Remember that the Vue.js array notifies changes only when these methods are called:
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
function arraySetWithoutIndexes(array, index, value) {
array.splice(index, 1, value);
}
function arraySwap(array, indexA, indexB) {
var x = array[indexA];
arraySetWithoutIndexes(array, indexA, array[indexB]);
arraySetWithoutIndexes(array, indexB, x);
}
Let’s define a shuffle
function to mess with the array elements’ positions:
async function shuffle(a) {
var j, i;
for (i = a.length - 1; i > 0; i--) {
j = Math.floor(Math.random() * (i + 1));
arraySwap(a, i, j);
await sleep();
}
}
Notice the use of:
async
: we want to asynchronously wait for the sleep operation to completearraySwap
: swapping elements with splice()
in order to notify the swap to our representation of the arraysleep
: in order to slow down each swap operationasync function bubbleSort(a) {
var len = a.length;
for (var i = len - 1; i >= 0; i--) {
for (var j = 1; j <= i; j++) {
if (a[j - 1] > a[j]) {
arraySwap(a, j - 1, j);
await sleep();
}
}
}
}
async function selectionSort(a) {
var minIdx, temp,
len = a.length;
for (var i = 0; i < len; i++) {
minIdx = i;
for (var j = i + 1; j < len; j++) {
if (a[j] < a[minIdx]) {
minIdx = j;
}
}
arraySwap(a, i, minIdx);
await sleep();
}
}
async function insertionSort(a) {
var i, len = a.length, el, j;
for (i = 1; i < len; i++) {
el = a[i];
j = i;
while (j > 0 && a[j - 1] > el) {
a[j] = a[j - 1];
j--;
}
arraySetWithoutIndexes(a, j, el);
await sleep();
}
}
<div id="app-sorting">
<div>
<transition name="fade" v-if="!isManipulatingArray">
<div class="buttons-container">
<button class="button" v-on:click="shuffle()"><span>{{ shuffleButtonText }}</span></button>
<button class="button" v-for="b in sortAlgorithms" v-on:click="sort(b)">{{ b.name }}</button>
</div>
</transition>
</div>
<transition-group tag="div" name="list-animation" class="array-to-be-sorted">
<div v-for="num in arrayToBeSorted" v-bind:key="num" v-bind:class="[ num % 2 == 0 ? 'even' : 'odd', 'list-animation-item', 'list-item' ]">
<span>{{ num }}</span>
</div>
</transition-group>
</div>
As you can see, our template is divided into two parts:
transition-group
in order to render the animation. The array is represented only with a simple v-for
.In our app.js
, we’ll define this Vue.js application:
var sortingApp = new Vue({
el: '#app-sorting',
data: {
arrayToBeSorted: [1, 2, 3, 4, 5, 6, 7, 8],
isManipulatingArray: false,
shuffleButtonText: "Shuffle!",
sortAlgorithms: [
{ name: "Bubble sort", fn: bubbleSort },
{ name: "Selection sort", fn: selectionSort },
{ name: "Insertion sort", fn: insertionSort }
]
},
methods: {
shuffle: function () {
this.isManipulatingArray = true;
shuffle(this.arrayToBeSorted).then(() => this.isManipulatingArray = false);
},
sort: function (sortAlgorithm) {
this.isManipulatingArray = true;
sortAlgorithm.fn(this.arrayToBeSorted).then(() => this.isManipulatingArray = false);
}
}
});
As you can see, the list of sorting functions are defined in an array with a name and a function delegate, in order to make them bind with the buttons container.
Moreover, the shuffle and sort functions manage the isManipulatingArray
property to notify the template when to show or hide the buttons container.
Animations are written in the CSS file. They’re quite basic, we’ll just:
div
are obtained with the opacity
and transform
properties.list-animation-item {
transition: all ease 0.5s;
}
.fade-enter-active, .fade-leave-active {
transition: all ease 1s;
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
opacity: 0;
transform: translateY(-30px) scale(0.9);
}
Thank you for reading! If you enjoyed this article, please share it with others who may enjoy it as well.!
#Vuejs #Vue #JavaScript #Programming #Web Development