Making a Responsive and Interactive Animation with SVGs in CSS


  1. Setting up Our Animation Project - In this lesson, we'll learn how to setup our projects. Let's start by taking a look at the folder structure. Now I've made a folder and called it underwater fun and in which I've made a web folder which will contain all the assets, the CSS, the JavaScript, the SASS, and the SVG as well as an index file. I'm going to open this up in my favorite code editor which is Sublime Text and here you can see the basic setup of the HTML documents. It's an HTML5 doc type, just an HTML tag, a head tag and body tag, and this one contains a div called scene, which I will use to display all the SVG files and to group them and in the head tag we've got a few meta tags and most importantly the view port one in which I've set the user scalable to no as well as initial scale and maximum scale to 1 to ensure that the user can't use pinch zoom on a tablet device or any kind of touch device. That way I have full control on any scaling and I'm going to really make it responsive using media queries and CSS. I'm also putting width equals device width to make sure that the media queries actually behave the way they're supposed to. A couple of other meta tags I've got are utf-8 for the character sets and X-UA compatible for Internet Explorer, just to ensure that the rendering is optimal on that one. Also an Apple mobile web app capable tag just for iOS. You can find more documentation on that one if you Google it, but that's just to make sure that the view in mobile Safari is just an optimal way of viewing things. And that's for our basic HTML setup. We're also going to need a few external files. I'm actually going to use jQuery to write JavaScript and I'm also going to load something called Modernizr and let's take a look. Modernizr is basically a feature detection library so if you go to the bottom development you're going to see you've got a lot of options here. You can just select which features you want to do a test against and it will display a class on your HTML tag if it either supports or doesn't support a certain feature and it will actually do the same in your JavaScript as well, add a test for those features. I usually go ahead and select everything for CSS 3, but really the most important one we're going to use is CSS Animations. For HTML we don't really have anything that we're going to use. We're going to use touch events as well and the default extra so the html5shiv Modernizr load and add CSS classes. This is the way the detection is going to be added to the HTML tag. Other than that, in the non-core detects I've selected the CSS pointer events and I'm probably not going to need this because I'm going to probably going to include some kind of fallback or some kind of a function to make sure that pointer events work in Explorer, but this is just in case you would like to have some kind of fallback or detection for pointer events and yes, that's about it. You can just click that custom downloads button. If you go to your downloads folder, I've downloaded one already. You're going to see a file with some kind of build number in it. I can just move that one inside your JavaScript folder. As you can see, I've already added a Modernizr folder. I've named it 2.8.3 so that's the version number for the name of the folder and in it I just put the Modernizr name without the actual build number. I find it easier to put the version numbers and things like that in a folder a level higher; that's just the way I like to work and it's safe for jQuery as well. You can go to jQuery-downloads and take the latest version, 2.1.3 for example and then add a folder for that name and put your jQuery folder file in that folder as well. I'm going to go to my file and add my script tag and the source for Modernizr is going to be in the head so that's going to be in JavaScript/Modernizr and then my version number, which is 2.8.3. Modernizr.custom.js and I'm going to copy that line, copy and paste this into the body. Of course, don't forget to close the script tag or you're going to have a bit of trouble there. Yes, script tag here as well. I'm going to put jQuery at this bottom of the body tag. This jQuery and a version number 2.1.3., jQuery my minimized version dot JavaScript and also what I'm going to need is a custom JavaScript file to put my functions in. I'm going to load it after my jQuery function and I'm just going to call that custom.js and as you can see, I've already saved one before. It's just an empty file. The way you can do that is just by doing Command + N. You've got an untitled file and you can just save this into your JavaScript folder as custom.js and that should be it. And let's go back to our folder. So we've got our JavaScript file so our HTML files and this should be everything we need for that. I'm going to double click my index file, which should open my file in the browser. I'm just using Chrome. You can do the same in any kind of browser basically. What we need for this now is the developer tools and we open those by using Command + Click or right mouse button click and then go to inspect elements and this will open up kind of a menu on either on the side or the bottom of the page with your HTML structure in it. You've got your styles here at the bottom tab and as you can see, you've also got some errors showing here some JavaScript errors and if I click here, I'm going to notice that it's not loading my JavaScript files so if I right mouse click this one, we could actually copy that one and open up a new tab. I could post it and just paste it in there and see this file isn't loading so what I probably did then is probably used the wrong name to address one of these files. So that's why these developer tools are very handy. It allows you to track down any errors you have without having to guess what it could be. So in this case, it seems I've forgotten a slash in the name jQuery so I'm going to go back to file and as you can see, jquery, slash, and then I should have my folder number. If I'm going to reload this, you'll see that error is gone and I've got a similar error for Modernizr it would seem. You see, I've made a spelling error here. It should be Modernizr, not mondernizr. Save that one. Refresh and see all my errors are gone. I can show in height this panel by clicking this icon right here and I've got similar kind of tools. For example, let's see. Five Forks Developer edition for example has got similar page, Ctrl + Click, element inspect, and you've got similar tools in there as well. JavaScript is in this little tab here and here you've got your HTML and here you've got your styling. Now if you want to keep using Chrome in the duration of this project, you're going to have to set up your local hosts because if you open a file inside Chrome and inside if all you're going to load assets like SVG using JavaScript as we are going to do in later lessons, it's going to give you security errors. So either you have to set up your local host or Chrome or you can use another browser such as Firefox because that one doesn't give you those errors. Really it's up to you the way you prefer to work, and showing you how to set up the host isn't really inside the scope of these lessons so if you want to do that, you can Google local host Mac, for example or setting up local hosts and you'll find a lot of information about it and if you don't want to go through the hassle you can just use Firefox and yes, that should be it and this is how we set up the project files for our lessons.

  2. Making SVGs Ready for CSS - In this lesson we'll learn how to create SVGs using Adobe Illustrator and optimize them for CSS animations. Let's go into our project folder and in my underwater fun I've also created one called Illustrator Files and this is where I'll be putting all my original files ready to be exported into SVGs. I'm going to open up Adobe Illustrator, Command + N or Ctrl + N if you're on a PC and as a size I've chosen 1024 x 768 and portrait orientation. The reason I'm using this is because it's got an aspect ratio of 4 x 3 and that's about the aspect ratio most commonly used in tablets and smartphones. Now some of them are a little bit wider than that, but that's not really a problem since we're going to make our background repeatable and everything will be scalable anyway. So we could use something smaller or bigger, as long as you have a similar aspect ratio. Go ahead and hit OK. And this is going to give us an artboard of that size and in our layers palette is where we'll be putting all of our SVGs, one on top of the other, separated in layers. Now I went ahead and created one before. Go in Illustrator Files. I made an underwater scene and as you can see, it's got a background color, some waves, a bottom submarine, and the fish. The submarine itself is also separated into sub layers for every element that has to be animated. So there's a propeller that will turn. There's a periscope that will go up and down and there's the body. And the fish, the sub, the bottom, the waves will all be separate SVGs. Now a little note about the waves and the bottom. These elements will have to be repeatable in some way, by which I mean if I select one of these waves for example, I'm going to move this one to the left a little bit. If I make a copy, Command + C, Command + F, and I move them next to each other, you'll see I've made the waves so that the end of one wave aligns perfectly with the start of the next one so every wave element and the same for the bottom is actually a repeatable pattern. So you're going to need to do that in order for the application itself to have a background that can stretch or repeat in the direction to the left and the direction to the right in case you're displaying your application on a screen that's a little bit wider than the 4 x 3 aspect ratio. So keep that in mind when you're creating a background. Now I'm going to into my files. So what I need to do now because I've separated all my SVGs into layers, I want them to be exported into separate SVGs as well, of course, but Illustrator doesn't really allow you to export layers into separate SVG files. So I'm going to go and duplicate this scene four times. That's Command + D four times and I'm going to rename that to the name of every SVG that I want so I'm going to have a submarine. I'm going to have fish and I'm going to have the bottom and waves. Now if I go to submarine and I open that one up for example, I'm going to need to delete every layer that's not a part of this submarine, hit the trashcan and now I've got just my submarine and I'm going to resize my art boards to match this size. So make sure it's maybe a little bit bigger, but certainly not smaller than your elements. It doesn't have to be precise, it just has to fit your SVG into it. So hit Command + S. If you go back, you see the preview is just our submarine and you do that for every separate file except for our scene of course, that's the master file. We leave that one the way it is. And now we need to export those files into an SVG and we're going to go to save as or save a copy and into Illustrator files, I'm first going to make a new folder at the bottom left. You see this new folder button, underscore export is what I'm going to name it and as a format I'm going to choose SVG. Hit save and there's an SVG button at the bottom. The SVG profile, just leave it at 1.1, click that button and you can see it's going to make a text file and open it up and I think in text edit automatically and this is your code for your SVG with a strange name on top, what you can just rename that to, let's say submarine. And the location you can change that one to export. That's the latest folder. You add it, and if you go to the finder, you're going to find that file right there. So I've deleted the extension and I'm going to replace the extension with SVG and it's going to give you a warning. Choose use.svg and this should be your file. You do that for every separate one and you should have a whole list of them right here. Now as a rule, this should be enough for your HTML file to handle, but we want to optimize this SVG a bit. So what I'm going to do is I'm going to go into Chrome and load an SVG optimizer and choose my file, hit enter, upload that file. Oh, I see my link has expired and I'm going to go back and refresh this SVG optimizer again. Hit choose file, submarine SVG upload this again. And now it should work. Yes, here it is. I'm getting a couple of options. My decimal places will need to be 2, for example. That's just the size of our art board is going to round this number a bit. I'm going to convert the styles into CSS. That's the only thing I need to check. Hit optimize file. Download link and in my downloads folder there should be one strangely named file and this is the one. Now this optimize file is what I'm going to be putting into my web application so we'll go to the web and then SVG and drop that one in here. As you can see, I already made one before, but I'm going to delete that one for now. So I've got my strangely named file. I'm going to rename that submarine again and I'm going to add opt for optimized and I'll go into my code editor and as you can see, all the styles have been separated and all the colors and background colors and things like that have been put in the top of my file. Now I'm going to need to change a couple of last things. For one thing, I need to add preserve aspect ratio to the top and that's going to be xMinYMin and meet and a width of 100% as well as a height of 100%. And this will make sure that everything is scalable at a certain, at the proper aspect ratio. One last thing I need to do is I'm going to need to change all the IDs inside this file and replace them by classes. The reason I'm doing this is because if I'm going to need multiple versions of an SVG, for example, multiple fish, I can't have duplicate IDs in the code so I need to change this to classes. I think Command + option F will be find and replace. ID by class, replace all, Command + S to save this and that should be it. So if you do the same for every separate SVG, save them in your web SVG folder, and that way you should have all your files optimized and this is how we optimize our SVGs for use with CSS animations.

  3. Introducing Sass for Better CSS Writing - In this lesson we will learn how to use SASS to optimize our CSS. As you may have noticed, I haven't added an external style sheet yet and the reason for that is because we will be using a pre-processing language in order to produce the CSS and I want to give you a little bit more information before we get started. So let's go to the website of sass-lang.com and in here there's a learn SASS section with all the basics. So what SASS does is it's actually a way of writing CSS that gives you a few more features, but one of the things it's got is you can use variables which is much like the way you would use it in JavaScript. You've got the nesting of all your styles and your properties, which keeps everything a little bit cleaner in your CSS, I find, especially if you want to work modularly. It's also got partials and imports, which we will be using in this lesson so that way you can split up all of your styles into different sections and put that into different files and in the end, everything gets imported and exported back into one CSS file. There are also mixins, there's let's see, operators for making calculations on the fly in your CSS as you work. That's all pretty handy, I find. So if you're not using SASS in current projects, I would highly recommend that you look into it. Now to install it is all pretty straightforward. All the information is on the website itself, so I'm not going to take you through all the steps. I myself am working on a Mac and I've got Ruby preinstalled and then it's pretty easy. It's just the SASS gem that you install on there, just gem install SASS; for Linux and Windows you have to install Ruby first before you get going, but it's really all pretty easy and all the information is on here. So we're going to get started, assuming you've got SASS installed on your computer. We're going to get started by making our main SASS file and I've already added a few partials as well. So I've got a file for putting all my animations. I've got one for helpers, which is variables, mixins, all kind of stuff I can reuse. There are keyframes for all the keyframe functions. Those will be called in my animations later on. I've got a layout CSS for things like the body tag and the containers. I've got my SVG which is where I will be collecting all the styles from SVG files and of course, the main file which will combine everything. So as you will notice, all these partials, all these separate files have got underscores, but the main one doesn't. So the reason for that is is just to tell SASS that these files will be used for an import and it doesn't have to target these specific files. It can just ignore these as separate files. It will only target the one without an underscore and in this one I will be putting import tags. So it's typing import or rather @import and then I'm going to add helpers.scss so that's the extension we will be using and end it with a semicolon and now just copy and paste those a couple of times, one for every file. So there are helpers, there are keyframes, and there's my SVG, my layout, and my animation. So as you'll notice, I didn't put any underscores in here because those only serve that one function, just to tell SASS ignore this file and you could really type it, you could type it if you want. It doesn't really care about the underscores once it's named as an import in a file. Now let's see. So once we've got all that covered, now I'm going to you how to actually start SASS. So you're going to need a terminal window and the way you get there is by going to your finder, your applications, and then your utilities folder and there's a terminal right there. I'm going to do Command + open that one and you're going to tell it sass --watch and another space. Now you need your source folder which is sass. I'm going to just drag and drop this. Remove this space and add a column and after that one I need to add my export folder, which is my CSS folder. Again, drag and drop. I'm going to hit enter and this is just going to write my main CSS file so it takes the name of your file that you're using to import everything. That's going to be the name of your file. So that's the simplest way of using it, basically. So now that I have everything, I'm going to, let's see I'm going to add my style sheet right here in my index folder, or my index file and my head tag. I'm going to add link and auto complete this and css/main.css is going to be the href. Because I'm in HTML5 I don't really need to add a type to my link tag. That's about everything we need, I think. I'm going to go to my SVGs next. So the second functionality we're going to be using is actually the nesting of styles. So in my SVG I'm going to put all my styles for these. Let's see, if I go into submarine for example, you have noticed from the previous lessons, all my styles on my colors are in the top of one document right here. What I'm going to do is I'm going to take the class of my document and then I'm going to be nesting all of these styles into it. Now I just noticed that I added a class sub to my submarine file. Now I'm going to rename this submarine. The only reason I'm doing this is because I think it's probably best in order to keep track of your names and not make any mistakes, to really use the same file name for the class name of your SVG. That way you can never get confused. So for example, if I go in my fish optimize file, this one has a class. This SVG has a class of fish. So it's probably important to do the same for the submarine just as a best practice. Now as I said, just copy this class, go into my SVG SASS file and I'll go and add .submarine and open and close the brackets. I'm going to go back in my submarine, select all my styles. Cut those, remove the style tags. We won't be needing those. Just save and I'm going to paste that right in here and I'm going to save that. So we're nesting all of our styles under this class and if I go into my CSS file here, which should have been generated, let's check the terminal, yes. So it's watching, SASS is watching my folder and every time I save something and one of those SASS files, it doesn't matter which one, it's going to update my main CSS file. So everything gets compiled. I don't really have to check this. I just have to keep it running in its own window. So I'm going to go to my CSS and as you can see, it has compiled all the nested styles and just added everything to its own submarine class. Just the way you would in regular CSS. So you're going to have to do this for every one of those SVGs, all the optimized SVGs will have to get their styles taken out and nested in their own class. Then I'm going to go into Chrome for a moment, into my project, if it loads my page. I'm going to go in my head tag and as you'll notice, I've got my link right here, CSS, open that for a moment. Yes, it's importing everything. Because I haven't loaded any SVGs, I can't really check out if the styles are working, but we're going to be importing those in the next lesson and then you'll see how all the styles work together to give colors and everything to your separate SVGs. And so yes, that's a look at how we use SASS to optimize our CSS.

  4. Setting up the Scene and Importing Our Graphics into HTML - In this lesson we will learn how to import the SVGs into HTML and set up our scene. Now that we've got our main CSS file all set up, what we're going to do is import all the SVGs. One way of doing that will be to just copy and paste the SVG code right into the index.html, but that would pollute the HTML code really quickly so we're going to use a bit of custom JavaScript instead. We're going to write everything in jQuery so I'm going to start by adding document ready function, right, and this is we're going to be calling our function, but first of course I need a few variables on the function itself so I'm going to add a scene. This will be our container. This is a div that we've put in the HTML already and then an array fits in the paths to all our SVGs. So an array is square brackets and this is going to have just a list of strings which are the paths, svg/bottom-opt.svg. So these paths are relative to our assets folder. Copy paste that a couple of times and there's waves. There's the submarine and there's a fish and yes, there are only four of those and I can delete this and save that and then we're going to write the function itself and I'm going to add this name load SVGs and I'm going to start by iterating the SVG array using the each function so each and then SVGs. I'll put this in a function and this is going to give us for every item a key and a value which is the URL. You could write anything you want, I just find those easiest to use as names because they're most descriptive. Basically we're going to extract its URL for every element and then we're going to use the get function on every URL to actually fetch the SVG and load that and that's going to return this data element. So now we're getting, or we're actually creating an element, a data element for every URL and we're going to put that in an object and find the SVG in there and then append it to our scene right there. So that's our function and inside of our document ready is where we'll actually call our function SVGs and just like this, I'm going to go into my scene for a moment, into my file and load this and as you can see, it's loading all my SVGs, one after the other. So this works and what I'm going to do next is I'm going to set up the scene and the boundaries in which all these SVGs will eventually be placed. So I'm going to go into layout for a moment and inside layout I'm going to get my body and my HTML tags ready. HTML and body and set some dimensions and paddings and things like that so everything is going to be padding and margin 0 and a width and the height of 100%. And then overflow hidden because I don't want any scroll bars. So this is going to set the dimensions of a document and the body itself is going to have the background color of the ocean that I set earlier in the illustration so this blue. Select this in Illustrator and copy this color, paste that in there. So yes, the body is going to be blue. Refresh that to see if this is working. It's working and now the scrollbars are gone. I can't scroll to the page because I set the overflow to hidden. So I know what I'm going to do now is now that I've given dimensions to the body, I'm going to give dimensions to the scene itself. So as I said, I designed everything on my ratio of 4 x 3, so that means if I take my scene, I'm going to give this a height of 100% because in landscape mode I want it to be as high as the page and the width will be four-thirds of that height and I'm going to do a bit of calculations. I'm going to use the view height instead of pixels. You could use view heights as a unit and multiply that by four-thirds and save that and there are a few others things that I will need as a position relative because all the SVGs will be positioned in relation to the scene so I need to have some kind of position set up for this as well and then a margin 0 and auto to center the whole thing. I'm going to refresh this a for a moment. In my developer tools on the right I can select my scene element and see how everything changes, how everything scales, by just grabbing a corner, scaling this page and as you can see, when I select this scene, when I just click the element, it's going to highlight it and as you can see, it actually shrinks along with the page, but it always stays in the same aspect ratio so that's exactly what I want for when it's in landscape mode, but when it's in portrait mode, as you will notice right here, it's going to cut everything off. So I'm going to have to change the ratio once I'm square or in a long page and for that reason I'm going to introduce some media queries. I'm going to start by adding at media and my maximum aspect ratio of 4 x 3 so that's going to be everything smaller than my landscape of 4 x 3 and in this case I'm going to copy paste my scene in there. And this I don't need. I think remove this. And now things are going to be reversed. Now the width will be 100% and the height will be 100 times the view width this time and instead of 4 x 3, it's going to be I think 3 x 4 is it? Yes. I'm going to go back into this again, select this and make a longer page and as you can see, everything is scaling along with this as well. Now we're going to fine tune everything in one of the later lessons, but this was a look at how we import our SVGs and do HTML and set up our scene using SASS.

  5. Building the Scene by Placing and Scaling the SVGs - In this lesson we will learn how to position and place the SVGs to build our scene. In the last lesson we saw how we can inject the SVGs right into our HTML. Now the next thing we need to do is scale and position all the elements according to our design. So the way we're going to do that is by first go into our SVG styling block and we're going to add a few general styles so for the SVG I'm going to put a display of block because we need that to make dimensions. Position of absolute, and that's the way we're going to position everything relative to our scene, and then an overflow hidden because we don't want any element to extend outside of the bounding box of the SVG in case there are any loose elements that would extend otherwise. So that's the basis. In my layout I'm going to add all the classes for the elements so the waves first, then on top of that we're going to have our bottom SVG so all the plants and everything. Then we're going to have our submarine and then we're going to have the fish. So everything is positioned in layers sort of on top of each other. As you can see in the Illustrator file, the waves are behind the submarine and the plants are on top these waves so everything will get a zed index. The waves are at the lowest so it's at the index of 0. The bottom on top of that is a 1. Submarine is getting a 2 and then the fish will get a 3 and because they will swim right across the submarine in our end result when we actually make it swim and make everything move. So this is the basis. Then for the dimensions, the waves of course are the full size of our scene so 100% for the width and the height. The bottom itself, those plants, will have a width of 100% and the height will be a special thing that will be calculated based on the pixel size and there's a calculation we'll be using for the submarine and the fish as well, but first before we do that, we need some reference numbers. I'm going to put those in variables and my helpers. I'm going to save my size, my height, and the width of my scene basically, of my art board. So a variable starts with a dollar sign. I'm going to set a scene width of, let's see that's 1024 that I used and then a scene height and that's going to be 768, so that's our basis for our calculations back to the layout. For the height of the bottom element, I'm going to go into the code of my bottom SVG and I've got a view box property here, which has my coordinates and my size so 1024 is the width in pixels, 135 is the height in pixels and that's the number I need. Back in the layout I'm going to put this right between these brackets, 135, divide this, so that's the pixel height of my SVG divided by the scene height. Scene height and then multiply this by 100 and that number will give me a percentage. Now I'm going to add the percent sign after this because if I don't, I will just get a number without a unit and I need the percent unit for this. So this is for the bottom. I'm going to do the same for the submarine and for the fish of course I will change this pixel value, but the similar calculation for the submarine itself and this is a width and scene width of course. Copy that and put this in here. For my submarine I've got 517 and 417.3. For my fish, 131 and 88. So back to my layout and if I remember correctly, so 517 for the submarine and then a 417.3 for the height. The fish was 131 and the height was 88; s those should be our dimensions. If I go back into Chrome and I refresh, everything should be scaled and absolutely positioned. So now the next thing I need to do is set my coordinates. So the waves are already right. Those are to the top and to the left, but I'm going to set them explicitly just to be sure. The top and the left of 0. That's for the waves, actually. And for the bottom, that's almost the same. The bottom is going to be a bottom of 0 instead of a top. Now in the submarine we'll have a left of 0 because it's set all the way to the left and the height is I think about a fifth or a fourth maybe so let's say maybe 24%. It doesn't have to be exactly the same thing. Just somewhere, yes, close to it. And then for the fish, a left of maybe 70% and I think if I go in Illustrator it's a little bit below the top so the top of 50%. So I'm just making some guess work. It's just some eyeballing. It doesn't have to be really, really pixel precise because these elements will be moving anyway so I just need a starting point that's somewhere in the middle. So that's about it, I think. So yes, it looks about the same. Now if I start scaling this, you'll notice that my scene is actually aligned to the top, which means that my background color on my body tag, this blue is actually extending behind my bottom or basically behind the ocean bottom that I created. So I'm going to make a little tweak to these colors. So when I'm in this media query, so smaller than my four-thirds ratio, I'm actually going to change the background color. So the body background color will have this green so that way everything behind the scene will extend into this color and then the scene itself will be this ocean blue. So I'm going to go into my scene. Yes, the background color and this background color is this blue that I put on the body tag earlier. So this is inside this media query that I made in the previous lesson. Now for my body tag I'm going to add a background color as well, but this one is going to be green. So in Illustrator I'm selecting my bottom elements, double clicking the color on the left, and copying that value, paste it in here. Save, go back to Chrome, and it's extending. Now you might notice there's a little white line right here at the bottom, just at the place at the divider between, actually the scene and the rest of the body. So the reason for that is because we're actually using percentages for scaling and positioning and things like that and that means when we're resizing the window, everything is getting recalculated by the browser and aligned on a pixel. So if a percentage falls between two pixels, the browser is going to round this to the nearest pixel and that means sometimes we're going to get a pixel line and one way of countering that is by moving the bottom a little bit down so it overlaps with this background color. So I'm going to give that bottom a -1 pixel and that should fix things. Yes, no more line right there. So if I scale this, if it's longer, it's aligned with the bottom and if it's like this, it's actually the bottom color that's extended right there. And so yes, this is a look at how we position and place the SVGs to build our scene.

  6. Animating Our Background - In this lesson we will learn how to write keyframe animations to make a repeatable moving background. So in the previous lessons we learned how to make and append SVGs and scale and position them according to the design, but what we're missing now is a repeat element to the left and to the right. This is what it will become eventually, but if I refresh for a moment, this is what we have now. So we've got this gap to the left and to the right when we start scaling this scene. So I'm going to need multiple SVGs to position a bit more a few to the left and to the right to repeat everything. The way I'm going to do that is by changing my JavaScript functions a bit. I'm going to replace this array with the square brackets by a key value pair array. So curly brackets to start with and every URL will have a separator next to it a colon, and then the number of times I want it turned into as a string as well. So I'm going to use this for my array and then I'm going to have to change my function a bit. Instead of key and URL I've got URL and something I'm going to call this total, total number of times I want it. So 5 for the bottom, 5 for the waves, 1 submarine and 1 fish for the moment and then instead of just making SVG and appending this, I'm going to get my SVG and save it in a variable. So find my SVG in my data, get the first one, and then get the SVG class because I'm going to manipulate that as well and then I'm going to add a new loop. So I'm going to loop through this total number of times. I start at 0 and as long as it's smaller than total, it keeps iterating and then I'm going to add some classes before I append everything. So it's going to look a little bit like this. SVG attribute class is the original class, plus a gap and then the class with an number appended to it and the number is i+1 because i starts at 0, but I want my classes to start at 1 so that's the way it looks and then I'm going to clone it and the reason is if I don't clone it, it's going to overwrite my SVG every time it loops so I need to clone and then append to my scene, just as previous and this is going to be how we append all the SVGs. Then we need to position them accordingly. So if I check out this bottom class and the SVG class, I've already nested my numbered classes so waves-1 and 2 and 3 and 4. There's 5 in total, but 1 is the original position and the four other ones will be a few to the left as you can see. -200, -100, and a positive 100 and +200%. Same for the bottom and then I added a bit of margin to create an overlap. So I'm going to push them by 1 or 2 pixels over each other and if I go back to the browser, refresh this, you can see it extends. Now as you can see, I still have to tweak these margins, the pulling of it because it's a little bit jagged so depending on your design, you're going to need one or two of those pixels to overlap. That's something we can tweak later on. So now that I've got my background, I wanted to animate. So what I'm going to do is write keyframes. So the keyframes define what's going to happen at the start and what's going to happen, well actually what's going to happen between the start and the end of an animation. So these keyframes only have actually two frames, the start and the end. So 0% and 100%. If you've got more, 4 for example, you would have 0, 25, 50, and 100%. So it's always 100% divided by the number of frames you need. So what I'm going to do is use transform to manipulate the position. I'm going to use translate3d. It's got three coordinates, but I only needed the x coordinates. The reason I'm using this and not translate2d or top or some left position is because this trick is hardware acceleration in your web kit browsers so that makes everything a little bit smoother. So that's one reason I would be using this. I'm going from 0% to -100% so from the right to the left and everything else that remains 0 that doesn't change, I'm not giving it a unit because sometimes that gives strange results in Chrome so no units if there's no position transforming and it's a 0. Then I'm going to call this on a class, namely my waves classes so all five of them have this same class and the bottom as well. It will have an animation that calls the name of those keyframes so bgMove, the timing 30 seconds, linear is the easing. There's no easing so we call it linear, no speeding up, no slowing down and it's going to be looping an infinite number of times. You could put a number there if you wanted to move or animate a limited number of times. This is our basis and then we're going to have to use some prefixes because if we save this, this is moving. That's because web kit browser like Chrome needs a prefix still. So in my helpers I've created a mixin. A mixin is something like a function you would have in JavaScript and in SASS you have something called a mixin. I've called this one vendorize and I passed some variables to it, property and value and it outputs that property and value and I can append something to it or prefix something and I've chosen to use the vendor prefixes to attach this to it and if I just call that, I can or I don't have to manually add everything. We can also see there's three dots after this variable. That's something special that allows you to use commas and certain special characters inside a variable. We don't need this now, but we'll need this later on. So I'm going to change all these things, animation, etc., and the way I'm doing this is by wrapping it in an @includes and then the name of mixin, vendorize, and then put everything between these brackets and I need a comma instead of a colon to separate these things that will be wrapped in variables and yes, the same thing for the one below. And we need the same inside the keyframes. So include vendorize and then transform. Oh, let's do that again. Transform and this translate thing will go in there and actually that can go and same line below, but -100%, yes. And the last thing we need to do is the keyframes itself. This line itself will also need to be prefixed and I've made another kind of mixin for that that's a little bit bigger. So instead of one line with property and value, it's a little bit bigger. It's separated on multiple lines, as you can see there, a mixin called keyframes with the name and inside it will just output our content from our keyframes and wrap it in these keyframes lines with the name as coming from the variable and this prefix right here. It looks a bit complex, but if you just copy paste what I'm doing, it should work really well. So it always looks the same. Always this @includes, but instead of @keyframes it will be @includes and then keyframes and the name in brackets like this. This should be everything. If I go into it right now, as you can see, everything is moving and one last remark I can add. I've got my SVGs themselves. My SVG in the groups and so as SVG I'm going to add transform style preserve 3d and backspace visibility hidden and that's to fix a few things. So hardware acceleration in case I'm animating something that's not translate3d and this backspace visibility prevents uncertain flickering and blinking and then let's see if I've forgotten something. Oh, yes. I've actually wrapped my animations, my classes inside something called CSS animations and that's a class that's added to the HTML tag by Modernizr. If you recall that, it's the library we use to detect if a browser supports certain things. So our browser supports CSS animations so it will have a CSS animations class attached to the HTML. So if it doesn't have that class, it won't try to execute this and nothing will happen. Well, nothing will happen anyway, but that's just to be sure that this CSS isn't loaded and try to execute by the browser. So yes, this is how we write keyframe animations using SASS and create a repeatable moving background.

  7. Animating the Submarine - In this lesson we will learn how to combine animations in order to make a submarine move. So now that we've got our moving background, we'll also want to manipulate the foreground. I want this submarine to go up and down slightly following the waves and I want this propeller to rotate so that it gives the illusion of giving the submarine movement. So I'm going to back into my code and I'm going to add another keyframe animation so I can just copy paste the setup and give it another name. I'm going to move this bob because it's bobbing up and down. I'm going to change the coordinates so instead of an x coordinate, it's going to be the y coordinate, so the second one and I'm going to need five of these and why? Because I'm actually going to make this move in two directions and back to the center so it's going to start at the center and then it's going to go 25%, to 50, 75%, and 100. So percentage is just a division of the number of keyframes that we need. So from 0 to -5 position, then back to 0, then to +5, then back to 0. This is going to give us a sign wave and it's going to go like this, up and down and up and down and infinitely repeated. So in our animations SASS file I'm going to add the same thing as I did for the background so submarine and then vendorize our animation and call our bobbing animation and the timing is going to be 4 seconds which is a bit faster than the background itself and I'm going to refresh this. That looks about right. So timing is something you're going to have to tweak. You're going to have to feel it out a little bit. So I've done this a couple of times before so I've got a pretty good idea of how fast or how slow I want this to go. And now that I've got this element, I've also got to take care of a small bug for Explorer and that is if you start a keyframe at a certain position, that is 0 for example, I make it end at the same position, you'll sometimes get a glitch. So in order to avoid getting a glitch, I'm actually going to add a few decimal points to the 0. So it's a number small enough that you won't notice any animation, that it's not the original starting position, but it makes it different from 0, which makes Explorer actually use that keyframe instead of ignoring it. So that should be it and the other thing I want is to make this element rotate the propeller and for that reason we're going to make another keyframe animation so I'm copying my setup. I'm going to call this spin and it's going to be rotate instead of transform from 0 degrees. So your unit this time is in degrees, to 360, which is a complete revolvement and from 0 to 100 so only 2 keyframes and in my submarine I'm going to nest this. My propeller is actually a group inside my SVG. If you'll recall, we made our submarine, we split it into sub layers. If you go back to Illustrator, open your palette, you've got three sub layers and those will be named groups as well inside the SVG. If I go inside the SVG, when we export it, they were IDs and we renamed them to classes. So this is the thing. Now we would expect that this would just rotate in a normal way. Unfortunately we're going to have some issues with that as I'm going to show you. So if I add my propeller, vendorize animation, then we'll call it spin, and a bit faster than submarine movement so 2 seconds and again infinite. As you can see, it's rotating very strangely. It's actually taking the top left corner as a coordinate. Now we've got two solutions to fix this. Either we give it a coordinate using transform origin in the CSS, unfortunately that doesn't work in Firefox. That just ignores coordinates. It will always take the top left. So that leaves us with one other solution and that's actually hard coding the coordinates right into our SVG. Unfortunately, in order to do that, we have to change this layout slightly. So these stacks. So instead of having a group called propeller, we're actually going to have to nest two SVGs with the coordinates of our propeller and it's a bit weird and a bit counterintuitive to do it this way, but it's the best solution I've found to fix this. So I'm going to indent this a couple of times and I'm going to quickly copy paste this from my notes so you can quickly see what's going to change. So instead of this one group we've got this, an SVG, a group, SVG, and another group. So I'm going to undo this for a moment and add a little more indentation. So this becomes very clear. So instead of this group class propeller, I've added an SVG around it and I've moved the class right to this and then we've got a group and then another SVG and then another group. So one group was replaced by two groups and two SVGs. I'm going to close that at the bottom so I don't forget to do this so I don't get any mistakes. Let's see. This should be right here and this should be right here and save. The first SVG has my as positive coordinates as you will see, and the second SVG will have the same coordinates, but negative. Again, it looks very illogical, but it's actually a way of pushing down the propeller and then pulling it back up and by doing so, you're actually moving the center point or the top left point to the center and to know the coordinates of your element, you can actually go inside your layers of your element, your complete submarine and you just click your propeller that's nested, open your transform panel right here and look for the middle coordinates, the x and the y, and that's the numbers you want to use. So that's 78 something and 257 something. Going back here, positive on the first and negative on the second one. And then what we're going to do instead of, of course, rotating this propeller, what we're going to do is we'll target the propeller group or better yet the propeller SVG and then the first group that's in there. So that's propeller and then the bigger than sign and then the g, that's targeting the first group inside our nested SVG and this is where we give the spin to. I'm going to go back and refresh. As you can see, it's rotating, but as piece is cut off and that's because I set overflow hidden before on SVG so I'm going to make an exception. Inside my submarine I'm going to add an ampersand. That means repetition of the submarine class. Add SVG after that and give that an overflow visible. Go back, refresh, and that should rotate it. Now one last remark on this. This will now work in most modern browsers including this rotation, except for Explorer 10 and 11, I believe. They have problems with manipulating or animating nested groups and nested SVGs inside another SVG. There is not really a pure CSS solution to do that, to fix that. So if you want an animation like this, if you really need this to work in Explorer, you're going to have to pull the propeller out and make it its own SVG so like we have the fish and the submarine and the bottom and the background, you will need to make this its own file and export this as an SVG from Illustrator, optimize that, follow all the rules with it for the separate SVGs and then you can position and animate it. Now I'm not going to do this because this animation in my eyes is not really essential to the animation as a whole. The most important things I think is that the ocean moves, that the submarine moves a bit and later we'll have the fish move as well. So this propeller is a nice extra, but again, if you want to make this move, you could do that by separating the SVG. Another element we still have is this periscope right here. If you want to make this one move, for example, you could do that as well. One thing you could do for example is write a keyframe animation to move this along the y axis to move this up and down again and for example, trigger it on the submarine hover. That's something I'm going to let you decide if you want to do this. We've seen how we can build animations and keyframes so that's something you could test out if you want to. So this is how we combine animations to make our submarine move.

  8. Making a School of Fish - In this lesson we'll learn how to turn one fish into a whole school and randomize the appearance. So now we've got our submarine moving right here. We'll also want to make some swimming fish. The way I'm going to do that is by multiplying these SVGs and wrapping them in a new container. So back in my index.html I added a difficult school inside my scene. This will be my new wrapper and I'm going to add that div as a variable into my JavaScript as well and then I'm going to need 10 fish so add a 10 to my SVGs and in my load SVGs I'm going to differentiate between the different SVGs that I need. I'm going to use an if-else for that one. So if my SVG class, which I saved right here equals fish, I'm going to use this line and I'm going to append to my school div instead of this scene and for my else statement it will just be the original one that just appends to this scene and this is how we multiply those and then in my layout I'm going to add some styling for my school and I'm just going to copy paste the bit I used for the background elements. This is going to be about the same size. So I copied the ones from waves because I want this index is going to be 10 overlay everything, the top and the left of 0 and a width and a height of 100% to fill the scene basically, but I want my fish to be slightly off-screen when they start so my left is going to be 100%. And then for my fish I'm going to be randomizing their position a little bit using a for loop, much like in JavaScript, you can use that in SASS as well and it's going to just iterate through a list of numbers from 1 to 10. So at 4 and then a variable i, from 1 through 10. So for numbers from 1 to 10 I'm going to generate a fish class with that number. So you'll recall when I'm creating SVGs, I'm actually attaching a number to those classes via JavaScript. So I can use that in my SASS as well. So looping through 1 to 10, my fish with a class for fish with a number from 1 through 10 and then I'm going to add a top and a left and I'm going to start with 0% and add a random number. So starting with SASS 3.4 maybe or 3 point something you've got a random number generator and that's random like this and your maximum number goes right in there. So my top is between 0 and 90 and then for the left I'm going to use 200 so twice the width of my scene and then I'm going to save a random number into a variable, random from 0 to 5 and this is what I'm going to use to scale my size. So I can never move my original top and left because I've got some randomly generated ones. My width and my height I'm going to turn those into variables by adding a dollar sign and I'm going to be multiplying those by my random number. So my new width will be width multiplied by my random and same for the height. Now this will create a fish that's kind of big, five times as big as my original one, the biggest one, and I actually want to inverse that. I want to make smaller fish because this is already too big so what I'm going to do is I'm going to cheat a little bit and I'm going to make my original sizes a bit smaller. So five times smaller for example. So I've replaced my 100% by 20. So that way my original is five times smaller and then I've got my random from 0 to 5 so that will make for a good size I think. Save that. And let's see if I can, yes. So we can see different sizes and different positions if I refresh. What am I going to do next? Oh yes, my school, I have to position that one absolutely so that way it will be off-camera. Yes, it's gone. So what we need to do now is we're going to have some random callers and this is pretty special. The same deal we've got with the for loop for the fish and the layout, we're going to do the same in my SVGs SASS file. For the fish we've got different styles for different fill colors. What I did now is I created now a for loop addressing all the fish and then addressing all the classes with colors. Now what I did then is replaced my fill color notation by a new kind of color notation. So instead of hexadecimal, which I'm using right here, I first converted it to HSL; so there's a site for that, rgb to. If you paste in a color value, convert to the hex color, it will give you that color and all kinds of different color models and HSL is a really good one because the first number in HSL defines the color and the two other ones are for the saturation and the lightness. So if we assign a random number for the first number, we'll actually be generating random callers so I've made a random number here from 0 to 359 because there are 360 different options including the 0. So let's go from 0 to 359 and I've actually copy pasted each and every one of those colors in here and converted it to HSL. So all the colors are filled in with HSL. The first number is replaced by that random color and if I save that, and go back and replace, I'm going to write and scale that and see if you see some fish right here. There's a blue one, there's a red one. It's going to be all kind of different colors right there. So the last thing we want to do is make some animation. I'm going to copy paste my background animation. I renamed that and it's going to be fish move instead of bg move and I'm going to move it 300% instead of 100% and in my animation I actually already saved that one. On school, add in my animation fish move for 15 seconds is the time it's going to take and it's going to be infinite so it's going to loop and repeat all the time. So refresh and as you can see, the fish are slowly coming across and swimming right over the submarine. So this is how we turn one fish into a whole school of fish and randomize their look and appearance.

  9. Interacting with the Fish - In this lesson we will learn how to add touch and click interaction. Now that we have our fish and they're all moving and positioned, we want to add a bit of interaction to those fish so what I'm going to do is add pointer events first. What it does is pointer events none enables you to click through an element, for example, this school down to anything that's below that. So for example, we have this school of fish that's swimming across our submarine and we want to add some interaction with the submarine itself or if you want to do that with the background, we're going to be able to click through it if we add pointer events none and then for any children we still want interaction with inside that div, that school, we have to add pointer events all. Now I don't have any interaction planned with the background, but if you want to add some of that functionality, you'll have to add this. Now that doesn't work in Internet Explorer or there are fallbacks for that. There's a polyfill for it and I'll address that issue in one of the later videos when I'll be talking about browser fallbacks and those kinds of scenarios. So now that we have that, I'm going to be adding a bit of animation. So on my fish inside my school I'm going to add a hover and an active. So for the hover I want the fish color to change and pulsate from one to the other. I'm going to address the style 0 on hover because that's the main body of my fish and on active, what this does, this is the event that's fired when you're pressing down, either on a mouse or when you're touching on a touch screen and this is where we'll be catching the fish. So we'll make the fish animate so that it grows and the opacity changes to 0 so it fades out and that gives an effect that it's coming more or less towards you or disappearing. So now that we have that, I'm going to add some keyframe animations, a fish hover and a fish active and I'm going to add some of these right in here. My fish hover is going to go from 0 to 50 to 100 because I wanted to go to one color and back again and this one is just going to need two. So I'm going to start the fish hover by changing the fill color and I'm going to have to go into my SVG file and look for my fish style 0 and I used to have this fill color before we changed it to HSL in our extended functionality in the previous lesson, but I'm going to start with my original yellow and let's see, did I correctly copy that? I don't think I did. Like this and alright. So start and end on a yellow and for the middle one, maybe some kind of reddish or an orange-y color. So you can just go inside Illustrator or any kind of color picker and change that color. So this is going to be from yellow to orange to yellow and then on my active, I'm going to change the scaling and I'm going to start with my original first size that I had, which was 131 and 88 calculated to percentages. I was using scene width if I remember. So yes, you can just copy paste that from your layout file and change that around a little bit. I'm going to scale that by 4 and then so actually my original size will be my first size and the scaled one will be on my final keyframe and then the opacity, I'm going to change that from 1 to 0 and I'm going to go see my animations and trigger those and I'll have a fish hover that's going to take slightly more than a second maybe. That's a good one and then the fish active, which will be very fast because, so 100 milliseconds or 0.1 or just 0.1 seconds, because a touch or click event doesn't take very long. You don't have a lot of time to make an animation and I'm going to add the easing, ease out and it's not going to be infinite. It's just going to play once and stay stuck on the final frame. For that I use forwards and I'm going to refresh. You can see it pulsating on the hover and if I click one, it scales up. Now the opacity, I haven't set it to 0 yet, but what happens if it scales, it's going from the top left corner which pulls it back a bit to the right and to the bottom. I'm going to compensate by adding a transform and I'm going to go, let's see, transform and translate and as soon as it's pulling to the bottom and the right, I'm going to pull back to the left by half the size. So if I you scale it by full, you have to pull it back by half in order to achieve pretty much the center point of your element or just about. So yes, as you can see, if I click it, this appears. Of course, if I let go again, it just goes back to its original position because that's the end of my event and in order to keep that from happening, to make it disappear completely, I'm going to add some JavaScript. When my SVG classes are generated, when my fish are being injected or appended to my school, I'm going to add an if statement. If i is total minus 1, that means if I'm at the last fish being generated, I'm going to add a function catch fish. So then this is where I will be handling all the events. So on my catch fish function, function catch fish, and then what I'm going to do in there is handle everything that has to do with touch and click. So I'm going to start by saving my fish and a variable called fish and then I'm adding a touch start event and a click event as well, but I'm going to use mouse down. That's the cleanest way of doing things because click sometimes gives missed some errors on touch devices when I'm running this function and mouse down seems to be doing a bit better. So on touch, mouse down is also triggered or click events are also triggered and in order to separate those two from each other, I'm actually going to register if we own a touch device or not. I'm going to add a variable touch is false at first at the top and when on a touch device, I'm going set that touch to true and this one I'm go use as a statement in mouse down, to only run if touch is false. Like this. And then I'm going to add prevent defaults and that's usually a good practice. Let's see, like this and to prevent any bubbling or things like that. Now what else am I going to do? I'm going to need to save my fish that I just clicked. I'm going to use a different name for that. So that's my fish and same in the mouse down and then I'm going to trigger or call a new function, a fish handler in which I will do everything to make the fish disappear, fish handler like such and just add the fish to it and the same in here. That way I won't have to write that again and now my function, let's see fish handler and add my fish to it. Now what I'm going to do next is I'm going to add a slight delay so I'm going to add a set timeout, the reason being of course that I'm animating using 100 milliseconds and so I can't really use anything other than set time out. If I want to add a delay, that's the cleanest way of doing it, and I'm going to add my fish and then remove. I'm going to go back into browser and refresh and if I click and let go, it's gone. So this is how we add our click and the touch interaction to our fish.

  10. Turning Our Animation into a Touch-based Game - In this lesson we'll learn how to turn our animation into a click and touch game. So now we've got our fish animated and we can just click to catch them. I'm going to turn this into a complete game by adding a bit more JavaScript and some instructions and messages. So I'm going to start by the instructions so I'm going to add a div class instructions and visible. Now the reason for that class is because I'm going to be setting all the messages to opacity 0 for starters and now I'm going to toggle the visibility with the JavaScript by adding and removing some visible classes. So at the start, the instructions are going to be visible. I'm going to ask to click or touch the fish. Then I'm going to need to add a message while I'm playing, which will count down the number of fish that are left and count up the number of fish that you've got caught, so that's why I've got this div class count up for my line and a count down for the other line and there's going to be an element, just an empty element, an opening and closing tag with a class up and one with a class down and those will have the number of fish injected into them with JavaScript. So that's my playing div, my playing message, and then a message when everything is done to congratulate me because I've caught all the fish and then an extra line with again an element with a class down that's empty. Again, this tag which will show the number of seconds in which I've caught all the fish. So those are the two messages and then I'm going to need a little bit of styling for those messages. I'm going to be putting them at the top and the bottom of my screen and for that I'm going to have some properties that they share. There's going to be an opacity of 0 and then if I add a class visible, opacity will be 1, so that's here at the bottom. Then I'm going to add pointer events none, because I want to be able to click through my div because I'm going to be putting those messages on top of everything and if a fish touches it or swims underneath it, I want to be able to click through it, so that's why you point your events none are declared right here. They're going to be positioned absolutely and then the rest is a bit of styling you can choose what you want to do with that. I added a bit of padding. I've got some font size and Arial fonts, some border radius and one that's a bit important, this box sizing border box is one I use regularly. That enables you to put a width or a height on any elements and not have to bother with including the padding and your width calculations. So you could put as much padding as you want on it. It won't affect the width of the height that you have put on it if you were to explicitly set something. That's very handy when you're making grids, for example. So let's see what else do I need? I'm going to need to position the instructions and the message separately. My instructions will be at the top right 5%, a bit more styling for that in the background color and then my messages will be also at the right, but I want those at the bottom. So right here the bottom and the right and also a bit of coloring and then I've got my done message when everything is finished. I'm going to give that a red background color and a big border, that way it should really jump up at you and it's more visible until that message changes. So this is for my styling and the little bit maybe in the media queries because if I refresh that, this is my message. If I start scaling, you can see this takes a lot of space on my screen and I've got a lot of space here as well, which I'm going to use for putting my messages on and the way I'm going to do that is by changing my CSS in my media queries, but I'm also going to add a new media query to it. So let's see. What else do I need? I'm going to have my maximum aspects ratio of 4 x 3, that's when everything is getting white. I'm also going to be using one that's 3 on 4, that's when everything is going to get longer so when I'm on an iPhone for example like this. So what I'm going to do is I'm going to add some styling for the messages. I'm going to be pulling those messages down a bit and changing the font size on different media queries, so if it's white or when it's long screen, this is going to get pulled on a bit to that message. And this looks a bit smaller as well. So I'm going to, yes, I'm going to put this like for a moment. Now I'm going to go into my JavaScript and I'm going to be adding a whole lot of different elements to keep track of counts of fish and my messages so I'm going to add fireballs. There's going to be my instructions, there's going to be my playing message, that's going to be my done message, a count, if we count all the fish and the total number of fish. Now this total number of fish, I can already fill that in. When I'm loading all my fish SVGs right here, we can actually save that total number of SVGs that I have here. I'm going through that each and it's got to be saved in that total fish global variable so I can reuse that later on. In my fish handler when I click a fish, this is where I'll be adding my count so let's see. I've got a count plus 1. As soon as a click a fish, the count is going to increase by 1 and the first time I've increased it, the first click I'm going to save a date object and that's in order to keep track of the number of seconds it takes me to catch all the fish. And then the if/else statement. So this is all going before I remove the fish of course. I'm going to be keeping track of my messages in my playing and I'm going to find that up and down elements, those empty tags, I'm going to inject into the count via text into it. So a count in that top line and total fish minus count is the number of fish I will have left. I'm going to save that for a moment and I'm going to hide my instructions and show my message while I'm playing. So I'm going to look if my instructions has a class visible, I'm going to remove that and if my playing message doesn't have that class, that's why we have an exclamation mark right here. That means negative so if it doesn't have class, it will add a class visible. So we're going to refresh that for a moment. So now if I click a fish, this disappears and I've got something to keep track of my numbers. Now if I click, that number is going to change, but it doesn't really catch your eye. I want this do something every time I click a fish so that you can really see that something is happening. So I'm going to make that thing shake by adding a class to it and then make some keyframe animation. So playing I'm going to add a class and then I'm going to remove that by using some set time out, much like I did for removing the fish on the previous lesson. So set timeout again with a function in which I've got this remove class and a time of half a second should be plenty of time and then I'm going to add something when everything is done, when everything is over and I've caught all the fish, that's my else statement. I'm going to again log the time so in my var called expanded for expanded time, I'm going to subtract my old time and my start from a new date element that gives me milliseconds so divide that number by 1000 and you've got seconds. Now what I'm going to do next is I'm going to inject that in my down element so again, remember we have an empty tag with a class down and our done message and in that via the use of the property text or the attribute text here, you can actually inject math round and then extend it of expended. I'm using math around because I don't want to have any decimals in there so that's why I'm using that. So keep track of your brackets; there's a couple of brackets there. Make sure that's closed correctly, and then I'm going to hide my previous messages and show my final message. So this should be it, I think. So I'm keeping the score. I'm showing and hiding some instructions and some messages and displaying what I want. Let's try this for a moment. So every time we click, that happens. Now we still have to make our keyframe animation for making that message shake. I'm going to add a shake right here and I'm going to need a few keyframes, about five I think, and I'm going to be making that 0 to 25, 50, 75, and 100. It's an uneven number because I'm going to get back to 0. So we'll start at 0, go to -10 degrees, 0, 10 plus 10, then back to 0. So I'm rotating this to the left and to the right. That's one shake movement and I'm going to be playing that a limited number of times in order to make it shake like maybe three times or something. So I'm going to add a shake class, include my animation, shake, point to seconds will go pretty fast and linear so no easing, and then three times instead of infinites. Then let's see. I'll click and as you can see, it's moving and when you click all the fish you should be able to get a message. So yes, that gives me that red message so this is how we turn our animation into a touch and click-based game.

  11. Dealing with Partial and Nonexistent Browser Support - In this lesson we'll learn how to provide a fallback and fixes for non-supporting browsers. When working with CSS animations and SVGs, you'll notice not everything works the way you want it to across all devices and browsers. Now what we can do for that is provide some kind of fallbacks or fixes based on feature detection and the way we use that is by addressing our Modernizr which we loaded in one of the earliest lessons. What this does is it provides some classes on the HTML tag and also so tags in the JavaScript itself. I'm going to start now by just adding a message here and this is in case there's no support at all. So that's why I called it no support and what I'll do there is I point the user towards a browser that does support these kinds of animations and you also want to provide a few links of course towards Chrome and Firefox or even the latest version of Internet Explorer. Explorer 11 should provide enough support for those kinds of animations. So now that we have that div, I'm also going to add a bit of styling for that. In our animation SASS file we already used the CSS animation class to add our triggers towards our keyframe animations. What I'm going to do now is I made a no-cssanimations class for all the other browsers and in there I've added a bit of styling for that no-support message. So it's just going to be positioned absolutely on top of everything, then add a bit of styling, a bit of some dimensions. Also, the scene itself, I'm going to add a bit of opacity. It's now at 25% and if I put my nested or my class, top class in the comments, you'll notice, you'll see how this looks. Everything is set a bit in the background and the message comes through quite clearly. Now of course this will be a static image because no animations are supported in these older browsers, but that gives them an idea, the end user, of what it could like and maybe they will be motivated to try it in a different browser. So that's how we start this. Now we'll also want to detect for certain features that maybe we could provide some kind of fix for. One of those features is the pointer events property in the CSS that we used on the fish or on the fish container and the way we can use that is there are JavaScript solutions that provide the missing functionality for that. For example, we've got our pointer events polyfill here. I'm going to provide you with a link in the docs for that one and as you can see, I've already downloaded it. What this does is it works with jQuery and then you just initialize it and you can give it a few options. For example, use polyfill f and there you can add a Modernizr feature detection specifically for that feature. For example, because the standard is just detection for Internet Explorer and really if we can detect features, you should use the features instead of detecting a device or a browser. So the way you use it, I've already linked this right here. Just link it after your jQuery and then in your custom JavaScript you can actually just initialize that before initializing anything else in your document ready there on top and that should provide you with that functionality. Now sometimes you can't really rely on that because certain features are implemented, they're just not supported all that well. One of those examples is the view port height and view port width, which we used in our layout for our scene. As you can see, we had a certain height and the width was based on that vh unit and yes, if we can't really rely on the detection, on the feature detection, we're going to have to rely on the device detection instead. So if I go here to caniuse.com, I can actually as I did here, I typed in just view port units and then it gave me this handy table showing all the supports and the light green ones that are partially supported. Unfortunately, as you can see, I was 7.1 as one of those and there's also a little bit of explanation. So for Explorer we don't have to worry. The way we're using it, it should actually work the way we want it to. If we go to the notes for 7.1 the iOS, it's a little bit differently, it's a bit buggy. So what we can do then is provide our own missing functionality and file function and we'll have to use device detection instead of the feature detection and the way I'm going to do this is I'm just going to write a new function for that. I'm going to put that above all other functions and call that fix view port for example. Now what I'm going to do is I'm going to add my scene width. So if I remove this for a moment, I'm setting my scene width and in between the brackets I'm adding scene height multiplied by my ratio of 4 on 3. So that sets our sizing. I also want to do that in a window resize event so when I'm turning the device and it resizes from portrait to landscape or the other way around, it recalculates everything. So this would be the calculations, but of course I will also have to add the detection itself and we can use navigator user agent to do that. So it looks a bit like this. I'm going to close that so that's actually navigator using agent and if we use .match and in between brackets we can just put in our, well, actually between the brackets we have to put an expression that contains the devices and the iOS that we want to use. So in this case it's, yes this runs on iPad, iPhone and etc., and it's OS 7 here that we're using. And that should actually fix it the way we want it. So that's it for feature detection and for providing fallbacks and fixes for our browsers. Now sometimes you're going to have to think about if you really need to provide alternative content or any kind of fix because in all projects, if it takes a lot of time, it also costs a lot of money so it's important to discuss things which your client or to really think about what you want something to do. One example for this is for example, if I go back to my submarine here. We have the rotating propeller here, which I fixed for Firefox. Now that took extra time and a lot of searching on StackOverflow for example, to find a decent solution for that, but that also costs a lot of time. Now I fixed that for Firefox because we're expected that things work in Firefox. It's a modern browser and things like animation should really do what you want. Now unfortunately, there was a missing feature that I couldn't detect with feature detection and I didn't have a really simple JavaScript solution for that, so I had to look a bit and eventually found something. Now this is something that still doesn't work in Internet Explorer. Nested SVGs inside another SVG or nested groups, you cannot really animate that the way you want it to inside the Explorer 10, I believe, and maybe that's fixed in 11. I haven't really looked into that last bit yet, but there is the problem you have to face is it won't always work and it costs a lot of time and money sometimes to fix it. So really you have to think, is it worth it and in my case I don't consider this to be an essential part of the animation so I chose not to fix this for Internet Explorer because the most important part is that the fix move and you can actually click and catch those elements. That's really the most important part and it's really the biggest decision you have to make when working on such a program really. So yes, this is how we provide our fixes and fallbacks for our non-supporting browsers. I had a great time making this course and I hope you found it helpful and that it inspires you to explore animation as part of your projects. We covered CSS animations and SVG and a little bit of JavaScript, but those are just some of the possible building blocks and we only scratched the surface of user interaction really. There's a lot more possible there as well. So I think as long as you don't overuse it, animation can be a wonderful tool for you to tell a story or capture attention or simply add a bit of life to your site or application. It's definitely something I would like to see more of in the post flash days and I hope the same for you as well.