<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Dan Wilson</title>
    <description>Personal site for web and app developer Dan Wilson. Articles, Projects, and More.
</description>
    <link>http://danielcwilson.com/</link>
    <atom:link href="http://danielcwilson.com/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Fri, 07 Apr 2017 08:19:28 -0500</pubDate>
    <lastBuildDate>Fri, 07 Apr 2017 08:19:28 -0500</lastBuildDate>
    <generator>Jekyll v2.5.3</generator>
    
      <item>
        <title>Individualizing CSS Properties with CSS Variables</title>
        <description>&lt;p&gt;In &lt;a href=&quot;/blog/2017/02/individual-transforms&quot;&gt;“A Trick: Individual CSS Transform Functions”&lt;/a&gt;, I discussed how we could use CSS Variables (Custom Properties) to bring us close to independent transform properties. Each day I explore CSS Variables, however, I’m finding they can help us with any property that accepts multiple values at the same time.&lt;/p&gt;

&lt;p data-height=&quot;265&quot; data-theme-id=&quot;0&quot; data-slug-hash=&quot;WpBEBX&quot; data-default-tab=&quot;js,result&quot; data-user=&quot;danwilson&quot; data-embed-version=&quot;2&quot; data-pen-title=&quot;Pause Independent Animations with CSS Variables&quot; data-preview=&quot;true&quot; data-editable=&quot;true&quot; class=&quot;codepen&quot;&gt;See the Pen &lt;a href=&quot;http://codepen.io/danwilson/pen/WpBEBX/&quot;&gt;Pause Independent Animations with CSS Variables&lt;/a&gt; by Dan Wilson (&lt;a href=&quot;http://codepen.io/danwilson&quot;&gt;@danwilson&lt;/a&gt;) on &lt;a href=&quot;http://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This example shows a block of text that animates via &lt;code&gt;clip-path&lt;/code&gt; to reveal itself over another block of text.  I’ve added a second keyframe animation to do a &lt;code&gt;hue-rotate&lt;/code&gt; &lt;code&gt;filter&lt;/code&gt; to effectively cycle through colors for the background. The &lt;code&gt;animation&lt;/code&gt; property therefore has two values: one for each animation. If I want to change anything later for only one animation - such as a &lt;code&gt;duration&lt;/code&gt; or &lt;code&gt;play-state&lt;/code&gt;, I would likely take one of two approaches (Let’s talk about toggling the &lt;code&gt;animation-play-state&lt;/code&gt; from &lt;code&gt;paused&lt;/code&gt; to &lt;code&gt;running&lt;/code&gt;):&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Set up multiple classes to represent all the different combinations of play state we can have (in our case four: &lt;code&gt;running,running&lt;/code&gt;; &lt;code&gt;running,paused&lt;/code&gt;; &lt;code&gt;paused,running&lt;/code&gt;; &lt;code&gt;paused,paused&lt;/code&gt;;), and use JavaScript to determine the correct one and toggle the class.&lt;/li&gt;
  &lt;li&gt;Or: use JavaScript to &lt;code&gt;getComputedStyle&lt;/code&gt; on our animating element, tokenize the value based on the comma, set the desired value on the one we want to update, and then join back together for a final result string to be set on the element’s &lt;code&gt;style.animationPlayState&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These approaches have drawbacks, since they both grow more complex as we add more animations. We need nine classes if we have three animations and more complicated JS to get the right class applied. For the second option, we need to add additional logic to our JS any time a new animation is added, and we need to be careful to not change order in our CSS.&lt;/p&gt;

&lt;p&gt;Instead, our example shows how we can use CSS Variables to break them apart and think of them more individually.  We set up our &lt;code&gt;animation&lt;/code&gt; as we normally would but we also set a separate &lt;code&gt;animation-play-state&lt;/code&gt; property value, with the default values of running:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-css&quot; data-lang=&quot;css&quot;&gt;&lt;span class=&quot;nt&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;play&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;running&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;play&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;running&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;animation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; 
    &lt;span class=&quot;n&quot;&gt;reveal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;3000&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ms&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ms&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;infinite&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;alternate&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ease&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;both&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;hue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;adjust&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;6000&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ms&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ms&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;infinite&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;alternate&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ease&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;animation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;play&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; 
    &lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;play&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;play&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now we can add some form controls that allow us to pause an individual animation via a small amount of JS:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;main&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//Get Form controls with an id that syncs with the CSS Variable names&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;shape&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;click&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;updatePlayState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;hue&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;click&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;updatePlayState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;updatePlayState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;variable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;--&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;currentTarget&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;-play-state&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;setProperty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;currentTarget&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;checked&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;paused&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;running&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This allows us to break out of manipulating full property values when we only need to update a small segment. We could take this further and add controls to everything… for each animation’s durations, direction, iteration count, etc. It’s not just CSS Animations and Transforms that take multiple values/functions in their properties and benefit from this approach.&lt;/p&gt;

&lt;p&gt;We can use CSS Variables to switch Hue, Saturation, and Lightness for &lt;code&gt;color: hsl()&lt;/code&gt;:&lt;/p&gt;

&lt;p data-height=&quot;265&quot; data-theme-id=&quot;0&quot; data-slug-hash=&quot;BpbYmZ&quot; data-default-tab=&quot;css,result&quot; data-user=&quot;danwilson&quot; data-embed-version=&quot;2&quot; data-pen-title=&quot;HSL&quot; class=&quot;codepen&quot;&gt;See the Pen &lt;a href=&quot;http://codepen.io/danwilson/pen/BpbYmZ/&quot;&gt;HSL&lt;/a&gt; by Dan Wilson (&lt;a href=&quot;http://codepen.io/danwilson&quot;&gt;@danwilson&lt;/a&gt;) on &lt;a href=&quot;http://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We can combine it with “The Original CSS Variable” &lt;code&gt;currentColor&lt;/code&gt; and theme a site:&lt;/p&gt;

&lt;p data-height=&quot;265&quot; data-theme-id=&quot;0&quot; data-slug-hash=&quot;bqxRgj&quot; data-default-tab=&quot;css,result&quot; data-user=&quot;danwilson&quot; data-embed-version=&quot;2&quot; data-pen-title=&quot;Site Theming with input[type=range]&quot; class=&quot;codepen&quot;&gt;See the Pen &lt;a href=&quot;http://codepen.io/danwilson/pen/bqxRgj/&quot;&gt;Site Theming with input[type=range]&lt;/a&gt; by Dan Wilson (&lt;a href=&quot;http://codepen.io/danwilson&quot;&gt;@danwilson&lt;/a&gt;) on &lt;a href=&quot;http://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We can even update the individual parts of a &lt;code&gt;cubic-bezier()&lt;/code&gt; easing function on the fly:&lt;/p&gt;

&lt;p data-height=&quot;241&quot; data-theme-id=&quot;0&quot; data-slug-hash=&quot;wJOazR&quot; data-default-tab=&quot;css,result&quot; data-user=&quot;danwilson&quot; data-embed-version=&quot;2&quot; data-pen-title=&quot;Jump to Where You Press&quot; data-preview=&quot;true&quot; class=&quot;codepen&quot;&gt;See the Pen &lt;a href=&quot;http://codepen.io/danwilson/pen/wJOazR/&quot;&gt;Jump to Where You Press&lt;/a&gt; by Dan Wilson (&lt;a href=&quot;http://codepen.io/danwilson&quot;&gt;@danwilson&lt;/a&gt;) on &lt;a href=&quot;http://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Multiple backgrounds, box shadows, and more are open to this simplification. Latest Chrome, Firefox, and Safari do well with these examples. Edge 15 (just released) is the first version to have CSS Variables, so I’m just starting to play with this there and… &lt;a href=&quot;http://codepen.io/danwilson/pen/ZeaVLz/&quot;&gt;they sometimes work&lt;/a&gt;. Impressive for an initial release in my book, and the more common use cases for Variables seem to be working very well.  Hopefully we will see improvements in all the browsers as we continue to explore what CSS Variables can do.&lt;/p&gt;
</description>
        <pubDate>Fri, 07 Apr 2017 00:00:00 -0500</pubDate>
        <link>http://danielcwilson.com/blog/2017/04/individualized-properties/</link>
        <guid isPermaLink="true">http://danielcwilson.com/blog/2017/04/individualized-properties/</guid>
        
        <category>animations</category>
        
        <category>web</category>
        
        <category>CSS Variables</category>
        
        
      </item>
    
      <item>
        <title>A Trick: Individual CSS Transform Functions</title>
        <description>&lt;p&gt;We get a lot of power through the single &lt;code&gt;transform&lt;/code&gt; property in CSS - allowing us to rotate, translate, scale, and more all at once. But allowing all of those different transform functions into one property can trip us up.&lt;/p&gt;

&lt;p&gt;It’s common to want to apply different transforms to different states of our elements. Say we have a button that we always want to be translated &lt;code&gt;-150%&lt;/code&gt; vertically. When a user hovers over the button we scale the button down a bit, and on press (the active state) we rotate it 180 degrees. This example shows how one might first think to write the CSS for “My Button” as just described, and then the “Expected” button shows a way to get it as intended.&lt;/p&gt;

&lt;p data-height=&quot;237&quot; data-theme-id=&quot;0&quot; data-slug-hash=&quot;EZBvVV&quot; data-default-tab=&quot;css,result&quot; data-user=&quot;danwilson&quot; data-embed-version=&quot;2&quot; data-pen-title=&quot;Basics with Transform Functions&quot; class=&quot;codepen&quot;&gt;See the Pen &lt;a href=&quot;http://codepen.io/danwilson/pen/EZBvVV/&quot;&gt;Basics with Transform Functions&lt;/a&gt; by Dan Wilson (&lt;a href=&quot;http://codepen.io/danwilson&quot;&gt;@danwilson&lt;/a&gt;) on &lt;a href=&quot;http://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With the initial styles on the button we are not just adding the scale on hover… we are overriding the original translate as well, so it scales &lt;em&gt;and&lt;/em&gt; transitions back to &lt;code&gt;translateY(0)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Why is this? Linear Algebra.  The way these transformations happen depend on each other and their order (such that &lt;code&gt;translate(-50%, -50%) scale(.4) rotate(50deg)&lt;/code&gt; is different than &lt;code&gt;rotate(50deg) translate(-50%, -50%) scale(.4)&lt;/code&gt;), and they boil down to matrix multiplication.  But we usually don’t need to know transforms at that level.  Web developers just want to know how they can maintain these transform functions at an individual level.&lt;/p&gt;

