Jeremy Troy Suchanski
Web Frontend Development II
Gary James
May 10, 2022
L07 Readings Notes
Ch11: Further Functions (Notes)
The Properties and Methods of All JavaScript
Functions
- functions: are first-class objects, which
means they can have properties and methods.
- length property: returns the number of
parameters the function has. All functions have this property. (i.e. square.length)
- call() method: used to set the value of this
inside a function to an object that is provided as the first argument. Code Example:
const clark = { name: 'Clark' };
const bruce = { name: 'Bruce' };
sayHello.call(clark);
<< 'Hello, my name is Clark'
sayHello.call(bruce);
<< 'Hello, my name is Bruce'
If the function that’s called requires any parameters, these need to be
provided as arguments after the first argument, which is always the value of this. Code
Example:
function sayHello(greeting='Hello'){
return `${ greeting }, my name
is ${ this.name }`; }
sayHello.call(clark, 'How do you do');
<< 'How do you do, my name is Clark'
sayHello.call(bruce);
<< 'Hello, my name is Bruce'
If a function doesn’t refer to an object as this in its body, it can
still be called using the call() method, but you need provide null as its first argument. (i.e. square.call(null,
4))
- apply() method: works in the same way as
call(), except the arguments of the function are provided as an array, even if there is only one argument (i.e.
square.apply(null, [4])) This can be useful if the data you’re using as an argument is already in the form
of an array, although it's not really needed in ES6, as the spread operator can be used to split an array of
values into separate parameters.
- Custom Properties: you can add your own
properties to functions in the same way that you can add properties to any object. Code
Example:
square.description = 'Squares a number that is provided as an
argument'
- memorization: is result
caching. If a function takes some time to compute a return value, we can save the result in a cache property.
Then if the same argument is used again later, we can return the value from the cache, rather than having to
compute the result again. Code Example:
function square(x){
square.cache = square.cache || {};
if (!square.cache[x]) {
square.cache[x] = x*x; }
return square.cache[x] }
- Immediately Invoked Function Expression or IIFE –
(pronounced 'iffy'): is an anonymous function that is invoked
as soon as it’s defined by placing parentheses at the end of the function definition. The function also
has to be made into an expression by placing the whole declaration inside parentheses. Code
Example:
(function(){
const temp = 'World';
console.log(`Hello ${temp}`);
})();
<< 'Hello World'
IIFE Temporary Variables: There
is no way to remove a variable from a scope once it’s been declared. IIFEs are a
useful way of performing a task while keeping any variables wrapped up within the scope of the function. Can be
used to swap values within a scope.
- destructuring: technique in
ES6 to swap the values of two variables. Code Example:
let [a,b] = [1,2];
[a,b] = [b,a];
IIFE Initialization Code: code
that there’ll be no need for again. Can set up any variables, objects and event
handlers for one use out of scope.
- block scope: ES6 variables
have block scope when const or let are used Code Example:
{
const name = 'Peter Parker'; // This might be obtained from a cookie in reality
const days = ['Sunday','Monday','Tuesday','Wednesday','Thursday',
'Friday','Saturday'];
const date = new Date(),today = days[date.getDay()];
console.log(`Welcome back ${name}. Today is ${today}`);
}
<< 'Welcome back Peter Parker. Today is Tuesday'
IFFE Strict Mode: the
recommended way to use strict mode is to place all your code inside an IIFE with “use strict” right
under (function() {
IFFE Self-contained Code Blocks:
encloses a block of code inside its own private scope so it doesn’t interfere with any other part of the
program. This can be achieved in ES6 by simply placing the different parts of code
into blocks.
Functions that Define and Rewrite Themselves
- Lazy Definition Pattern:
using IFFE’s to redefine/rewrite functions. If the function that is changed is assigned to another
variable before being changed, this variable will maintain the original function definition and not be
rewritten. If any properties have previously been set on the function, these will
be lost when the function redefines itself.
Code Example:
function party(){
console.log('Wow this is amazing!');
party = function(){
console.log('Been there, got the T-Shirt'); } }
- Init-Time Branching: used
with the feature detection to create functions that rewrite themselves. This
enables the functions to work more effectively in the browser, and avoid checking for features every time
they’re invoked. Code Example:
function ride(){
if (window.unicorn) {
ride = function(){
// some code
that uses the brand new and sparkly unicorn methods
return 'Riding on a
unicorn is the best!'; }
} else {
ride = function(){
// some code
that uses the older pony methods
return 'Riding on a pony
is still pretty good'; } }
return ride(); }
- Recursive Functions: a
function that invokes itself until a certain condition is met. i.e.:
function factorial(n) {
if (n === 0) {
return 1;
} else {
return n * factorial(n - 1); } }
- Callbacks: functions passed to other
functions as arguments and then invoked inside the function they are passed to.
- Event-driven Asynchronous Programming (JavaScript event-loop): Instead of waiting for an event to occur, a callback can be created that’s invoked when
the event happens. This means that the code is able to run out of order, or
asynchronously. JavaScript event-loop video - Code
Example:
function wait(message, callback, seconds){
setTimeout(callback,seconds * 1000);
console.log(message); }
function selfDestruct(){
console.log('BOOOOM!'); }
wait('This
tape will self-destruct in five seconds ... ', selfDestruct, 5);
console.log('Hmmm, should I accept this
mission or not ... ?');
<< 'This tape will self-destruct in five seconds ... '
<< 'Hmmm, should I accept this mission or not ... ? '
<< 'BOOOOM!'
- Callback Hell: messy and confusing
'spaghetti code', where more than one callback is used in the same function, resulting in a large number
of nested blocks that are difficult to comprehend. Website on Callback Hell
- Error-first Callbacks: In this coding
pattern, callbacks have two arguments. The first is the error argument. The second argument is any data returned
by the operation that can be used in the body of the callback. (i.e. login(userName,
function(error,user))
- Promises: represents the future result of an
asynchronous operation. #1 There is a pending phase while you wait on the results of an operation. #2 Then once
the promise is settled as resolved or rejected, you deal with the results in an appropriate
way. The
Promise of a Burger Party
- Creating a Promise: A promise is created
using a constructor function. The constructor function takes a function called an executor as an argument. The
executor initializes the promise and starts the asynchronous operation. The executor function also accepts two
functions as arguments: the resolve() function (called if operation is successful), the reject() function
(called if the operation fails). Code Example:
const promise = new Promise( (resolve, reject) => {
// initialization code goes
here
if (success) {
resolve(value);
} else {
reject(error); } });
if-else block: used
below to specify the conditions for success (rolling any number higher than 1) and failure
(rolling a 1) Code Example:
const promise = new Promise( (resolve,reject) => {
const n = dice.roll();
setTimeout(() => {
(n > 1) ? resolve(n) : reject(n);
}, n*1000); });
- then() method: used to
deal with the outcome once a promise is settled. It accepts 2 args. #1 is a fulfilment function called for a
resolved promise. Any data returned from the resolve() function is passed to this function. #2 is a rejection
function called for a rejected promise. Any data returned from the reject() function is passed to this
function. Code i.e.:
promise.then( result => console.log(`Yes! I rolled a ${result}`), result => console.log(`Drat! ... I rolled a ${result}`)
);
- catch() method: can be
used, alternatively, to specify what to do if the operation fails instead. Code Example:
promise.catch( result => console.log(`Drat! ... I rolled a ${result}`));
- then() & catch() methods chained
together: this forms a succinct description of how to deal with
the outcome of the promise. Code Example:
promise.then( result => console.log(`I rolled a ${result}`) )
.catch( result => console.log(`Drat! ... I rolled a ${result}`) );
- Chaining Multiple Promises:
we can chain the then() methods together to form a sequential piece of code that’s easy to read. Each
promise begins after the previous promise is settled. Code Example.:
login(userName)
.then(user => getPlayerInfo(user.id))
.then(info => loadGame(info))
.catch( throw error)
- Async Functions: (added in
ES2017) These functions are preceded by the async keyword and allow you to write asynchronous code as if it
was synchronous. This is achieved by using the await operator before an asynchronous function. This will wrap
the return value of the function in a promise that can then be assigned to a variable. The next line of code
is not executed until the promise is resolved. Code Example:
async function loadGame(userName) {
try {const user = await login(userName);
const info = await getPlayerInfo (user.id);
// load the
game using the returned info }
catch (error){throw error;} }
- Generalized Functions:
Callbacks can be used to build more generalized functions. Instead of having lots of specific functions, one
function can be written that accepts a callback. Code Example:
function random(a,b,callback) {
if (b === undefined) b = a, a = 1; // if only one argument is supplied, assume the lower limit
is 1
const result = Math.floor((b-a+1) * Math.random()) + a
if(callback) {
result = callback(result); }
return result; }
- Functions That Return Functions: In JavaScript functions can return functions. To make use of the function that is returned,
we need to assign it to a variable. Then you can invoke the function by placing parenthesis after the
variable. In this way different specific uses of the function can be tied to different variables. Code
Example.:
function greeter(greeting = 'Hello') {
return function() {
console.log(greeting); } }
const englishGreeter = greeter(); // greeter() called
englishGreeter();
<< Hello
const frenchGreeter = greeter('Bonjour'); // greeter
called
frenchGreeter();
<< Bonjour
const germanGreeter = greeter('Guten Tag'); //
greeter called
germanGreeter();
<< Guten Tag
- Closures: one of
JavaScript’s most powerful features. It is a reference to a variable that
was created inside the scope of another function, but is then kept alive and used in another part of the
program. Whenever a function is defined inside another function, the inner
function will have access to any variables that are declared in the outer function's scope. Code
Example:
function outer() {
const outside = 'Outside!';
function inner() {
const inside = 'Inside!';
console.log(outside);
console.log(inside); }
console.log(outside);
inner(); }
outer()
<< Outside!
Inside!
Outside!
- Forming a Closure: A
closure is formed when the inner function is returned by the outer function, maintaining access to any
variables declared inside the enclosing function. i.e.:
function outer() {
const outside = 'Outside!';
function inner() {
const inside = 'Inside!';
console.log(outside);
console.log(inside); }
return inner; }
const closure = outer();
closure();
<< Outside!
Inside!
- Closure Use: Closures not
only have access to variables declared in a parent function's scope; they can also change the value of
these variables. Code Example:
function counter(start){
let i = start;
return function() {
return i++; } }
const count = counter(1);
count();
<< 1
count();
<< 2
- Generators: are special
functions used to produce iterators that maintain the state of a value. To define
a generator function, an asterisk symbol (*) is placed after the function declaration. It runs a loop one
cycle through with the next() method that it inherits.
yield: Generator functions
employ this special keyword that is used to return a value. The difference between the yield and the
return keywords is that by using yield, the state of the value returned is remembered the next time yield is
called. Code Example:
function* fibonacci(a,b) {
let [ prev,current ] = [ a,b ];
while(true) {
[prev, current] = [current, prev + current];
yield current; } }
const sequence = fibonacci(1,1);
sequence.next();
<< 2
sequence.next();
<< 3
sequence.next();
<< 5
iterating over the generator:
this will invoke the generator multiple times. In the example the sequence will continue from the last value
produced using the next() method, because a generator will maintain its state throughout the life of a program.
Code i.e.:
for (n of sequence) {
// stop the sequence after
it reaches 100
if (n > 100) break;
console.log(n); }
<< 8 << 13 << 21 << 34 << 55 << 89
- programming paradigm: a way to view and
approach programming, i.e.: #1 object oriented programming #2 procedural programming #3 functional programming. JavaScript is a multi-paradigm language,
meaning that it can be used to program in a variety of paradigms (and sometimes a mash-up of them!).
- Functional Programming: is a programming
paradigm. JavaScript has always supported functional-style programming due to functions being first-class
objects. The ability to pass functions as arguments, return them from other functions, and use anonymous
functions and closures, are all fundamental elements of functional programming that JavaScript excels at.
Functional programming uses pure functions as the building blocks of a program. A program becomes a sequence of expressions based on the return values of pure functions. The
emphasis is placed on using function composition to combine pure functions together
to complete more complex tasks. It allows generic higher-order functions to be used to return more specific
functions based on particular parameters.
Pure Functions: A key aspect of
functional programming is its use of pure functions. (A pure function is a function that adheres to the
following rules: #1 The return value of a pure function should only depend on
the values provided as arguments. It doesn't rely on values from somewhere else in the
program. #2 There are no side-effects. A pure function doesn't
change any values or data elsewhere in the program. It only makes non-destructive data transformations and
returns new values, rather than altering any of the underlying
data. #3 Referential transparency. Given the same arguments, a pure function
will always return the same result.) A pure function must have #1 at least one
argument #2 a return value. By only performing a single task, pure functions are more flexible, as they can be
used as the building blocks for many different situations
const: using const to declare
variables will help to avoid destructive data transformations. (although variables
that are assigned to non-primitive objects using const can still be mutated, so it's not a complete
solution).
Code Example:
const number = 42;
function pureAdd(x,y) {
return x + y; }
result = pureAdd(number,10);
<< 52
function
composition: using functions as the building blocks of functions. Code i.e.:
function variance(array) {
return sum(array,square)/array.length - square(mean(array)) }
variance([1,2,3])
<< 0.666666666666667
- Higher-Order Functions:
functions that accept another function as an argument, or return another function as a result, or both. They
can create a generic function that can be used to then return more specific functions based on its arguments.
Code Example:
function multiplier(x){
return function(y){
return x*y; } }
doubler = multiplier(2);
doubler(10);
<< 20
tripler = multiplier(3);
tripler(10);
<< 30
using double parentheses: create
an anonymous return function and immediately invoke it. This example works because power(3) returns a function, to
which we immediately pass an argument of 5 by adding it in parentheses at the end. Code Example:
function power(x) {
return function(power) {
return Math.pow(x,power); } }
twoExp = power(2);
<< function (power) {
return Math.pow(x,power); }
twoExp(5);
<< 32
power(3)(5);
<< 243
- Currying: a process that involves the
partial application of functions. It’s named after the logician Haskell Curry developed while working on a
paper by Moses Schönfinkel. Currying relies on higher-order functions that are
able to return partially applied functions. All curried functions are higher-order functions because they return a
function, but not all higher-order functions are curried. Currying allows you to turn
a single function into a series of functions instead.
- Curried Function: A function is said to be
curried when not all arguments have been supplied to the function, so it returns another function that retains
the arguments already provided, and expects the remaining arguments that were omitted when the original function
was called. A final result is only returned once all the expected arguments have eventually been provided.
Code Example:
function multiplier(x,y) {
if (y === undefined) {
return function(z) {
return x * z; }
} else {
return x * y; } }
calcTax = multiplier(0.22);
<< function (z){
return x * z; }
calcTax(400);
<< 88
Ch8: Transforms and Transitions (Notes)
- CSS3 Transforms and Transitions: without a
line of JavaScript or a single JPEG, you can tilt, scale, move, and even flip your elements with ease.
- CSS3 transform property: lets you
translate, rotate, scale, and/or skew any element on the page. Transforms
don’t work on inline elements. To fix that just add “display: inline-block;” to the element in
the CSS file.
- translate(x,y) function: moves an element x
from the left, and y from the top. Translation, has no impact on the document flow. This means that if you
translate inline-block elements, text around it will fail to accommodate it with reflowing. Code
i.e.:
transform: translate(45px, -45px);
- Transforms and Older Browsers: require
vendor prefixing for IE9, Android up to 4.4.3, iOS8, and Blackberry 10. (i.e. -webkit-transform:
translate(45px,-45px); /* iOS8, Android ↵4.4.3, BB10 */ or -ms-transform: translate(45px,-45px); /* IE9 only */)
- translateX(x) function: used to move an
element horizontally. Code Example:
transform: translateX(45px);
- translateY(y) function:
used to move an element vertically. Code Example:
transform: translateY(-30px);
- scale(x,y) function: scales
an element by the defined factors horizontally then vertically. If only one value is provided, it will be used
for both. The element’s center will stay in the same place as its dimensions change. Scaling, like
translation, has no impact on the document flow. This means that if you scale inline-block elements, text
around it will fail to accommodate it with reflowing. Code Examples:
transform: scale(1.5, 0.25);
transform: scale(1); /* Maintains the same size
with size*1 */
transform: scale(2); /* Doubles the size with
size*2 */
- scaleX(x) function: will
scale only the horizontal dimensions.
transform: scaleX(1.5);
- scaleY(y) function: will
scale only the vertical dimensions.
transform: scaleY(1.5);
- multiple transformations:
To declare, provide a space-separated list of transform functions. A second
transform would override the first. Code Example:
transform: translateX(40px) scale(1.5);
- rotate() function: rotates
an element around the point of origin by a specified angle value. As with scale, by default the point of
origin is the element’s center. Generally, angles are declared in degrees, with positive degrees moving
clockwise and negative moving counterclockwise. (In addition to degrees, values can be provided in grads,
radians, or turns) Code Example:
transform: rotate(10deg)
- skew(x,y) function:
specifies a skew along the x and y axes. If the second parameter is omitted, the skew will only occur on the x
axis.
transform: skew(15deg, 4deg);
- skewX(x): will scew only
the horizontal dimensions.
transform: skewX(15deg);
- skewY(y): will scew only the vertical dimensions.
transform: skewY(15deg);
- transform-origin property:
you can control the origin from which your transforms are applied. It defaults to the center of the object (so
that scales and rotations will be around the center of the box by default). Browser support for the
transform-origin property is the same as for transform —prefixing being required when the transform
property requires it. Application: applying a rotate() transform to a circle would have no visible effect,
however, if you gave your circle or ellipse a transform-origin of 10% 10% or top center, you would notice the
rotation. Code Example:
transform-origin: 10% 10%;
transform: rotate(180deg);
- Choose Your Ordering Carefully: The order
of transform functions does matter: if you rotate before translating, your translate direction will be on the
rotated axis.
- Mimicking CSS3 transforms (which is unsupported in IE before version 9): (translation) use
position: relative;, and top and left values (scale) alter its width and height, or changing the font-size,
however – unlike transform’s scale this alters the space allocated for the element and can affect
the layout. (rotate) You can use filters to rotate an element in older versions of Internet Explorer, but
it’s ugly and performs poorly
- CSS transition property: transitions can be
gradual, with all for all properties being the default. Any property changing from
one value to another for which you can find a valid midpoint can be transitioned + the exception of visible and
hidden. List of properties that can be animated Link. You can provide any number of CSS properties to the
transition-property declaration, separated by commas. Alternatively, you can use the keyword all to indicate
that every supported property should be animated as it transitions. If the browser lacks support for
transitions, the change will be immediate instead of gradual, which is fine and accessible. Often the change will be due to different styles applied to a hover state; however, transitions
will work equally well if the property in question is changed by adding a class, or otherwise using JavaScript
to change state. (The -webkit- vendor prefix is still needed for older mobile devices, including iOS6.1,
BlackBerry10, Android 4.3 and UC Browser for Android.) In itself, the transition-property has no effect;
that’s because we still need to specify the duration of the transition. Code
Examples:
transition-property: transform;
more than 1 property
transition-property: transform, color;
older browsers
-webkit-transition-property: -webkit-transform;
transition-property: transform;
- Steps to create a simple transition using only CSS: #1 Declare the original state of the element in the default style
declaration. #2 Declare the final state of your transitioned element; for example, a :hover state. #3 Include the
transition functions in your default style declaration using the transition properties.
- transition-duration property: sets how long
the transition will take. You can specify this either in seconds (s) or milliseconds (ms).
(200ms is generally considered the optimum time for a
transition.) Code Example:
transition-duration: 0.2s;
- transition-timing-function:
lets you control the pace of the transition in even more granular detail. The
most common timing functions include the key terms ease, linear, ease-in, ease-out, or ease-in-out.
ease: default key term for
transition-timing-function that has a slow start, then it speeds up, and ends
slowly.
ease-in-out: key term for
transition-timing-function that is similar to ease, but accelerates more sharply at the beginning.
linear: key term for
transition-timing-function that creates a transition that animates at a constant
speed.
ease-in: key term for
transition-timing-function that creates a transition that is slow to start but gains speed, then stops
abruptly.
ease-out: key term for
transition-timing-function that starts at full speed, then slows progressively as it
reaches the conclusion of the transition.
Code Example:
transition-timing-function: ease-out;
- cubic-bezier function: It accepts four
numeric parameters. If you’ve studied six years of calculus, the method of writing a cubic Bézier
function might make sense; otherwise, it’s likely you’ll want to stick to one of the five basic timing
functions. Helps: Link1 Link2
- steps function: you define the number of
steps and the direction of either start or end. For example, steps(5, start) would jump through the equidistant
steps of 0%, 20%, 40%, 60%, and 80%, and steps(5, end) would jump throught the equidistant steps of 20%, 40%,
60%, 80%, and 100%.
- transition-delay property: makes it’s
possible to introduce a delay before the transition begins. Normally a transition begins immediately, so the
default is 0. Include the number of milliseconds (ms) or seconds (s) to delay the transition. (Interestingly, a
negative time delay that’s less than the duration of the entire transition will cause it to start
immediately, but it will start partway through the animation. For example, if you have a delay of -500ms on a 2s
transition, the transition will start a quarter of the way through, and will last 1.5 seconds. On the way back,
it will jump 75% of the way through the transition, and then transition back to the default state.) Code
Example:
-webkit-transition-delay: 50ms;
transition-delay: 50ms;
- transition Shorthand Property: The transition property is shorthand for the four transition properties. (Note that the
properties in the shorthand syntax can be in any order, however, if a delay is included, you must also include
a duration, and the duration must precede the delay.) Code Example:
transition-property: transform;
transition-duration: 0.2s;
transition-timing-function: ease-out;
transition-delay: 50ms;
shorthand =
transition: transform 0.2s ease-out 50ms;
- transition properties at different rates: include them as a comma-separated list containing, at minimum, the transition-property and
transition-duration for each. Simply include each value in a comma-separated list using the same order as the
transition-property for all your longhand transition property declarations. Code Example:
transition-property: transform, color;
transition-duration: 0.2s, 0.1s;
transition-timing-function: ease-out, linear;
transition-delay: 50ms;
- shorthand for multiple transitions at different durations,
delays, & timing functions: specify all the transition values as a
shorthand for each transition, and separate each property’s transition with a comma. Code
Example:
transition: transform 0.2s ease-out 50ms, color 0.1s linear 50ms;
- all keyword: all the
properties transition at the same rate, speed, and delay. Code i.e.:
transition: all 0.2s ease-out 50ms;
- transitionend event—prefixed and camel-cased as
webkitTransitionEnd: is fired upon completion of a CSS transition in both
directions. If you have more than one property being transitioned, the transitionend
event will fire multiple times.
- CSS animations: allow you to control each
step of an animation via keyframes.
keyframe: a snapshot that
defines a starting or end point of any smooth transition. With CSS transitions,
you’re essentially limited to defining a first and a last keyframe. CSS animations allow you to add any
number of keyframes in between, to guide our animation in more complex ways. (the -webkit- prefix in iOS8, Android
4.4.3, and BlackBerry 10 is required) Generally, it is best to use CSS for
simple-state changes in a mobile environment.
Code Examples:
@keyframes moveRight {
from {
transform: translateX(-50%);
}
to {
transform: translateX(50%);
}
}
@keyframes appearDisappear {
0%, 100% {
opacity: 0;
}
20%, 80% {
opacity: 1;
}
}
@keyframes bgMove {
100% {
background-position: 120% 0;
}
}
- Apply it to one or more elements using the various animation
properties: the code above created three animations, but nothing in
our document will animate yet. An element must have at minimum an animation name for there to be an animation,
and must also have a duration declared for the animation to be perceptible. Once the keyframe animations are
defined, the next step is to apply it to one or more elements using the various animation properties. (While
animation-name is the only required animation property to create an animation, the animation-durationshould be
considered required to animate an element. Without declaring the duration it defaults to 0s, which is
imperceptible, but still fires the animationstart and animationend events. The other animation properties,
while they enable you to better control your animation, are optional.)
animation name property: names
the animation.
animation-duration property:
defines the length of time (in seconds or milliseconds) an animation takes to complete one iteration (all the way
through, from 0% to 100%).
animation-timing-function:
determines how the animation will progress over its duration. The options are the same as for
transition-timing-function: ease, linear, ease-in, ease-out, ease-in-out, a developer-defined cubic-bezier()
function, step-start, step-end, or a developer-defined number of steps with the steps(number, direction)
function.
animation-iteration-count property: lets you define how many times the animation will play through. The value is generally an
integer, but you can also use numbers with decimal points (in which case, the animation will end partway through
an iteration), or the value infinite for endlessly repeating animations. If omitted, it will default to 1.
animation-direction property:
The value of reverse will cause the animation to start at the 100% keyframe and work its way to the 0% keyframe
for every iteration. With the alternate value, the initial iteration and odd-numbered iterations after that will
go in the normal 0% to 100% direction, but the second iteration and every even iteration after that will go in the
reverse direction of 100% to 0%. Similarly, the alternate-reverseanimation-direction value causes the animation to
alternate direction at every iteration, but it starts in reverse. When animations are
played in reverse, timing functions are also reversed; for example, ease-in becomes ease-out.
animation-delay property: used
to define how many milliseconds or seconds to wait before the browser begins the animation
animation-fill-mode property:
defines what happens before the first animation iteration begins and after the last animation iteration concludes.
(default behavior animation-fill-mode: none) The available values are none, forwards,
backwards, or both.
- backwards: keyword that tells the animation
to sit and wait on the first keyframe from the moment the animation is applied to the element, through the
duration of the animation delay, until the animation starts iterating.
- forwards: keyword that holds the element at the last keyframe, with last keyframe property values overriding the
element's original property values, without reverting to the original values at the conclusion of the last
animation iteration.
- both: keyword that does both the backwards
and forwards key words actions.
animation-play-state property:
defines whether the animation is running or paused.
Code Examples:
animation-name: appearDisappear;
animation-duration: 300ms;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-delay: 50ms;
animation-fill-mode: both;
animation-play-state: running;
Shorthand animation Property: The animation property takes as its value a space-separated list of values for the longhand
animation-name, animation-duration, animation-timing-function, animation-delay, animation-iteration-count,
animation-direction, animation-fill-mode, and animation-play-state properties. (Note that in the shorthand
version, the animation-iteration-count and animation-play-state were left out since both were set to default.)
Code Example:
.verbose {
animation-name: appearDisappear;
animation-duration: 300ms;
animation-timing-function: ease-in;
animation-iteration-count: 1;
animation-direction: alternate;
animation-delay: 5s;
animation-fill-mode: backwards;
animation-play-state: running;
}
/* shorthand */
.concise {
animation: 300ms ease-in alternate 5s backwards appearDisappear;
}