{"id":264051,"date":"2018-01-02T08:37:50","date_gmt":"2018-01-02T15:37:50","guid":{"rendered":"http:\/\/css-tricks.com\/?p=264051"},"modified":"2020-03-30T15:31:52","modified_gmt":"2020-03-30T22:31:52","slug":"additive-animation-web-animations-api","status":"publish","type":"post","link":"https:\/\/css-tricks.com\/additive-animation-web-animations-api\/","title":{"rendered":"Additive Animation with the Web Animations API"},"content":{"rendered":"

These features have not landed in any stable browsers at the time of writing. However, everything discussed is already in Firefox Nightly<\/a> by default and key parts are in Chrome Canary<\/a> (with the Experimental Web Platform Features flag enabled), so I recommend using one of those browsers (when reading this article) to see as many of the features in action as possible.<\/p>\n

Regardless your preferred method of animation on the web, there will be times that you need to animate the same property in separate animations. Maybe you have a hover effect that scales an image and a click event that triggers a translate \u2014 both affecting the transform<\/code>. By default, those animations do not know anything about the other, and only one will visually be applied (since they are affecting the same CSS property and the other value will be overridden).<\/p>\n

<\/p>\n

element.animate({\n  transform: ['translateY(0)', 'translateY(10px)']\n}, 1000);\n\n\/* This will completely override the previous animation *\/\nelement.animate({\n  transform: ['scale(1)', 'scale(1.15)']\n}, 1500);<\/code><\/pre>\n

The second animation in this Web Animations API example is the only one that would be visually rendered in this example as both animations play at the same time and it was the last one defined.<\/p>\n

Sometimes we even have grander ideas where we want a foundational animation and then based on some user interaction change in state we smoothly modify the animation a bit midway without affecting its existing duration, keyframes, or easing. CSS Animations and the current Web Animations API in stable browsers today cannot do this out of the box.<\/p>\n

A New Option<\/h3>\n

The Web Animations specification introduces the composite<\/code> property<\/a> (and the related iterationComposite<\/code>). The default composite<\/code> is 'replace'<\/code> and has the behavior we have had for years now where an actively animating property’s value simply replaces any previously set value \u2014 either from a rule set or another animation.<\/p>\n

The 'add'<\/code> value is where things change from the previous norms.<\/p>\n

element.animate({\n  transform: ['scale(1)', 'scale(1.5)']\n}, {\n  duration: 1000,\n  fill: 'both'\n});\nelement.animate({\n  transform: ['rotate(0deg)', 'rotate(180deg)']\n}, {\n  duration: 1500,\n  fill: 'both',\n  composite: 'add'\n});<\/code><\/pre>\n

Now both animations will be seen as the browser on the fly figures out the appropriate transformation at a given point in the element’s timeline accounting for both transformations. In our examples, the easing is 'linear'<\/code> by default and the animations start at the same time, so we can break out what the effective transform<\/code> is at any given point. Such as:<\/p>\n