&lt;p data-height=&quot;223&quot; data-theme-id=&quot;0&quot; data-slug-hash=&quot;apgwrO&quot; data-default-tab=&quot;css,result&quot; data-user=&quot;danwilson&quot; data-embed-version=&quot;2&quot; data-pen-title=&quot;Order of  Transform Functions&quot; class=&quot;codepen&quot;&gt;See the Pen &lt;a href=&quot;http://codepen.io/danwilson/pen/apgwrO/&quot;&gt;Order of Transform Functions&lt;/a&gt; by Dan Wilson (&lt;a href=&quot;http://codepen.io/danwilson&quot;&gt;@danwilson&lt;/a&gt;) on &lt;a href=&quot;http://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Chrome has begun implementing individual properties, such that &lt;code&gt;translate&lt;/code&gt;, &lt;code&gt;rotate&lt;/code&gt;, and &lt;code&gt;scale&lt;/code&gt; become first class properties as seen in this previous example (as of this writing requires Chrome Canary). But this has limitations of its own:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The &lt;code&gt;x&lt;/code&gt;, &lt;code&gt;y&lt;/code&gt;, and &lt;code&gt;z&lt;/code&gt; pieces of each are still tied to a single property currently.&lt;/li&gt;
  &lt;li&gt;The order will always be &lt;code&gt;translate scale rotate&lt;/code&gt; when it is converted to matrices.&lt;/li&gt;
  &lt;li&gt;Early days - just in Chrome Canary.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;so-what-can-we-do&quot;&gt;So what can we do?&lt;/h3&gt;

&lt;p&gt;Use CSS Variables.&lt;/p&gt;

&lt;p&gt;Listening to &lt;a href=&quot;https://codepen.io/davidkpiano/&quot;&gt;David Khourshid&lt;/a&gt; talk about CSS Variables quickly opened my eyes to a lot of opportunities for animating with them. It wasn’t until I started putting variables everywhere that their power became even clearer.  Without further ado… here is the trick to give us more flexibility (with the how/what/why after the example).&lt;/p&gt;

&lt;p data-height=&quot;228&quot; data-theme-id=&quot;0&quot; data-slug-hash=&quot;oBrOGW&quot; data-default-tab=&quot;css,result&quot; data-user=&quot;danwilson&quot; data-embed-version=&quot;2&quot; data-pen-title=&quot;CSS Variables + Transform = Individual Properties&quot; class=&quot;codepen&quot;&gt;See the Pen &lt;a href=&quot;https://codepen.io/danwilson/pen/oBrOGW/&quot;&gt;CSS Variables + Transform = Individual Properties&lt;/a&gt; by Dan Wilson (&lt;a href=&quot;http://codepen.io/danwilson&quot;&gt;@danwilson&lt;/a&gt;) on &lt;a href=&quot;http://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We set up a key initial &lt;code&gt;transform&lt;/code&gt; for our element with all the variables we intend to change. By modifying the variable value on the different states we can get a CSS rule that looks closer to our original code but with much more flexibility as the complexity grows.  In this example we are dealing with many more states than the original example’s three by introducing JavaScript (but this is not required: Here is a &lt;a href=&quot;http://codepen.io/danwilson/pen/ggVPVQ&quot;&gt;CSS only version of our original button example&lt;/a&gt;). Still, it effectively is one CSS property defined, and we change only one transform function at a time (whether that be in JS or CSS).&lt;/p&gt;

&lt;p&gt;Without the CSS variables we would have to do some calculations on the current transition when changing one of the transform functions (which may not be trivial). Then we could know where the other two functions are currently to make sure the transition remained smooth. Every time a variable is changed, a new transition occurs in the same way as if you had rewritten the &lt;code&gt;transform&lt;/code&gt; property from scratch, so you still can’t have different transitions for each transform function.&lt;/p&gt;

&lt;h3 id=&quot;how-does-this-compare-to-the-upcoming-individual-properties-in-chrome-canary&quot;&gt;How does this compare to the upcoming individual properties in Chrome Canary?&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;We can do any combination of &lt;code&gt;x&lt;/code&gt;, &lt;code&gt;y&lt;/code&gt;, and &lt;code&gt;z&lt;/code&gt; since we choose how to set up our initial &lt;code&gt;transform&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Similarly, we can even do whatever order of the transform functions we want (though we lose the (likely) less common use case of changing the order around between states).&lt;/li&gt;
  &lt;li&gt;I’ve seen this work well in latest Chrome (56), Firefox (50), and Safari (10.1 on Mac, iOS 10.3) (version 10 supported variables but did not do a smooth transition).  Additionally, the latest Windows 10 (Creators Update) releases April 11, 2017, and its new version of Edge supports CSS Variables, so we will soon see how this works there.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Please &lt;a href=&quot;https://twitter.com/dancwilson&quot;&gt;reach out&lt;/a&gt; if you have some creative uses for this technique.&lt;/p&gt;

</description>
        <pubDate>Tue, 21 Feb 2017 00:00:00 -0600</pubDate>
        <link>http://danielcwilson.com/blog/2017/02/individual-transforms/</link>
        <guid isPermaLink="true">http://danielcwilson.com/blog/2017/02/individual-transforms/</guid>
        
        <category>animations</category>
        
        <category>web</category>
        
        <category>CSS Variables</category>
        
        
      </item>
    
      <item>
        <title>A Different CSS Motion Path</title>
        <description>&lt;p&gt;When I first heard about the Web Animations API a few years ago, the most exciting piece was the promise of support for motion path animations - so that we could move/translate elements along a defined path instead of the linear default.&lt;/p&gt;

&lt;p&gt;SVG has had this for years in most browsers, but the ability to use this with any DOM element brought new possibilities. A lot &lt;a href=&quot;/blog/2015/09/animations-part-5/&quot;&gt;changed after the initial announcement&lt;/a&gt;, and a lot &lt;a href=&quot;https://codepen.io/danwilson/post/css-motion-paths-2016&quot;&gt;more has changed again&lt;/a&gt;, and there are a lot of exciting things to come from this spec. To see some examples of the current spec, see &lt;a href=&quot;http://codepen.io/collection/DjzrGP/&quot;&gt;my demos&lt;/a&gt; and &lt;a href=&quot;http://codepen.io/collection/AQWaem/&quot;&gt;others’ demos&lt;/a&gt; in Chrome 55+ or Opera 42+.&lt;/p&gt;

&lt;p&gt;For now, I want to discuss what I had originally hoped the CSS Motion Path module would be (using CSS + SVG animations to illustrate, since this doesn’t really exist).&lt;/p&gt;

&lt;h3 id=&quot;how-i-imagined-css-motion-path&quot;&gt;How I Imagined CSS Motion Path&lt;/h3&gt;

&lt;p&gt;Instead of defining a path for an element and then animating its offset value to create motion along the path, I feel my ideal CSS Motion Path would tie more into existing transitions/animations.&lt;/p&gt;

&lt;h4 id=&quot;take-a-normal-translate&quot;&gt;Take a normal translate&lt;/h4&gt;

&lt;p&gt;For example, take a basic translation animation with a 2000ms duration with linear easing and an infinite iteration count via &lt;code&gt;transform: translate(25rem, 7.5rem)&lt;/code&gt;:&lt;/p&gt;

&lt;figure id=&quot;standard-translate&quot;&gt;
  &lt;div class=&quot;cssmp-example&quot;&gt;
    &lt;div&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/figure&gt;

&lt;h4 id=&quot;and-a-path-from-svg&quot;&gt;… and a path from SVG&lt;/h4&gt;

&lt;figure&gt;
  &lt;svg viewbox=&quot;0 0 300 100&quot;&gt;
    &lt;path d=&quot;M0,100 C200,0 200,200 300,0&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot; stroke=&quot;#333&quot; stroke-dashoffset=&quot;0&quot; stroke-dasharray=&quot;8&quot; id=&quot;path&quot; /&gt;
    &lt;path d=&quot;M0,100 L 300,0&quot; stroke-width=&quot;2&quot; fill=&quot;none&quot; stroke=&quot;#333&quot; stroke-dashoffset=&quot;0&quot; stroke-dasharray=&quot;8&quot; id=&quot;control-path&quot; /&gt;
  &lt;/svg&gt;
  &lt;figcaption&gt;Path defined by the points &lt;code&gt;&quot;M0,100 C200,0 200,200 300,0&quot;&lt;/code&gt; from a viewBox &lt;code&gt;&quot;0 0 300 100&quot;&lt;/code&gt;&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h4 id=&quot;add-a-property-to-specify-the-path&quot;&gt;Add a property to specify the path&lt;/h4&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;translate-path: path(&quot;M0,100 C200,0 200,200 300,0&quot;)&lt;/code&gt;&lt;/p&gt;

&lt;h4 id=&quot;let-the-browser-map-the-points&quot;&gt;Let the browser map the points&lt;/h4&gt;

&lt;p&gt;This is where I would pass the hard stuff to the browser (and why I understand this is a complicated issue). Assuming this could be achieved well, I’d expect the path to be rotated and scaled such that its start and end points match the start and end points of the translation.&lt;/p&gt;

&lt;p&gt;So with the following CSS:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-css&quot; data-lang=&quot;css&quot;&gt;&lt;span class=&quot;nc&quot;&gt;.circle&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;animation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;go&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;forth&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2000&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ms&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ms&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;infinite&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;linear&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;translate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;M0,100 C200,0 200,200 300,0&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;@keyframes&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;go-forth&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;translate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rem&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We could have the following animation (second dot is the reference of the default translation):&lt;/p&gt;

&lt;figure id=&quot;standard-plus-path&quot;&gt;
  &lt;svg viewbox=&quot;0 0 300 140&quot;&gt;
    &lt;use xlink:href=&quot;#path&quot; /&gt;
    &lt;circle cx=&quot;0&quot; cy=&quot;0&quot; r=&quot;10&quot; fill=&quot;#459cbd&quot;&gt;
      &lt;animatemotion dur=&quot;2000ms&quot; repeatcount=&quot;indefinite&quot;&gt;
        &lt;mpath xlink:href=&quot;#path&quot; /&gt;
      &lt;/animatemotion&gt;
    &lt;/circle&gt;
    &lt;circle cx=&quot;0&quot; cy=&quot;0&quot; r=&quot;10&quot; fill=&quot;#459cbd&quot; class=&quot;cssmp-control&quot;&gt;
      &lt;animatemotion dur=&quot;2000ms&quot; repeatcount=&quot;indefinite&quot;&gt;
        &lt;mpath xlink:href=&quot;#control-path&quot; /&gt;
      &lt;/animatemotion&gt;
    &lt;/circle&gt;
  &lt;/svg&gt;
