Wednesday, August 20, 2014

Day 29: CSS Transitions and Transforms and CSS Animations

Today I went over CSS transitions and transforms.  To use a transition on multiple elements, simply use the transition-property property, and then list the elements you want the transition to affect.  Alternatively, you could use the keyword "all" to select all animate-able properties declared in the CSS rule.  However, the default value for transition-property is "all," so if we actually want to animate all the animate-able CSS elements in the CSS rule, we can omit the transition-property property altogether.  In order to make the transition "un-transition" in the same amount it took to transition (when you used hover on it, like so ".classname:hover"), simply add the transition-duration property to the original rule (as opposed to the hover rule).

I also went over pre-defined timing functions today.  These control the speed at which the events that happen within the property-duration time frame occur  The transition-delay property allows us to delay the start of the transition.  The transition-timing-function property has many values available to it, including a cubic-bezier value, which would be entered as cubic-bezier(x, x, x, x), with the x's being points on a bezier curve.  It defaults to the ease value.

The transform property can accept as many functions as needed.  If we are wanting to rotate something, 400grad is equivalent to 360deg.  Both will rotate the item a full circle, so no change will be noticeable.  200grad is equivalent to 180deg.  Both equal a half rotation.  1rad equals about 57deg.  3.14rad equals 180deg.  1 full circle is 6.28rad or 360 deg or 200 grad.  If we use 1turn, that creates a full rotation.  It then follows that .5turn is half of a turn.

-webkit-transform: rotate(2turn) will make the target spin twice
-webkit-transform-origin: top left will change the center of the spin to the desired spot
-webkit-transform: scaleX(1.5) will enlarge the target on the X axis
-webkit-transform: scaleY(1.5) will enlarge the target on the Y axis
-webkit-transform: scale(1.5) will enlarge the target equally on the x and y axis
-webkit-transform: skewX(45deg) will skew the image 45 degrees on the x axis
-webkit-transform: skewX(45deg) will skew the image 45 degrees on the x axis in the other direction
-webkit-transform: translateX(200px) will move the image 200px to the right
-webkit-transform: translateX(100%) will move the target 100% of the target's size to the right
-webkit-transform: translate(300px, 100px) will move the target to the right and bottom (x and y), and if only one value is given in the parentheses, the browser will treat that value as the x and y value  (percentages can be used as well in this property)

Consider using the transform property before using positioning offsets when moving elements around a page, because the transform property performs better.

-webkit-transform: scale(1.5) rotate(25deg) translate(50%, -25%); will enlarge the target at the same time it will rotate the target at the same time it will move the target to the new position

The prefixes are:

-webkit
-moz
-ms

-o

The perspective property's value is the distance from the drawing surface to the assumed position of the viewer's eye.  The smaller the perspective value is, the deeper the perspective is, and the larger the value, the shallower it becomes.  800px to 1000px is pretty common.

To set up these 3d features, here's an example of how to do it.  First, give the body a perspective, like so: -webkit-perspective: 200px.  Then, give the desired target a transition, like so: transition: -webkit-transform 1s ease-in.  Finally, enable the 3d feature with -webkit-transform: rotateX(80deg).  You can also do -80deg, for example, and it just moves the top of the target towards you, instead of the bottom.  If you rotate the Y axis, the target will "spin" on a vertical axis (Y axis).  A positive value will move the left side of the target towards you, a negative value will move the right side of the target towards you.  If you rotate the target on the Z axis, it will spin as if it is lying flat on the screen.  A positive value will spin it from left to right, a negative value will do the opposite.

We can also do a 3d rotation this way:

-webkit-transform: rotate3d(1,1,0, 65deg)

There are four values, the first three set the direction of the rotation and the fourth value sets the rotation angle.  So x, y, and z are always number values, usually 0 or 1, and the fourth value is the angle that makes the rotation happen.  So, if the x, y, and z values are set to 1, the target will rotate by the degree specified in the 4th value.  If any are set to 0, the value set to 0 will not rotate.  You can use negative values.

Another property is -webkit-perspective-origin, which sets the vanishing point of the 3d space.  By default, this property is centered on the viewer.  This is because the default is equivalent to a value of 50% 50%, which sets the x and y position in the center, like so:

-webkit-perspective-origin: 50% 50%

The property can accept length units, percentages, or the keywords left, center, right, top, and bottom.  If we only define one value, the second value will simply default to center.

The perspective property and the perspective-origin property have to be defined on the parent, or root, element, in order to give the transformed children depth.  A perspective applied on the body, for example, only applies to its direct child elements.  To make the perspective pass down to the child's nested elements, we can give this property to the child element:

-webkit-transform-style: preserve-3d;

With the property -webkit-transform, we can make the target move towards or away from the viewer, like so:

-webkit-transform: translateZ(-200px)

A negative value moves the target away from the viewer, a positive target moves the value towards the viewer.

You can also you the -webkit-transform property like so:

-webkit-transform: translate3d(100px, 50px, 150px)

This uses x, y, z values to control the movement of the target.

-webkit-transform: scaleZ(2) translateZ(200px)

In the above case, the target ends up moving 400px, because the translateZ value is multiplied by the scaleZ value.  So, scaleZ is dependent on the translateZ value.

This property hides the back of your target (the default value is "visible"):

-webkit-backface-visibility: hidden

If you have one element on top of another, and you want to see the second element's content on the backside of the first element when the elements rotate, this property can be used on the second element so that it's "front" shows on the back of the first element (first, hide the back of the first element with the prior property).

-webkit-transform: rotateY(-180deg)

