Skip to content

Latest commit

 

History

History
298 lines (260 loc) · 10.1 KB

File metadata and controls

298 lines (260 loc) · 10.1 KB
layout lesson
title Bubble popper
desc Use jQuery & CSS animations and transitions to make a small application that makes and pops random bubbles.
markbot_submit true
hide_show_for_marks true
extra_tutorials
title url
JavaScript + jQuery effects
javascript-jquery-effects
title url
JavaScript cheat sheet
javascript-cheat-sheet
title url
JavaScript + jQuery effects slide deck
/courses/javascript/javascript-jquery-effects/
goal
before image notes
We’ll have a fully functional application that—when the space key is pressed—makes a random, poppable bubble.
goal.gif
label text
Type it, type it real good
Remember the purpose of this lesson is to type the code out yourself—build up that muscle memory in your fingers!
fork
url
steps
title before folders after notes
Set up project
Before we get started, create some files and get ready.
label type
bubble-popper
folder
label indent
index.html
1
label type indent
css
folder
1
label indent
main.css
2
label type indent
js
folder
1
label indent
main.js
2
1. Make an `index.html` & add the boilerplate code. 2. Make a `main.css` in your `css` folder & add the boilerplate code. 3. Make an empty `main.js` in your `js` folder & connect it to your HTML. 4. Connect jQuery to your website, with the URL from [cdnjs](https://cdnjs.cloudflare.com/).
label text
Naming conventions
Don’t forget to follow the [naming conventions](/topics/naming-paths-cheat-sheet/#naming-conventions).
title before code_lang code_file code lines notes
HTML setup
We’re not going to need any HTML elements to make this work, so the `<body>` can stay empty except for the `<script>` tags.
html
index.html
<!DOCTYPE html> <html lang="en-ca"> <head> <meta charset="utf-8"> <title>Bubble popper</title> <meta name="viewport" content="width=device-width,initial-scale=1"> <link href="css/main.css" rel="stylesheet"> </head> <body> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <script src="js/main.js"></script> </body> </html>
num text
11
Don’t forget to hook up jQuery.
label text
HTML snippets
Create the boilerplate with `html5`, `viewport`, `css` & `jss`
title before code_lang code_file code lines notes
Styling the bubbles
With a touch of CSS we can transform any `<div>` into a bubble.
css
css/main.css
html { box-sizing: border-box; } *, *::before, *::after { box-sizing: inherit; } .bubble { left: 0; top: 0; position: absolute; height: 50px; width: 50px; border-radius: 50%; background-color: lightblue; }
num text
10-12
Using `position: absolute` is really important here because we want to be able to the move the circle around the screen with coordinates.
label text
CSS snippets
Create the boilerplate with `borderbox`
title before code_lang code_file code lines after
Add random bubbles to the screen
When the `Space` key is pressed on the keyboard, we’re going to create a new `<div>` tag, with the class of bubble, and place it on the screen in a random location.
js
js/main.js
var $body = $('body'); $('html').on('keydown', function (e) { var $bubble; if (e.key == ' ') { $bubble = $('<div>'); $bubble.addClass('bubble'); $bubble.css({ 'top': Math.random() * (document.documentElement.clientHeight - 100), 'left': Math.random() * (document.documentElement.clientWidth - 100) }); $body.append($bubble); } });
num text
6
The `Space` key is represented by the key `' '` a literal space. [You can see all the different key values here.](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values)
num text
9
If we want to change multiple CSS properties at the same time we can pass and object to the `.css()` function instead of calling it multiple times.
num text
10-11
We can use `document.documentElement.clientWidth` & `height` to constrain the random coordinates to the dimensions of the window. The `- 100` here is subtracting the width of the circle so they don’t appear slightly off the screen.
At this point, pressing the `Space` key should create a random bubble on the screen. ![](create.gif)
title before code_lang code_file code lines after
Make the bubbles grow
When the bubbles appear on the screen, it’d be neat if they grew into place. With some CSS animations we can do that.
css
css/main.css
.bubble { ⋮ border-radius: 50%; background-color: lightblue; animation: bounce .5s cubic-bezier(.5, -.9, .6, 1.9) forwards; transform: translate(-50%, -50%); } @keyframes bounce { 0% { height: 50px; width: 50px; } 100% { height: 100px; width: 100px; } }
num fade
3-4
true
num text
5
Add an `animation` to the bubble that makes a bounce effect. Notice in the keyframes that the bubble is just being scaled from `50px` to `100px`. The bouncing comes from the custom easing: `cubic-bezier()` With the `cubic-bezier()` function we can make any kind of easing we want. I didn’t magically come up with these numbers I used a [cubic bezier generator](http://cubic-bezier.com/). We’re using `forwards` here to keep the bubble at its bigger size when it’s done animating, otherwise it would snap back to the smaller size.
num text
6
The `transform` is here so the bubble scales from the centre, because we’re adjusting the width and height it will naturally scale from the top-left corner, so we’re changing the anchor point. Of course, I could have used `transform: scale()` inside `@keyframes` instead of `width` & `height` to acheive the same results.
With a refresh in your browser, pressing `Space` now should drop a bubble on the screen and it should animate. ![](animate.gif)
title before code_lang code_file code lines
Click to pop
The next piece of code we’re going to write is to make the bubbles “pop” when they are clicked. To start, let’s write some JavaScript that will add a class to the bubble when it’s clicked:
js
js/main.js
⋮ $body.append($bubble); } }); $body.on('click', '.bubble', function () { $(this).addClass('is-popping'); });
num fade
2-4
true
num text
6
We’re using event delegation here: listening for clicks on the `<body>`, but only activating the event handler when a `.bubble` is called upon. We need to use event delegation because we don’t know how many bubbles there are and we don’t want to add an event listener to every single one.
title before code_lang code_file code lines after
Popping CSS
The new `.is-popping` class will change the `width` & `height` to `0`, making the bubble shrink & set the `opacity` to `0` to fade the bubble away. We also need to add a transition to the `.bubble` to create the easing effect.
css
css/main.css
.bubble { ⋮ animation: bounce .5s cubic-bezier(.5, -.9, .6, 1.9) forwards; transform: translate(-50%, -50%); transition: width .3s cubic-bezier(.7, -.6, .4, 1.5), height .3s cubic-bezier(.7, -.6, .4, 1.5), opacity .3s ease-out ; } .is-popping { height: 0; width: 0; opacity: 0; animation-name: none; } @keyframes bounce { 0% { height: 50px; ⋮
num fade
3-4
true
num fade
19-21
true
num text
5-9
The `transition` is written on multiple lines because certain properties are going to have different easing than others—and one line is difficult to read. The 3 different transitions: - The `width` & `height` should have a bouncing effect - The `opactiy` should just `ease-out`
num text
16
It’s very important that we remove the `animation` at this point. Because the `forwards` in the animation forces the element to stay at its largest size after the animation is completed. Without removing the animation from the element we wouldn’t see it shrink.
When clicking on each of the bubbles now they should shrink and fade away. ![](pop.gif)
title before code_lang code_file code lines
Removing the element when completed
Even though the bubble shrinks and fades away there’s still an invisible `<div>` in the HTML. *Let’s use JavaScript to remove the `<div>` from the `<body>` after its animation has finished:*
js
js/main.js
⋮ $(this).addClass('is-popping'); }); $body.on('transitionend', '.bubble', function () { $(this).remove(); });
num fade
2-3
true
num text
5
The code is listening for the `transitionend` event that will be triggered whenever the `.bubble` has finished its shrinking-fading transition.
num text
6
We then target `$(this)`—which represents the single ball that finished—and remove it from the `<body>`