&lt;/figure&gt;

&lt;p&gt;Then if we only change the start and end points of our translation to be further apart and from the top/right to the bottom/left (with no change to anything related to the path) such as by changing our &lt;code&gt;keyframes&lt;/code&gt; to:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-css&quot; data-lang=&quot;css&quot;&gt;&lt;span class=&quot;k&quot;&gt;@keyframes&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;go-forth&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;translate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;-26&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rem&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;52&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We’d have:&lt;/p&gt;

&lt;figure id=&quot;bigger-plus-path&quot;&gt;
  &lt;svg viewbox=&quot;0 0 300 300&quot;&gt;
    &lt;use xlink:href=&quot;#path&quot; /&gt;
    &lt;circle cx=&quot;0&quot; cy=&quot;0&quot; r=&quot;5&quot; fill=&quot;#459cbd&quot;&gt;
      &lt;animatemotion dur=&quot;2000ms&quot; repeatcount=&quot;indefinite&quot;&gt;
        &lt;mpath xlink:href=&quot;#path&quot; /&gt;
      &lt;/animatemotion&gt;
    &lt;/circle&gt;
    &lt;circle cx=&quot;0&quot; cy=&quot;0&quot; r=&quot;5&quot; fill=&quot;#459cbd&quot; class=&quot;cssmp-control&quot;&gt;
      &lt;animatemotion dur=&quot;2000ms&quot; repeatcount=&quot;indefinite&quot;&gt;
        &lt;mpath xlink:href=&quot;#control-path&quot; /&gt;
      &lt;/animatemotion&gt;
    &lt;/circle&gt;
  &lt;/svg&gt;
&lt;/figure&gt;

&lt;p id=&quot;wrap-up-cssmp&quot;&gt;There are several use cases for the current spec, and in many ways I&#39;m glad it is how it is. There&#39;s still a part of me, though, that finds more value in what I&#39;ve just described.  I will certainly admit that might just be due to habit - being used to animating transforms for the last several years.&lt;/p&gt;
</description>
        <pubDate>Mon, 02 Jan 2017 00:00:00 -0600</pubDate>
        <link>http://danielcwilson.com/blog/2017/01/different-css-motion-path/</link>
        <guid isPermaLink="true">http://danielcwilson.com/blog/2017/01/different-css-motion-path/</guid>
        
        <category>animations</category>
        
        <category>web animations API</category>
        
        <category>motion path</category>
        
        <category>web</category>
        
        
      </item>
    
      <item>
        <title>When to Use the Web Animations API</title>
        <description>&lt;p&gt;Firefox 48 is now available, and with it comes the third browser (after Chrome and Opera) to support an initial feature set of the Web Animations API.  With it, Brian Birtles goes into detail &lt;a href=&quot;https://hacks.mozilla.org/2016/08/animating-like-you-just-dont-care-with-element-animate/&quot;&gt;why this API is a big deal&lt;/a&gt;.  A few people have recently asked me why I talk so much about the API but still use CSS animations a lot of the time… so with Firefox’s official release, here are some thoughts on when using JS might make more sense than CSS.&lt;/p&gt;

&lt;p&gt;But first, a spoiler… I still typically prefer CSS for animating.  You state an animation once, and all matching selectors will pick up on it without you having to iterate through them all.  There’s a reason over time we’ve seen things move from JS to CSS, and for me it’s hard to beat declaring some rules in CSS and calling it a day.&lt;/p&gt;

&lt;h3 id=&quot;so-why-go-with-the-api&quot;&gt;So Why Go with the API?&lt;/h3&gt;

&lt;h4 id=&quot;dynamicrandomnew-values&quot;&gt;Dynamic/Random/New Values&lt;/h4&gt;

&lt;p&gt;One of the main reasons to reach for JavaScript is when values are not static.  For a basic Transition, you can use JS to modify a value to a &lt;code&gt;transition&lt;/code&gt; property dynamically in one line such as &lt;code&gt;element.style.transitionDelay = &#39;123ms&#39;&lt;/code&gt; and that’s fine enough.  However, modifying keyframe values on the fly is much more involved, such as adding a new stylesheet to the document with your new keyframes fully defined.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;frames&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getFramesArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//get your new frames, e.g. [{offset: .5, transform: &amp;#39;scale(1)&amp;#39;}]&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;animation&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;@keyframes updatedAnimation {&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;frames&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;animation&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;offset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;% {transform:&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;transform&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;}&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;animation&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;}&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;style&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;createElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;style&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;appendChild&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;createTextNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;animation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;appendChild&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ele&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;toAnimate&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;ele&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;animationName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;updatedAnimation&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Instead the API can handle this directly, and in one spot.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;frames&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getFramesArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//get your new frames, e.g. [{offset: .5, transform: &amp;#39;&amp;#39;}];&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ele&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;toAnimate&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;ele&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;animate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;frames&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Making randomized &lt;a href=&quot;http://codepen.io/danwilson/pen/vKzbgd&quot;&gt;confetti&lt;/a&gt;, &lt;a href=&quot;http://codepen.io/danwilson/pen/zveqab&quot;&gt;snow&lt;/a&gt;, and &lt;a href=&quot;http://codepen.io/danwilson/pen/oXxKPd&quot;&gt;springy objects&lt;/a&gt; often requires less tinkering when using the API.&lt;/p&gt;

&lt;p data-height=&quot;265&quot; data-theme-id=&quot;0&quot; data-slug-hash=&quot;vKzbgd&quot; data-default-tab=&quot;js,result&quot; data-user=&quot;danwilson&quot; data-embed-version=&quot;2&quot; data-preview=&quot;true&quot; class=&quot;codepen&quot;&gt;See the Pen &lt;a href=&quot;http://codepen.io/danwilson/pen/vKzbgd/&quot;&gt;Confetti&lt;/a&gt; by Dan Wilson (&lt;a href=&quot;http://codepen.io/danwilson&quot;&gt;@danwilson&lt;/a&gt;) on &lt;a href=&quot;http://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For the confetti demo I actually combined both WAAPI and CSS.  I used the WAAPI to generate random scale and horizontal placement values (also duration and negative delays), while animating inner divs with a 3D rotation and a wavering back and forth via CSS.  I could have taken it further and animated everything with random values, but having only the container based on random values (for the primary confetti action of falling to the ground) was enough for it to feel spontaneous.&lt;/p&gt;

&lt;p&gt;And yes, I agree - the phrase “primary confetti action” is one of the least confetti-related phrases a person can say.&lt;/p&gt;

&lt;h4 id=&quot;a-plethora-of-class-toggles&quot;&gt;A Plethora of Class Toggles&lt;/h4&gt;

&lt;p&gt;If you’re already doing a lot of logic to add and remove classes to trigger your CSS transitions or animations, the API might be a good way to go as well. That way all of your logic is in one place instead of two.  Especially, if you are also needing to listen to animation events like &lt;code&gt;animationend&lt;/code&gt; or &lt;code&gt;transitionend&lt;/code&gt;.  That is usually a sign to me that the only reason I’m using CSS is to take advantage of hardware acceleration (which you will get from browsers that support the WAAPI already).&lt;/p&gt;

&lt;p data-height=&quot;265&quot; data-theme-id=&quot;0&quot; data-slug-hash=&quot;755de1ba31b1629e4f662db0818185ac&quot; data-default-tab=&quot;css,result&quot; data-user=&quot;danwilson&quot; data-embed-version=&quot;2&quot; data-editable=&quot;true&quot; class=&quot;codepen&quot;&gt;See the Pen &lt;a href=&quot;http://codepen.io/danwilson/pen/755de1ba31b1629e4f662db0818185ac/&quot;&gt;755de1ba31b1629e4f662db0818185ac&lt;/a&gt; by Dan Wilson (&lt;a href=&quot;http://codepen.io/danwilson&quot;&gt;@danwilson&lt;/a&gt;) on &lt;a href=&quot;http://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/p&gt;

&lt;h4 id=&quot;playback-control&quot;&gt;Playback Control&lt;/h4&gt;

&lt;p&gt;When you want to change the rate or be able to jump to different frames, the API will be the easiest way to do that now.  It’s all technically achievable with CSS now, but you have to take a fair amount of extra care to get timings right.&lt;/p&gt;

&lt;h4 id=&quot;chaining-multiple-animations&quot;&gt;Chaining Multiple Animations&lt;/h4&gt;

&lt;p&gt;Another reason is if you have complex animations that depend on other animations for when to start.  The next level of the spec is introducing formal grouping and sequencing for multiple animations, but even now using the callbacks, &lt;code&gt;delay&lt;/code&gt;, and &lt;code&gt;endDelay&lt;/code&gt;s in the WAAPI can be a lot easier than managing your sequence of animations via &lt;code&gt;delay&lt;/code&gt;s alone in CSS.&lt;/p&gt;

&lt;p&gt;An excellent CSS-Tricks article &lt;a href=&quot;https://css-tricks.com/comparison-animation-technologies/#article-header-id-1&quot;&gt;comparing various animation methods&lt;/a&gt; (by &lt;a href=&quot;http://sarahdrasnerdesign.com/&quot;&gt;Sarah Drasner&lt;/a&gt;) covers the cons for CSS in detail.&lt;/p&gt;

&lt;h3 id=&quot;what-about-some-specifics&quot;&gt;What about Some Specifics&lt;/h3&gt;

&lt;p data-height=&quot;298&quot; data-theme-id=&quot;0&quot; data-slug-hash=&quot;wWZWKW&quot; data-default-tab=&quot;result&quot; data-user=&quot;danwilson&quot; data-embed-version=&quot;2&quot; data-preview=&quot;true&quot; data-editable=&quot;true&quot; class=&quot;codepen&quot;&gt;See the Pen &lt;a href=&quot;http://codepen.io/danwilson/pen/wWZWKW/&quot;&gt;Falling Letters&lt;/a&gt; by Dan Wilson (&lt;a href=&quot;http://codepen.io/danwilson&quot;&gt;@danwilson&lt;/a&gt;) on &lt;a href=&quot;http://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I’ve used the Web Animations in a couple client projects because they were basic enough, but still benefited from the playback rate and timeline control.&lt;/p&gt;