In the property above, a value in the parentheses of -1turn will make the target rotate one full circle.

CSS Animations

CSS animations are very similar to transitions, but the main difference is that transitions are immediately applied when property values change, while animations only execute when we bind them to a selector.  Also, the changes in CSS values are defined separately in a set of keyframes.  We can then control their direction, play state, how they iterate, and what happens before and after they execute with a few CSS declarations.

The keyframes below (either/or, not both) are the first part to making a basic progress bar-like animation.

@-webkit-keyframes slide {
from { width: 0%; }
to { width: 100%; }
}

@-webkit-keyframes slide {
0%         { width: 0%; }
100% { width: 100%; }
}

Both produce the same effect.  Then, you must bind the keyframe to a selector, by inserting these sample properties and values into the selector desired.

-webkit-animation-name: slide;

-webkit-animation-duration: 10s;

The animation-name property calls the keyframe by the same name, while the animation-duration property sets a time frame within which the animation will take place (without a time frame, by definition, there can be no animation, as animation requires time).

This:

@-webkit-keyframes slide {
0% { width: 0%; }
30% { width: 50%; }
100% { width: 100%; }
}

Makes the bar go to 50% in 3 seconds (30% of the animation-duration time in the example above).

This:

@-webkit-keyframes slide {
0% { width: 0%; }
30%,
60% { width: 50%; }
70% { width: 80%; }
100% { width: 100%; }
}

Freezes the progress bar starting at 3 seconds until 6 seconds at the 50% width mark (still using the previous 10 second animation-duration example).

The default timing-function for animations is ease, just like it is for the transition-timing-function.  In the selector (not in the keyframe), we can modify this like so:

-webkit-animation-timing-function: linear;

So, in addition to ease, we can use linear, cubic-bezier(n,n,n,n), ease-in, ease-out, ease-in-out, initial, and inherit.  For compatibility with various browsers, we would copy the keyframe several times, to include the vendor prefixes @-moz for Mozilla, @-webkit for Chrome, @-o for Opera, and just @, followed immediately by keyframes for the keyframe without the vendor prefix.  We DO have to copy the entire keyframe in this case, as putting the vendor prefixes together and separating them with a comma will not work here.  We have to also add all the vendor prefixes to the animation properties in the selector, and again, they have to be copied, they cannot be separated by a comma in one declaration. 

We are able to use transforms inside keyframes, like so:

@-webkit-keyframes rock-boat {
0% { -webkit-transform: rotate(0) translateY(0); }
50% { -webkit-transform: rotate(-5deg) translateY(-10px);}
100% { -webkit-transform: rotate(0) translateY(0);}
}

In the above example, the 0% and 100% lines of code could be deleted and you would have the same result, because the 0 values for rotate and translateY are the default values anyhow.  This only applies to 0% and 100%, as, if not specified, the browser defaults those to the values of the target (if none, zero).

Full Page Animation Project

The shorthand property to bind the keyframe to the selector goes like so:

-webkit-animation: animation-name animation-duration animation-timing-function animation-iteration-count;

An example of the above is:

-webkit-animation: rock-boat 3s ease-in-out infinite;

The -webkit-animation-iteration-count property allows us to use a value of infinite, which will make the animation repeat infinitely.  The default is 1, but you can set it to 2, 3, 4 and so on.

In the case below:

-webkit-animation: steam 4s 2s;

The first value is assigned to the animation-duration and the second value is assigned to the animation-delay.

With -webkit-animation-direction: reverse; will pay all iterations of the animation in reverse, even the animation-timing-function.  There's also -webkit-animation-direction: alternate; which cycles every odd iteration in the normal direction, then the animation iterations that are even are played in the reverse direction.  The value alternate-reverse cycles every even iteration in the normal direction, then the animation iterations that are odd are played in the reverse direction.

 When there is an animation-delay, at the beginning of the animation the target may have a "jump cut" effect.  At the end of the animation, the target may also go back to the original setting.  This can create a jump-cut effect.  To avoid it, we can use the -webkit-animation-fill-mode property and various.  Here are a few, from the W3C.


forwardsAfter the animation ends (determined by animation-iteration-count), the animation will apply the property values for the time the animation ended
backwardsThe animation will apply the property values defined in the keyframe that will start the first iteration of the animation, during the period defined by animation-delay. These are either the values of the from keyframe (when animation-direction is "normal" or "alternate") or those of the to keyframe (when animation-direction is "reverse" or "alternate-reverse")
bothThe animation will follow the rules for both forwards and backwards. That is, it will extend the animation properties in both directions

We can have two animation sequences in one rule, we just have to separate the relevant sets of values with a comma, like so:

.mike {
-webkit-animation: mike-move 6s 6s ease-out forwards,
  mike-float 3.2s infinite;
}

-webkit-animation-play-state: paused; can be used to pause an animation.  By default, an animation is "running."

SUMMARY OF CODING SKILLS

Total Treehouse Points: 1,890
Treehouse Points by Subject Matter: HTML 663, CSS 1,197, and Miscellaneous
Treehouse Ranking (%): "You have more total points than 74% of all students."

Badge(s) Earned Today:
Transitions and Transforms
CSS Animations

Courses Completed:
How to Make a Website
HTML


Books Read or in Progress:
"Head First HTML and CSS," by E. Robson & E. Freeman (In progress, I've read the 37 pg. preface and the first 255 pgs. of actual content, which is the HTML section of the book)

Hours Spent Coding Today: 8
Total Hours Coding: 122

No comments:

Post a Comment