Hi!
In this tutorial you will learn how to make a "heart clicker" interaction/game!
This tutorial can be a good practice for anyone who want to learn javascript, vue, web-development, it can also fit experience developers who needs a little refreshment.
To make this tutorial work for your best, please prepare the following, I'll be waiting here:
- Vue app (you can use vue-cli).
- firebase project and App (we'll setup it later).
Ok good, now we're ready to start.
Part 1 - Create the heart
In this part we'll focus on drawing the heart using javascript canvas element.
Create a new component, name it HeartClicker and replace all the App.vue template with this component, so your app template should look like follow:
<template>
<div id="app">
<HeartClicker />
</div>
</template>
Add a canvas element to your template, you can wrap it with a div for later use.
<template>
<div>
<canvas
id="heart"
:width="width"
:height="height"></canvas>
</div>
</template>
Now, define the width and height properties for the heart in your component's data:
data() {
return {
width: 150,
height: 150
}
}
Drawing the heart will be done in the mounted method, which will be called after view is rendered, according to Vue documentation:
Called after the instance has been mounted, where el is replaced by the newly created vm.$el. If the root instance is mounted to an in-document element, vm.$el will also be in-document when mounted is called.
Grabbing the html canvas to draw the heart:
const canvas = this.$el.querySelector('#heart');
if (canvas.getContext) {
const ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.moveTo(75, 40);
ctx.bezierCurveTo(75, 37, 70, 25, 50, 25);
ctx.bezierCurveTo(20, 25, 20, 62.5, 20, 62.5);
ctx.bezierCurveTo(20, 80, 40, 102, 75, 120);
ctx.bezierCurveTo(110, 102, 130, 80, 130, 62.5);
ctx.bezierCurveTo(130, 62.5, 130, 25, 100, 25);
ctx.bezierCurveTo(85, 25, 75, 37, 75, 40);
ctx.fillStyle = '#FF0000'; // heart color
ctx.fill(); // fill the shape we draw
}
Check your browser, it should display a heart:
Part 2 - firebase setup
Add a realtime database in test mode for now (you can change it later).
Create a field name 'count' with value of zero:
Now add firebase to your project with npm or yarn:
npm i firebase
In the src folder create a new folder services and add a file ClickCountManager.js.
Separating the logic for firebase is a good practice, you can use this script in other projects that are not vue.
ClickCountManager.js:
import firebase from 'firebase';
const firebaseConfig = {
...
};
firebase.initializeApp(firebaseConfig);
const db = firebase.database();
const firebaseCountRef = db.ref('/count');
const registerToCounts = (onValue) => {
firebaseCountRef.on('value', snapshot => onValue(snapshot.val()));
}
const addClick = () => {
firebaseCountRef.transaction(function(count) {
return count + 1;
})
}
export {addClick, registerToCounts}
Copy the firebaseConfig from firebase settings under 'your apps'
Let's analyze the script.
First we initialize the firebase app using firebase.initializeApp(firebaseConfig)
function, then we reference to firebase database and the count field that we created earlier in our realtime database:
const db = firebase.database();
const firebaseCountRef = db.ref('/count');
registerToCounts function will be used to get updates to the global counter that we save in firebase.
addClick function adds and save a new click to our count field.
We export these functions to use in our HeartClicker component.
Part 3 - use firebase in our component
Now that we have firebase ready and set we can use it in our HeartClicker component.
Go back to the HeartClicker component, import ClickCountManager methods:
import {addClick, registerToCounts} from '../services/ClickCountManager';
Add a new globalClicks field to our data:
data() {
...
globalClicks: 0,
}
then add a new 'onClick' handler method in HeartClicker component:
methods: {
onClick(e) {
addClick();
}
Attach the method to the canvas element:
<template>
<div>
<canvas
id="heart"
:width="width"
:height="height"
@click="onClick"></canvas>
<p>{{globalClicks}}</p>
</div>
</template>
And lastly, register to count updates in the created function of your component:
created() {
registerToCounts(globalClicks => {
this.globalClicks = globalClicks;
})
},
I register to counts in the [created] lifecycle hook (https://vuejs.org/v2/api/#created) so we'll have that data before the component mounts. I recommend to have a look at Vue lifecycle diagram.
Open the browser and click the heart, you should see the count field in firebase and the globalCount property update.
Summary
What you've learned:
- Create a Vue component
- Use data in a Vue component
- Vue lifecycle
- Use and integrate firebase realtime database I hope you enjoyed this tutorial, please write your thoughts/feedback in the discussion below.
Bonus Level! - add "juice"
If you want to spice things up, you can continue to the bonus level where you will learn how to add "juice" to your heart by using some simple css and canvas particles.
The bonus level is in another post:
Bonus Level - vue.js and firebase "Heart Click"
Shai Angress ・ Jan 30 '21
You can grab the source here:
Top comments (2)
What a fantastic walkthrough to get a grip of both Firebase and Vue.js.
Thank you for sharing this valuable resource Shai.
Thrilled to see more of your content
Thanks! glad you enjoyed!