&lt;p&gt;You can also use features like canceling, &lt;code&gt;playbackRate&lt;/code&gt; variance, dynamic elements/values, &lt;code&gt;onfinish&lt;/code&gt; handlers, and more to create a game.  The CodePen version of a game I recently created is shown here, with the full version now at &lt;a href=&quot;https://lettersandsuch.herokuapp.com&quot;&gt;Letters and Such&lt;/a&gt;. Effectively, letters (or other characters) fall, and you have to type the appropraite key before they reach the ground.  Playback Rate is increased over time, letters and locations are randomized, and if the correct key is typed the animation is canceled (and you get a point, to boot).  If the key is not pressed in time, however, the &lt;code&gt;onfinish&lt;/code&gt; handler will be called and a “miss” is counted. The code in the CodePen is commented as far as the logic is concerned, so take a look for more detail.&lt;/p&gt;

&lt;p&gt;There is nothing that would prevent you from making this with CSS animations. It made sense for me to keep the animations primarily in JS, especially since the animations drive a lot of the actual game logic.&lt;/p&gt;

&lt;h3 id=&quot;but-what-about-the-future&quot;&gt;But What about the Future?&lt;/h3&gt;

&lt;p&gt;The Web Animations spec that underlies the Web Animations API is all about uniting JS and CSS methods. Firefox Nightly builds actually allow you to get all Animations on the document via JS, whether generated with the WAAPI, CSS Animations, or CSS Transitions.  Right now some of the properties on CSS ones are read only (no changing of duration, for example), but already you can read/write the currentTime, pause these animations, or change playbackRate.  There will be even less to differentiate the methods beyond personal preference as the spec matures.&lt;/p&gt;
</description>
        <pubDate>Thu, 04 Aug 2016 00:00:00 -0500</pubDate>
        <link>http://danielcwilson.com/blog/2016/08/why-waapi/</link>
        <guid isPermaLink="true">http://danielcwilson.com/blog/2016/08/why-waapi/</guid>
        
        <category>animations</category>
        
        <category>web animations API</category>
        
        <category>web</category>
        
        
      </item>
    
      <item>
        <title>A Mouse, Some Touches, and All Sorts of Pointers</title>
        <description>&lt;p&gt;If you’ve ever tried to support both touch and mouse events on the web you know there is a lot to consider, and you can get tripped up - especially when you accept that it is not an either/or situation.  Pointer Events try to unify different input pointing devices so you don’t have to think as differently for touch and mouse (or a stylus… or anything new that comes like an airtap), while also giving you access to the details that might be unique to each type.&lt;/p&gt;

&lt;p&gt;Pointer Events have been around since 2012 and the introduction of Windows 8 with IE 10.  Having used them when I made Windows apps for the launch of the Windows Store, I’ve been excited about their potential. They abstract enough of the similarities between different pointer types while still providing pressure on a device that allows it.&lt;/p&gt;

&lt;p&gt;With their introduction recently in Chrome 52 behind a flag, they now are on track to be in three stable evergreen browsers (with support already in Edge and Firefox (behind a flag since last August)).  We’ll take a look at how to use them, how to enable the flags, and how to provide a fallback to mouse + touch in other browsers.&lt;/p&gt;

&lt;h3 id=&quot;give-me-the-basics-please&quot;&gt;Give Me the Basics, Please&lt;/h3&gt;

&lt;p&gt;Pointer Events provide a single event for mouse + touch + stylus + other future pointing devices. They have common mappings to Mouse Events, such as if you currently listen to &lt;code&gt;mousedown&lt;/code&gt; you would instead listen to &lt;code&gt;pointerdown&lt;/code&gt;.&lt;/p&gt;

&lt;p data-height=&quot;265&quot; data-theme-id=&quot;0&quot; data-slug-hash=&quot;rLabXy&quot; data-default-tab=&quot;js,result&quot; data-user=&quot;danwilson&quot; data-embed-version=&quot;2&quot; class=&quot;codepen&quot;&gt;See the Pen &lt;a href=&quot;http://codepen.io/danwilson/pen/rLabXy/&quot;&gt;Pointer Event Logging&lt;/a&gt; by Dan Wilson (&lt;a href=&quot;http://codepen.io/danwilson&quot;&gt;@danwilson&lt;/a&gt;) on &lt;a href=&quot;http://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;These events can be triggered: &lt;code&gt;pointerdown&lt;/code&gt;, &lt;code&gt;pointermove&lt;/code&gt;, &lt;code&gt;pointerup&lt;/code&gt;, &lt;code&gt;pointerenter&lt;/code&gt;, &lt;code&gt;pointerleave&lt;/code&gt;, &lt;code&gt;pointerout&lt;/code&gt;, &lt;code&gt;pointerover&lt;/code&gt;, &lt;code&gt;pointercancel&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In addition to the normal event properties (such as &lt;code&gt;pageX&lt;/code&gt;) when an event fires you also are given the following:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code&gt;pointerId&lt;/code&gt;: a unique identifier (Integer) so that you can keep track of the touch with which you are dealing&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;pointerType&lt;/code&gt;: a string such as “mouse” or “touch”&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;pressure&lt;/code&gt;: a number between 0 and 1 for the pressure if the input and device support it (0 represents a hover, and 0.5 will be the default for an input + device that does not support pressure but is pressing)&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;tiltX&lt;/code&gt;: number in degress (from -90 to 90), &lt;a href=&quot;https://www.w3.org/TR/pointerevents/#widl-PointerEvent-tiltX&quot;&gt;visually described in the spec&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;tiltY&lt;/code&gt;: similar to &lt;code&gt;tiltX&lt;/code&gt;, also &lt;a href=&quot;https://www.w3.org/TR/pointerevents/#widl-PointerEvent-tiltY&quot;&gt;visually described in the spec&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;width&lt;/code&gt; and &lt;code&gt;height&lt;/code&gt;: dimensions (in CSS pixels) of the pointer.  This will likely 1x1 for a mouse and something bigger for a touch, but is left to the browser to determine how to report it&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;button&lt;/code&gt; and &lt;code&gt;buttons&lt;/code&gt;: shows which button is changed and all buttons pressed, respectively.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;pointerId&lt;/code&gt; and &lt;code&gt;pointerType&lt;/code&gt; are the two properties that will appear regardless of the capabilities of the pointer.&lt;/p&gt;

&lt;h3 id=&quot;how-do-i-use-this-today&quot;&gt;How Do I Use This Today?&lt;/h3&gt;

&lt;p&gt;There are three pieces you will want to remember when using Pointer Events:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;To check support, see if &lt;code&gt;window.PointerEvent&lt;/code&gt; is present.&lt;/li&gt;
  &lt;li&gt;Listen to events as you would with other devices/input, such as &lt;code&gt;Element.addEventListener(&#39;pointerdown&#39;, function(e) {})&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Set the &lt;code&gt;touch-action&lt;/code&gt; CSS property to &lt;code&gt;none&lt;/code&gt; (or other value than &lt;code&gt;auto&lt;/code&gt;) on the element(s) that you want to receive Pointer Events.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It’s the third point that needs the most explanation. If you do not set this in CSS, your pointer events will fire fine for mouse, but might do nothing on touch (as determined by each browser).  This is because the browser likely already has a lot of touch gestures that perform actions at the browser level, such as scrolling and zooming the viewport.  By setting &lt;code&gt;touch-action: none&lt;/code&gt; you are telling the browser to not perform those browser-level actions on the element and instead trigger Pointer Events. There are &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/touch-action&quot;&gt;other values&lt;/a&gt; that will allow you to continue some browser behaviors and then fire a subset of events.&lt;/p&gt;

&lt;p data-height=&quot;265&quot; data-theme-id=&quot;0&quot; data-slug-hash=&quot;MeYdrv&quot; data-default-tab=&quot;css,result&quot; data-user=&quot;danwilson&quot; data-embed-version=&quot;2&quot; class=&quot;codepen&quot;&gt;See the Pen &lt;a href=&quot;http://codepen.io/danwilson/pen/MeYdrv/&quot;&gt;CSS Touch Action&lt;/a&gt; by Dan Wilson (&lt;a href=&quot;http://codepen.io/danwilson&quot;&gt;@danwilson&lt;/a&gt;) on &lt;a href=&quot;http://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For example, you could still want normal scrolling/panning on a given element, but still want to know when a &lt;code&gt;pointerdown&lt;/code&gt; occurs via a JS event.  In that case you could set &lt;code&gt;touch-action: pan&lt;/code&gt;. You will no longer receive &lt;code&gt;pointermove&lt;/code&gt; events for every finger movement.  You could even limit this to a direction such as &lt;code&gt;touch-action: pan-y&lt;/code&gt;, which will fire &lt;code&gt;pointermove&lt;/code&gt; events for horizontal moves, but perform the default browser behavior for vertical movements (with no JS events sent).&lt;/p&gt;

&lt;p&gt;Edge will not fire any Pointer Events if &lt;code&gt;touch-action&lt;/code&gt; is &lt;code&gt;auto&lt;/code&gt;, while Chrome and Firefox both currently treat &lt;code&gt;auto&lt;/code&gt; similar to &lt;code&gt;pan&lt;/code&gt;. So it is best to know and specify what you want for consistency between browsers.&lt;/p&gt;

&lt;p&gt;&lt;a id=&quot;how-to-enable&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As of today, you can explore their uses in the following browsers&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Edge (and IE 11 (and IE10 with a prefix)): Supported&lt;/li&gt;
  &lt;li&gt;Firefox (41+): Enable the &lt;code&gt;dom.w3c_pointer_events.enabled&lt;/code&gt; and &lt;code&gt;layout.css.touch_action.enabled&lt;/code&gt; flags in &lt;code&gt;about:config&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Chrome (52+): Enable the &lt;code&gt;Pointer Events&lt;/code&gt; flag at &lt;code&gt;chrome://flags/#enable-pointer-events&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The fullest representation is Edge.  In my testing Chrome and Firefox work well with a mouse or single touch point already, but have issues to resolve with multitouch.&lt;/p&gt;

&lt;h3 id=&quot;what-about-fallbacks&quot;&gt;What about Fallbacks?&lt;/h3&gt;

&lt;p&gt;Almost everything in Pointer Events has a fallback either through Mouse Events or Touch Events.  For example, Touch Events have an &lt;code&gt;identifier&lt;/code&gt; that acts like &lt;code&gt;pointerId&lt;/code&gt; and &lt;code&gt;force&lt;/code&gt; which is similar to &lt;code&gt;pressure&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I’ve not seen an equivalent for &lt;code&gt;tilt*&lt;/code&gt;, so pen support will lack angles without Pointer Events.  Though, it’s important to note &lt;code&gt;tilt&lt;/code&gt; is only reported on a subset of pens (even the Surface Pro 4 pen does not support it in Edge).&lt;/p&gt;

&lt;p&gt;We can use our support check to provide fallbacks&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;PointerEvent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//register event listeners for Pointer Events&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//register for mouse and touch&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here is a full demo with multitouch and fallbacks. Press and the circles will surround your pointer. Release and they will fade away. If your pointer and device support it, more pressure/force will make the circles grow larger. 3D transforms occur when tilt values are detected.&lt;/p&gt;

&lt;p data-height=&quot;265&quot; data-theme-id=&quot;0&quot; data-slug-hash=&quot;LZpVpe&quot; data-default-tab=&quot;js,result&quot; data-user=&quot;danwilson&quot; data-embed-version=&quot;2&quot; data-preview=&quot;true&quot; class=&quot;codepen&quot;&gt;See the Pen &lt;a href=&quot;http://codepen.io/danwilson/pen/LZpVpe/&quot;&gt;Press &amp;amp; Hold&lt;/a&gt; by Dan Wilson (&lt;a href=&quot;http://codepen.io/danwilson&quot;&gt;@danwilson&lt;/a&gt;) on &lt;a href=&quot;http://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The caveats for this demo are the flagged releases of Chrome and Firefox. The Pointer events work well for mouse, pen, and a single touch point.  When multiple touch points occur in Chrome and Firefox currently (flagged versions 52 and 48, respectively), it cannot keep up.  Both browsers have work left before they become unflagged, and you can follow the status/bugs for both &lt;a href=&quot;https://www.chromestatus.com/feature/4504699138998272&quot;&gt;Chrome&lt;/a&gt; and &lt;a href=&quot;https://platform-status.mozilla.org/#pointer-events&quot;&gt;Firefox&lt;/a&gt; for updates.&lt;/p&gt;
</description>
        <pubDate>Tue, 14 Jun 2016 00:00:00 -0500</pubDate>
        <link>http://danielcwilson.com/blog/2016/06/pointer-events/</link>
        <guid isPermaLink="true">http://danielcwilson.com/blog/2016/06/pointer-events/</guid>
        
        <category>web</category>
        
        <category>mobile</category>
        
        <category>windows</category>
        
        
      </item>
    
      <item>
        <title>Promises in Web Animations</title>
        <description>&lt;p&gt;When I first started learning about the Web Animations API there was one way to handle a “finish” event - the &lt;code&gt;onfinish&lt;/code&gt; callback.  It lets you assign it a function and that function is called when the animation is finished.&lt;/p&gt;

&lt;p&gt;There is a newer way to handle this scenario, though… via the &lt;code&gt;finished&lt;/code&gt; Promise.  This either excites you (if you know what a Promise is), confuses you (if you know what a Promise is), or makes you ask what a Promise is. So…&lt;/p&gt;

&lt;h3 id=&quot;what-is-a-promise&quot;&gt;What is a Promise?&lt;/h3&gt;

&lt;p&gt;Promises have gone through several specs and implementations.  A standardized version has found its way into &lt;a href=&quot;http://caniuse.com/#feat=promises&quot;&gt;most browsers&lt;/a&gt; with Edge, Firefox, Safari, Chrome, and Opera’s latest all supporting Promises.  They are a feature in JavaScript similar to a callback in that they look for some code to finish running and then run some other code. With callbacks we often think of success and error handlers… with Promises we think of resolving and rejecting, such as:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;c1&quot;&gt;//set up 1 second animation to fade box out&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;box&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;box&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;animation&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;box&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;animate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;opacity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;opacity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}],&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;finishedHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; 
  &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;animation finished: &amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;canceledHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; 
  &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;animation canceled: &amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;//the Promise version, log the timestamp when the Animation finishes&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;animation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;finished&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;finishedHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;canceledHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;//the effective successful equivalent with the onfinish callback&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;animation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;onfinish&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;finishedHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This code starts an animation (by calling &lt;code&gt;animate()&lt;/code&gt; on an element), and any other code will continue to execute while we wait for the animation to enter the “finished” state. Animations will expose a &lt;code&gt;finished&lt;/code&gt; Promise that will “resolve” when the animation finishes.  You can think of the Promise as a future object.  When it resolves (in this case, a successful finish of the animation), the first function passed into the &lt;code&gt;then&lt;/code&gt; will run. If the animation is rejected (the animation is canceled), it will run the second function passed to &lt;code&gt;then&lt;/code&gt;, if specified.&lt;/p&gt;

&lt;p&gt;For rejection, the current spec defines it this way, but there are &lt;a href=&quot;https://github.com/w3c/web-animations/issues/141&quot;&gt;discussions to change&lt;/a&gt; away from this.  We will focus on how to work with an animation that resolves for now…&lt;/p&gt;

&lt;h3 id=&quot;one-time-fits-all&quot;&gt;One time fits all&lt;/h3&gt;

&lt;p&gt;Promises by definition will either resolve or be rejected, and this resolution will only happen once. As soon as a Promise is resolved or rejected, it will not resolve nor reject again. Since animations can be played multiple times, this seems to be at odds with the Web animations API as subsequent finishes would not resolve again.&lt;/p&gt;

&lt;p&gt;To solve this, the spec dictates a new Promise will replace the existing &lt;code&gt;finished&lt;/code&gt; Promise when the play state changes to “running”. This allows you to latch on to the Promise resolution state again, but you will have to add your handlers via &lt;code&gt;then&lt;/code&gt; again.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;c1&quot;&gt;//extending the previous example, play the animation second time&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;animation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;play&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;//set &amp;#39;then&amp;#39; to what spec states will be a newly created Promise&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;animation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;finished&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;finishedHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;//the onfinish from before remains&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Note: As of March 18, 2016 the polyfill has an &lt;a href=&quot;https://github.com/web-animations/web-animations-js/issues/62&quot;&gt;issue with resolving subsequent finished Promises&lt;/a&gt; at the correct time.&lt;/em&gt;&lt;/p&gt;

&lt;h3 id=&quot;then-why-bother&quot;&gt;Then Why Bother?&lt;/h3&gt;

&lt;p&gt;Imagine a case where you want to trigger new animations when a given animation finishes. The following example shows two boxes, one using &lt;code&gt;onfinish&lt;/code&gt; to start new animations and the second using the &lt;code&gt;finished&lt;/code&gt; Promise.&lt;/p&gt;

&lt;p data-height=&quot;200&quot; data-theme-id=&quot;0&quot; data-slug-hash=&quot;wGgXbB&quot; data-default-tab=&quot;result&quot; data-user=&quot;danwilson&quot; class=&quot;codepen&quot;&gt;See the Pen &lt;a href=&quot;http://codepen.io/danwilson/pen/wGgXbB/&quot;&gt;Callbacks vs. Promises with Web Animations API&lt;/a&gt; by Dan Wilson (&lt;a href=&quot;http://codepen.io/danwilson&quot;&gt;@danwilson&lt;/a&gt;) on &lt;a href=&quot;http://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Callbacks will nest, and Promises can chain by returning a Promise. For this example it reads differently, and one might be more readable than the other to you. In fuller development the chaining can provide more power with how you manage your animation states and values. We will look into that in a future post.&lt;/p&gt;

&lt;p&gt;There is a lot more to talk about with Promises… for much fuller discussions on Promises check out the &lt;a href=&quot;https://ponyfoo.com/articles/es6-promises-in-depth&quot;&gt;Ponyfoo&lt;/a&gt; article on the topic and the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise&quot;&gt;MDN&lt;/a&gt; article, especially their &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#See_also&quot;&gt;suggested reading&lt;/a&gt;.&lt;/p&gt;

&lt;p class=&quot;postamble&quot;&gt;Thanks to &lt;a href=&quot;https://twitter.com/rachelnabors&quot;&gt;Rachel&lt;/a&gt; for triggering this discussion and &lt;a href=&quot;https://twitter.com/simevidas&quot;&gt;Šime&lt;/a&gt; for pointing me to when an animation is rejected in the spec (and &lt;a href=&quot;https://twitter.com/jaffathecake/status/711852704654471169&quot;&gt;Jake&lt;/a&gt; for mentioning the discussion about changing that). Thanks also to &lt;a href=&quot;https://twitter.com/Nexii&quot;&gt;Martin&lt;/a&gt; for recommending additional Promise articles.&lt;/p&gt;
</description>
        <pubDate>Fri, 18 Mar 2016 00:00:00 -0500</pubDate>
        <link>http://danielcwilson.com/blog/2016/03/animations-and-promises/</link>
        <guid isPermaLink="true">http://danielcwilson.com/blog/2016/03/animations-and-promises/</guid>
        
        <category>web</category>
        
        <category>animations</category>
        
        <category>web animations API</category>
        
        
      </item>
    
      <item>
        <title>Of Layouts with Columns</title>
        <description>&lt;p class=&quot;preamble&quot;&gt;I&#39;ve been wanting to try this alternate large-screen layout out for a while, but there were quirks (more on those later) I hadn&#39;t resolved so I waited.  Now that I (potentially) have resolved the issues I&#39;m just going to flip the switch and see how these columns work out!&lt;/p&gt;

&lt;p&gt;Mobile is always where I first read something, but I know that especially in the tech industry we still read on large monitors while working.  It’s weird that we have these large monitors but we still set &lt;code&gt;max-width&lt;/code&gt;s on our content and force the user down a page.  So… I’m trying out columns on my articles when you have a large and wide screen.  Full width and horizontal scrolling - why not?&lt;/p&gt;

&lt;p&gt;Columns, grid layouts, and other new methods for laying out pages have been emerging the last few years.  I’ll quickly admit I have not done user research or anything to validate what I’m trying here… it’s simply my current exploration as to what we can try.  Hopefully it works well for you, and if it doesn’t I’d love to hear thoughts on why.&lt;/p&gt;

&lt;h3 id=&quot;so-how-does-it-work&quot;&gt;So How Does it Work?&lt;/h3&gt;

&lt;p&gt;Initially I’m rolling this out to what I (somewhat arbitrarily) deem a large enough viewport (1600x900), via the following media query:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-css&quot; data-lang=&quot;css&quot;&gt;&lt;span class=&quot;k&quot;&gt;@media&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;screen&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;min-width&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;100em&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;min-height&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;56&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;.25em&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;/* ... */&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I also look to see support in browsers.  The following should support all browsers that support &lt;code&gt;CSS.supports&lt;/code&gt; and &lt;code&gt;column&lt;/code&gt; (as well as IE 10 and 11 that have unprefixed &lt;code&gt;column&lt;/code&gt; support but lack &lt;code&gt;CSS.supports&lt;/code&gt;):&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;CSS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;CSS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;supports&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;CSS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;supports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;column-width&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;1px&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;CSS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;supports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;-webkit-column-width&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;1px&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;CSS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;supports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;-moz-column-width&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;1px&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;columnWidth&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;documentElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;classList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;columns&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then I do some width/padding/position updates to the body and containers to prepare them for being a page with height 100vh and scrolling horizontally, as well as adding the column properties to my &lt;code&gt;article&lt;/code&gt;.  There are also rules set up to try to prevent breaking before a paragraph that follows a heading:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-css&quot; data-lang=&quot;css&quot;&gt;&lt;span class=&quot;nc&quot;&gt;.columns&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;article&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;/* also include -moz and -webkit */&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;column&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;58&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;column&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vh&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;/* take full height less the header and footer */&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;.columns&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;h3&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;after&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;avoid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;/* not well supported outside IE/Edge */&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&quot;what-were-the-quirks&quot;&gt;What Were the Quirks?&lt;/h3&gt;

&lt;p&gt;I had planned to roll this out when I reworked my site a half year ago, but that was when I started using a lot of CodePens in my articles.  Columns do not respond well to changes to content once they have rendered (in the case of CodePen a link changes to a module with a different height and different &lt;code&gt;break&lt;/code&gt; rules).  If the length of your content changes after the column is painted the browsers are not responding to that change, and you will potentially have your last column(s) chopped.&lt;/p&gt;

&lt;p&gt;I’d known about this issue since I first tried columns a few years ago… but I still forget about it. I have now learned that both browser resizes and changes to the &lt;code&gt;column&lt;/code&gt; properties will cause the browser to repaint, so my current solution is to load the CodePen script and attach an &lt;code&gt;onload&lt;/code&gt; event listener.  That is still to soon to act, so for now I am resorting to a setTimeout to make it work (in my case a change to the &lt;code&gt;column-gap&lt;/code&gt; by .1rem does the trick).&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;onCodePenLoad&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;setTimeout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;article&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;.post-content&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;article&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;classList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;external-loaded&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//this class just changes the column-gap values by .1rem&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;createElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;script&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;text/javascript&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;cp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;src&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;//assets.codepen.io/assets/embed/ei.js&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;cp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;onload&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;onCodePenLoad&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getElementsByTagName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;script&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;parentNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;insertBefore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;cp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;})();&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&quot;other-layouts&quot;&gt;Other Layouts&lt;/h3&gt;

&lt;p&gt;There are many people talking about alternative screen layouts and the new CSS that is here and coming to help us.  I highly recommend &lt;a href=&quot;http://csslayout.news/&quot;&gt;CSS Layout Weekly&lt;/a&gt; from Rachel Andrew and catching up on podcasts and talks from Jen Simmons of &lt;a href=&quot;http://thewebahead.net/&quot;&gt;The Web Ahead&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Should be a fun time ahead on the web.&lt;/p&gt;

</description>
        <pubDate>Fri, 04 Dec 2015 00:00:00 -0600</pubDate>
        <link>http://danielcwilson.com/blog/2015/12/columns/</link>
        <guid isPermaLink="true">http://danielcwilson.com/blog/2015/12/columns/</guid>
        
        <category>web</category>
        
        <category>responsive-web</category>
        
        
      </item>
    
      <item>
        <title>Web Animations API Tutorial Conclusion</title>
        <description>&lt;p class=&quot;preamble&quot;&gt;This is the conclusion to an &lt;a href=&quot;/tags/web-animations-api&quot;&gt;introductory/tutorial series on the Web Animations API&lt;/a&gt; coming to browsers. I&#39;ve updated the series content in June 2016, as Chrome and Firefox have both rolled out major updates (and some small spec changes).  If you have thoughts/questions or see that I’ve misinterpreted the spec, please reach out to me on Twitter, &lt;a href=&quot;https://twitter.com/dancwilson&quot;&gt;@dancwilson&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We’ve covered a fair amount of ground and hopefully cleared up questions about what the Web Animations API is (and is not). To conclude this series, we’ll recap what we’ve discussed and take a look at what has yet to be implemented.&lt;/p&gt;

&lt;h3 id=&quot;why-bother-with-the-api&quot;&gt;Why Bother with the API?&lt;/h3&gt;

&lt;p&gt;In the &lt;a href=&quot;/blog/2015/07/animations-intro/&quot;&gt;introduction&lt;/a&gt; we discussed how the API came into being as a way to unite the various methods to animate in CSS, JS, and SVG… with the intent to take the best of them all.  This means, for example, JavaScript can latch on to the hardware acceleration that CSS has had for years, and you are not limited to the declarative nature of CSS.  The API is not meant to replace libraries like &lt;a href=&quot;http://greensock.com/&quot;&gt;GSAP&lt;/a&gt;, but simply to provide more options at the browser level.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://birtles.github.io/areweanimatedyet/&quot;&gt;Firefox&lt;/a&gt; and &lt;a href=&quot;https://www.chromestatus.com/features#animations&quot;&gt;Chrome&lt;/a&gt; have both started implementations, and Edge has it &lt;a href=&quot;https://dev.modern.ie/platform/status/webanimationsjavascriptapi/&quot;&gt;on its backlog&lt;/a&gt;.  The &lt;a href=&quot;https://github.com/web-animations/web-animations-js&quot;&gt;polyfill&lt;/a&gt; allows us to start playing with it today as the team finalizes the &lt;a href=&quot;https://w3c.github.io/web-animations/&quot;&gt;specification&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;animation-basics&quot;&gt;Animation Basics&lt;/h3&gt;

&lt;p&gt;To &lt;a href=&quot;/blog/2015/07/animations-part-1/&quot;&gt;create a basic animation&lt;/a&gt;, we follow a structure similar to CSS by providing keyframes and timing properties.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;player&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;toAnimate&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;animate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;scale(1)&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;opacity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;offset&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;scale(.6)&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;opacity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;offset&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;duration&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;700&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;/blog/2015/07/animations-part-2/&quot;&gt;Timeline controls&lt;/a&gt; are the obvious pieces not currently present in CSS. Reading the state of an animation happens via the &lt;code&gt;playState&lt;/code&gt; property, and changing the state is via methods such as &lt;code&gt;play()&lt;/code&gt;, &lt;code&gt;pause()&lt;/code&gt;, and &lt;code&gt;finish()&lt;/code&gt;.  We can also change the playback rate to be slower or faster with the read/write &lt;code&gt;playbackRate&lt;/code&gt; property.  The &lt;code&gt;currentTime&lt;/code&gt; can be checked (or changed), and we can set a callback for when the animation finishes with &lt;code&gt;onfinish&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;multiple-animations-and-grouping&quot;&gt;Multiple Animations and Grouping&lt;/h3&gt;

&lt;p&gt;The Web Animations API allows for &lt;a href=&quot;/blog/2015/08/animations-part-3&quot;&gt;multiple animations on an element&lt;/a&gt;, creating separate animation objects. The default timeline on the &lt;code&gt;document&lt;/code&gt; gives us access to all animations created with the &lt;code&gt;getAnimations()&lt;/code&gt; method. Animations can be grouped to play together or one after the other by &lt;a href=&quot;/blog/2015/09/animations-part-4&quot;&gt;using GroupEffects and SequenceEffects&lt;/a&gt; (available in the polyfill but not in the first spec).&lt;/p&gt;

&lt;h3 id=&quot;motion-path-and-the-future&quot;&gt;Motion Path and the Future&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;/blog/2015/09/animations-part-5&quot;&gt;Animating along a path&lt;/a&gt; sneakily saw its first implementation in CSS during this series, but there are many other pieces yet to come.&lt;/p&gt;

&lt;h4 id=&quot;spacing&quot;&gt;Spacing&lt;/h4&gt;

&lt;p&gt;The current implementations use a default spacing if no &lt;code&gt;offset&lt;/code&gt;s are set in the keyframes, meaning they are evenly distributed (e.g. three frames will have offsets of 0, .5, and 1).  The specification also defines a way to pace the animation based on a property, so that it has a constant rate of change.  The spec describes this well when discussing &lt;a href=&quot;http://w3c.github.io/web-animations/#spacing-keyframes&quot;&gt;Spacing Keyframes&lt;/a&gt;.&lt;/p&gt;

&lt;h4 id=&quot;promises&quot;&gt;Promises&lt;/h4&gt;

&lt;p&gt;The spec has evolved to include a &lt;code&gt;ready&lt;/code&gt; Promise that will be replaced with a new Promise every time the animation is cancelled or enters a pending state (which will typically happen before changing to “running” or “paused”).  In addition to using the &lt;code&gt;onfinish&lt;/code&gt; callback as we have discussed in this series, we will be able to use the &lt;code&gt;finished&lt;/code&gt; Promise to run a function after an animation finishes.&lt;/p&gt;

&lt;h3 id=&quot;lets-keep-talking-about-the-web-animations-api&quot;&gt;Let’s Keep Talking about the Web Animations API&lt;/h3&gt;

&lt;p&gt;People are starting to talk more about this API, and I hope this conversation continues. The spec, browser implementations, and polyfill have been going on for a while, and they are ready to examine closely.&lt;/p&gt;

&lt;p&gt;Sometimes CSS will make the most sense, sometimes &lt;code&gt;requestAnimationFrame&lt;/code&gt; will, and sometimes using a library will be the best solution.  It’s good to know when to use what, and this API provides quite a few things that were not previously available to us by default… so have fun.&lt;/p&gt;

&lt;p&gt;Check out the rest of this series:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;/blog/2015/07/animations-intro&quot;&gt;Introduction&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/blog/2015/07/animations-part-1&quot;&gt;Part 1: Creating a Basic Animation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/blog/2015/07/animations-part-2&quot;&gt;Part 2: The Animation and Timeline Controls&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/blog/2015/08/animations-part-3&quot;&gt;Part 3: Multiple Animations&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/blog/2015/09/animations-part-4&quot;&gt;Part 4: GroupEffects and SequenceEffects&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/blog/2015/09/animations-part-5&quot;&gt;Part 5: Motion Paths&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Mon, 14 Sep 2015 00:00:00 -0500</pubDate>
        <link>http://danielcwilson.com/blog/2015/09/animations-conclusion/</link>
        <guid isPermaLink="true">http://danielcwilson.com/blog/2015/09/animations-conclusion/</guid>
        
        <category>animations</category>
        
        <category>web animations API</category>
        
        <category>web</category>
        
        
      </item>
    
      <item>
        <title>Web Animations API Tutorial Part 5: The Loveable Motion Path</title>
        <description>&lt;p class=&quot;preamble&quot;&gt;This is Part 5 of an &lt;a href=&quot;/tags/web-animations-api&quot;&gt;introductory/tutorial series on the Web Animations API&lt;/a&gt; coming to browsers. I&#39;ve updated the series content in June 2016, as Chrome and Firefox have both rolled out major updates (and some small spec changes).  If you have thoughts/questions or see that I’ve misinterpreted the spec, please reach out to me on Twitter, &lt;a href=&quot;https://twitter.com/dancwilson&quot;&gt;@dancwilson&lt;/a&gt;. An earlier (and slimmer) version of this one article appeared on my &lt;a href=&quot;https://codepen.io/danwilson/blog/css-motion-paths&quot;&gt;CodePen Blog&lt;/a&gt; shortly after Chrome announced its flagged Motion Path support.&lt;/p&gt;

&lt;p&gt;Finally. Animating along a path… no longer just the domain of SVG.&lt;/p&gt;

&lt;h3 id=&quot;motion-path-current-direction-of-the-spec&quot;&gt;Motion Path: Current Direction (of the Spec)&lt;/h3&gt;

&lt;p data-height=&quot;145&quot; data-theme-id=&quot;0&quot; data-slug-hash=&quot;MwLmby&quot; data-default-tab=&quot;result&quot; data-user=&quot;danwilson&quot; class=&quot;codepen&quot;&gt;See the Pen &lt;a href=&quot;http://codepen.io/danwilson/pen/MwLmby/&quot;&gt;Motion Path Infinity&lt;/a&gt; by Dan Wilson (&lt;a href=&quot;http://codepen.io/danwilson&quot;&gt;@danwilson&lt;/a&gt;) on &lt;a href=&quot;http://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As the API specification has been worked through, motion path has appeared in different forms.  One direction that initially seemed likely was the form of an &lt;a href=&quot;https://github.com/w3c/web-animations/commit/e0e116e31960033beccc67b9a5047cfcb0b0f92a&quot;&gt;Effect&lt;/a&gt; (like the &lt;a href=&quot;/blog/2015/09/animations-part-4&quot;&gt;previously discussed GroupEffect&lt;/a&gt;), but then a little bit of steam picked up with Motion Path as a CSS Module (with &lt;a href=&quot;http://www.w3.org/TR/motion-1/&quot;&gt;its own spec&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Therefore animating along a path will simply be another set of CSS properties that can be animated, just as &lt;code&gt;opacity&lt;/code&gt; and &lt;code&gt;tranform&lt;/code&gt; can.  This way CSS Transitions and Keyframes can use it as well as the Web Animations API… which is great since we want as much as we can shared between these methods to give us more flexibility.  Chrome and Opera have released an initial implementation, so we can actually start playing with it today even though it has not found its way to any polyfill.&lt;/p&gt;

&lt;p&gt;Let’s break down what these properties are, how we can use them, and what things might still trip us up for now.&lt;/p&gt;

&lt;h3 id=&quot;motion-path-properties&quot;&gt;Motion Path Properties&lt;/h3&gt;

&lt;p&gt;There are three &lt;code&gt;motion&lt;/code&gt; properties we will discuss. For now, to see the examples you will need to be running Chrome 46 or Opera 33.&lt;/p&gt;

&lt;h4 id=&quot;motion-path&quot;&gt;&lt;code&gt;motion-path&lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;The starting point is &lt;code&gt;motion-path&lt;/code&gt; which defines a path along which the element can move, following how paths work in SVG 1.1:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-css&quot; data-lang=&quot;css&quot;&gt;&lt;span class=&quot;nf&quot;&gt;#motioner&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;motion&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;M200 200 S 200.5 200.1 348.7 184.4z&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This can also take a &lt;code&gt;fill-rule&lt;/code&gt; as an optional first parameter in the path call.  I recommend reading &lt;a href=&quot;http://svgpocketguide.com/book/#section-4&quot;&gt;Joni Trythall’s excellent Pocket Guide to Writing SVG&lt;/a&gt; for a discussion on what this entails.&lt;/p&gt;

&lt;p&gt;According to the spec, you can also use a basic shape such as &lt;code&gt;circle&lt;/code&gt;, &lt;code&gt;polygon&lt;/code&gt;, &lt;code&gt;ellipse&lt;/code&gt;, and &lt;code&gt;inset&lt;/code&gt;.  These should look familiar to you if you have tried using &lt;a href=&quot;http://alistapart.com/article/css-shapes-101&quot;&gt;CSS Shapes&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With Blink’s initial implementation, I’ve only seen the &lt;code&gt;path()&lt;/code&gt; method work, so either I’ve been using shapes incorrectly or that is yet to come.&lt;/p&gt;

&lt;h4 id=&quot;motion-offset&quot;&gt;&lt;code&gt;motion-offset&lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;To drive the motion and actually place the element somewhere on the path we use &lt;code&gt;motion-offset&lt;/code&gt;. This can either be a double length value or a percentage.  So to animate from the starting point of the path to the end we set up an animation that goes from 0 to 100%.  With the Web Animations API we have&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;motioner&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;animate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;motionOffset&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;motionOffset&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;100%&amp;#39;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And with CSS&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-css&quot; data-lang=&quot;css&quot;&gt;&lt;span class=&quot;nf&quot;&gt;#motioner&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;animation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;animation&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;@keyframes&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;path-animation&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; 
    &lt;span class=&quot;n&quot;&gt;motion&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;offset&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; 
    &lt;span class=&quot;n&quot;&gt;motion&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;offset&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;100%&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p data-height=&quot;425&quot; data-theme-id=&quot;0&quot; data-slug-hash=&quot;ZGmeRO&quot; data-default-tab=&quot;result&quot; data-user=&quot;danwilson&quot; class=&quot;codepen&quot;&gt;See the Pen &lt;a href=&quot;http://codepen.io/danwilson/pen/ZGmeRO/&quot;&gt;CSS Motion Path Spiral&lt;/a&gt; by Dan Wilson (&lt;a href=&quot;http://codepen.io/danwilson&quot;&gt;@danwilson&lt;/a&gt;) on &lt;a href=&quot;http://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This CodePen demo shows several dots moving along a spiral path from the outside to the inside.  As each dot approaches the center it gets faster, smaller, and becomes transparent.  &lt;code&gt;.animate()&lt;/code&gt; is called twice on each dot with inifinite iterations and a delay, where one call focuses on the motion offset and the other focuses on the scaling and opacity.  I broke them out to specify different easings, but they certainly could have been combined.&lt;/p&gt;

&lt;p&gt;This approach also uses feature detection, which you will notice if you are viewing this in Safari, Firefox, Edge, or an older Chrome/Opera because you will see a message instead of the animation. There a few ways to do this, such as&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;motioner&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;motionOffset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Of course, we wouldn’t want to block out users completely in a real &lt;a href=&quot;https://adactio.com/journal/6246&quot;&gt;web thang&lt;/a&gt;, so we can have an alternate animation (or no animation) that switches to the Motion Path animation if supported. Progressive Enhancement is a friend here, as usual.&lt;/p&gt;

&lt;h4 id=&quot;motion-rotation&quot;&gt;&lt;code&gt;motion-rotation&lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;The final property is &lt;code&gt;motion-rotation&lt;/code&gt;, and it deals with which direction the element “faces” as it moves along the path. There are four primary ways to specify this.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The value “auto” means the element will rotate with the path.&lt;/li&gt;
  &lt;li&gt;With the value “reverse” the element will also rotate with the path, but it will add 180 degress, so it will be facing backward.&lt;/li&gt;
  &lt;li&gt;“auto Xdeg” (or “reverse Xdeg”) will do the same except add X degrees&lt;/li&gt;
  &lt;li&gt;“Xdeg” will no longer rotate with the path, the element will stay fixed facing the same direction.&lt;/li&gt;
&lt;/ul&gt;

&lt;p data-height=&quot;350&quot; data-theme-id=&quot;0&quot; data-slug-hash=&quot;qdLQjz&quot; data-default-tab=&quot;result&quot; data-user=&quot;danwilson&quot; class=&quot;codepen&quot;&gt;See the Pen &lt;a href=&quot;http://codepen.io/danwilson/pen/qdLQjz/&quot;&gt;CSS MotionPath&lt;/a&gt; by Dan Wilson (&lt;a href=&quot;http://codepen.io/danwilson&quot;&gt;@danwilson&lt;/a&gt;) on &lt;a href=&quot;http://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;whats-missing&quot;&gt;What’s Missing?&lt;/h3&gt;

&lt;p&gt;This is a first version, of course, and the browser makers and spec writers are still discussing it all. The biggest thing I have noticed while trying this out was the lack of a way to adapt the path to different screen/container sizes.&lt;/p&gt;

&lt;p&gt;Paths simply appear as they are defined. When working with SVG we get flexibility because we have different coordinate systems and attributes on the container like &lt;a href=&quot;http://sarasoueidan.com/blog/svg-coordinate-systems/#svg-viewbox&quot;&gt;viewBox&lt;/a&gt;.  With Motion Paths defined in CSS, the size of the path cannot be additionally modified or constrained with other properties. The width and height defined on your element apply only to the element, not its motion path. You could use media queries or JavaScript to define different paths for different criteria, but setting it up with flexibility via the &lt;code&gt;motion&lt;/code&gt; properties is not possible yet.&lt;/p&gt;

&lt;h3 id=&quot;wrap-up-and-next-time&quot;&gt;Wrap Up and Next Time&lt;/h3&gt;

&lt;p&gt;We will see the direction the specification takes, but for now it’s fun to try this out and see what it might provide (and not provide).  I’m gathering a &lt;a href=&quot;http://codepen.io/collection/AQWaem&quot;&gt;collection of CSS Motion Path demos&lt;/a&gt; I find on CodePen, and Eric Willigers (owner of this implementation task on the Chrome development team) has a &lt;a href=&quot;https://docs.google.com/document/d/15nn0tc9meyahzSBAauYtIUpGFsuHaieZt403k1v9B90/edit&quot;&gt;Google Doc with examples&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We will wrap up this series next time by recapping what we have discussed and taking a look at a few currently-only-in-the-spec topics.&lt;/p&gt;

&lt;p&gt;Check out the rest of this series:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;/blog/2015/07/animations-intro&quot;&gt;Introduction&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/blog/2015/07/animations-part-1&quot;&gt;Part 1: Creating a Basic Animation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/blog/2015/07/animations-part-2&quot;&gt;Part 2: The Animation and Timeline Controls&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/blog/2015/08/animations-part-3&quot;&gt;Part 3: Multiple Animations&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/blog/2015/09/animations-part-4&quot;&gt;Part 4: GroupEffects and SequenceEffects&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/blog/2015/09/animations-conclusion&quot;&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Tue, 08 Sep 2015 00:00:00 -0500</pubDate>
        <link>http://danielcwilson.com/blog/2015/09/animations-part-5/</link>
        <guid isPermaLink="true">http://danielcwilson.com/blog/2015/09/animations-part-5/</guid>
        
        <category>animations</category>
        
        <category>web animations API</category>
        
        <category>motion path</category>
        
        <category>web</category>
        
        
      </item>
    
      <item>
        <title>Web Animations API Tutorial Part 4: GroupEffects &amp;amp; SequenceEffects</title>
        <description>&lt;p class=&quot;preamble&quot;&gt;This is Part 4 of an &lt;a href=&quot;/tags/web-animations-api&quot;&gt;introductory/tutorial series on the Web Animations API&lt;/a&gt; coming to browsers. I&#39;ve updated the series content in June 2016, as Chrome and Firefox have both rolled out major updates (and some small spec changes).  If you have thoughts/questions or see that I’ve misinterpreted the spec, please reach out to me on Twitter, &lt;a href=&quot;https://twitter.com/dancwilson&quot;&gt;@dancwilson&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let’s continue our discussion on &lt;a href=&quot;/blog/2015/08/animations-part-3&quot;&gt;multiple animations&lt;/a&gt; within the Web Animations API by discussing a few pieces available today in the polyfill to provide grouping and sequencing.&lt;/p&gt;

&lt;h3 id=&quot;keyframeeffects&quot;&gt;KeyframeEffects&lt;/h3&gt;

&lt;p&gt;A &lt;code&gt;KeyframeEffect&lt;/code&gt; takes three parameters: the element to animate, an array of keyframes, and our timing options. These are all parameters we’ve seen before when using &lt;code&gt;element.animate()&lt;/code&gt;. This new object essentially is a blueprint for a single animation and we will see it as we discuss ways to group and sequence animations.  It does not start an animation, it just defines one.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;elem&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;toAnimate&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;timings&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;duration&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;both&amp;#39;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;keyframes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;opacity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}.&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;opacity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;effect&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;KeyframeEffect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;elem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;keyframes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;timings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&quot;groupeffects&quot;&gt;GroupEffects&lt;/h3&gt;

&lt;p&gt;Though not available in any native implementation yet, and not even found in the &lt;a href=&quot;https://w3c.github.io/web-animations/&quot;&gt;Level 1 spec&lt;/a&gt;, the &lt;a href=&quot;https://github.com/web-animations/web-animations-js&quot;&gt;polyfill&lt;/a&gt; provides a way to group animations and play them together. The &lt;code&gt;GroupEffect&lt;/code&gt; (yes, &lt;a href=&quot;https://twitter.com/rachelnabors/status/631545063965720576&quot;&gt;it is coming&lt;/a&gt; in the Level 2 spec) groups one or more &lt;code&gt;KeyframeEffect&lt;/code&gt;s to play simultaneously.&lt;/p&gt;

&lt;p data-height=&quot;268&quot; data-theme-id=&quot;0&quot; data-slug-hash=&quot;zGeVey&quot; data-default-tab=&quot;result&quot; data-user=&quot;danwilson&quot; class=&quot;codepen&quot;&gt;See the Pen &lt;a href=&quot;http://codepen.io/danwilson/pen/zGeVey/&quot;&gt;zGeVey&lt;/a&gt; by Dan Wilson (&lt;a href=&quot;http://codepen.io/danwilson&quot;&gt;@danwilson&lt;/a&gt;) on &lt;a href=&quot;http://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;GroupEffect&lt;/code&gt; takes an effects parameter where we can pass in our array of &lt;code&gt;KeyframeEffect&lt;/code&gt;s representing our multiple animations. Once defined, we can play the group of animations on the default timeline when ready.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;elem&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;toAnimate&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;elem2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;toAnimate2&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;timings&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;duration&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;keyframes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;opacity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}.&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;opacity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;kEffects&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;KeyframeEffect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;elem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;keyframes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;timings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;KeyframeEffect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;elem2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;keyframes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;timings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;group&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;GroupEffect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;kEffects&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;timeline&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;play&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;group&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&quot;sequenceeffects&quot;&gt;SequenceEffects&lt;/h3&gt;

&lt;p&gt;Similar to the &lt;code&gt;GroupEffect&lt;/code&gt;, &lt;code&gt;SequenceEffect&lt;/code&gt;s allow us to group together multiple animations (specified by &lt;code&gt;KeyframeEffect&lt;/code&gt;s)… but instead of playing them in parallel they play one after the other.  You can also, as defined in the polyfill, use &lt;code&gt;GroupEffect&lt;/code&gt; and &lt;code&gt;SequenceEffect&lt;/code&gt; together (such as having a grouping of multiple sequences).&lt;/p&gt;

&lt;p data-height=&quot;268&quot; data-theme-id=&quot;0&quot; data-slug-hash=&quot;vNYQLL&quot; data-default-tab=&quot;result&quot; data-user=&quot;danwilson&quot; class=&quot;codepen&quot;&gt;See the Pen &lt;a href=&quot;http://codepen.io/danwilson/pen/vNYQLL/&quot;&gt;vNYQLL&lt;/a&gt; by Dan Wilson (&lt;a href=&quot;http://codepen.io/danwilson&quot;&gt;@danwilson&lt;/a&gt;) on &lt;a href=&quot;http://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Sequences give you something that we’ve had to work our way around with CSS or with what we’ve seen with the animations API so far.  We would have to maintain delays based on duration of earlier animations or use &lt;code&gt;finish&lt;/code&gt; callbacks. These methods can be hard to maintain and may not be as precise.&lt;/p&gt;

&lt;p&gt;Using the earlier variables from the &lt;code&gt;GroupEffect&lt;/code&gt; code segment:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;sequence&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;SequenceEffect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;kEffects&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;timeline&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;play&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;sequence&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&quot;an-alternate-way-to-create-an-animation&quot;&gt;An Alternate Way to Create an Animation&lt;/h3&gt;

&lt;p&gt;We have previously looked at the &lt;code&gt;element.animate()&lt;/code&gt; way to create animations. This is the quick way to create an animation, play it immediately, and get a reference to the &lt;code&gt;Animation&lt;/code&gt; object.  We focused on this first since it has been supported in Chrome for a while now, as well as the polyfill. Firefox is the first to support an alternate way: the &lt;code&gt;Animation&lt;/code&gt; constructor.  It shows us one more way to use the &lt;code&gt;KeyframeEffect&lt;/code&gt;, and it is in the Level 1 spec so we should see more use of this soon.&lt;/p&gt;

&lt;p&gt;First a reminder of how &lt;code&gt;element.animate()&lt;/code&gt; works:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;elem&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;toAnimate&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;timings&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;duration&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;both&amp;#39;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;keyframes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;opacity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}.&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;opacity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;elem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;animate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;keyframes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;timings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Using the same variables as above, the following is equivalent using the &lt;code&gt;Animation&lt;/code&gt; constructor:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;kEffect&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;KeyframeEffect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;elem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;keyframes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;timings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;player&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Animation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;kEffect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;elem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ownerDocument&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;timeline&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;player&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;play&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The primary difference here is that the animation does not start playing immediately, so this will be useful when creating animations in advance to be played later.&lt;/p&gt;

&lt;h3 id=&quot;wrap-up-and-next-time&quot;&gt;Wrap Up and Next Time&lt;/h3&gt;

&lt;p&gt;As the Level 2 spec makes its way through the working drafts, we should see more definition on these different Effects.  There are two more planned posts in this series.  Next time we will take a look at the future again with what else we can expect to see soon.&lt;/p&gt;

&lt;p&gt;Check out the rest of this series:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;/blog/2015/07/animations-intro&quot;&gt;Introduction&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/blog/2015/07/animations-part-1&quot;&gt;Part 1: Creating a Basic Animation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/blog/2015/07/animations-part-2&quot;&gt;Part 2: The Animation and Timeline Controls&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/blog/2015/08/animations-part-3&quot;&gt;Part 3: Multiple Animations&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/blog/2015/09/animations-part-5&quot;&gt;Part 5: Motion Paths&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/blog/2015/09/animations-conclusion&quot;&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 02 Sep 2015 00:00:00 -0500</pubDate>
        <link>http://danielcwilson.com/blog/2015/09/animations-part-4/</link>
        <guid isPermaLink="true">http://danielcwilson.com/blog/2015/09/animations-part-4/</guid>
        
        <category>animations</category>
        
        <category>web animations API</category>
        
        <category>web</category>
        
        
      </item>
    
  </channel>
</rss>
