| Index: third_party/polymer/components/core-animation/core-animation.html
|
| diff --git a/third_party/polymer/components/core-animation/core-animation.html b/third_party/polymer/components/core-animation/core-animation.html
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..9a958c9eafadd6dd204e9ca4f62f5862b2727330
|
| --- /dev/null
|
| +++ b/third_party/polymer/components/core-animation/core-animation.html
|
| @@ -0,0 +1,525 @@
|
| +<!--
|
| +Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
|
| +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
| +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
| +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
| +Code distributed by Google as part of the polymer project is also
|
| +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
| +-->
|
| +
|
| +<link rel="import" href="../polymer/polymer.html">
|
| +<link rel="import" href="web-animations.html">
|
| +
|
| +<!--
|
| +@group Polymer Core Elements
|
| +
|
| +`core-animation` is a convenience element to use web animations with Polymer elements. It
|
| +allows you to create a web animation declaratively. You can extend this class to create
|
| +new types of animations and combine them with `core-animation-group`.
|
| +
|
| +Example to create animation to fade out an element over 500ms:
|
| +
|
| + <core-animation id="fadeout" duration="500">
|
| + <core-animation-keyframe>
|
| + <core-animation-prop name="opacity" value="1"></core-animation-prop>
|
| + </core-animation-keyframe>
|
| + <core-animation-keyframe>
|
| + <core-animation-prop name="opacity" value="0"></core-animation-prop>
|
| + </core-animation-keyframe>
|
| + </core-animation>
|
| +
|
| + <div id="el">Fade me out</div>
|
| +
|
| + <script>
|
| + var animation = document.getElementById('fadeout');
|
| + animation.target = document.getElementById('el');
|
| + animation.play();
|
| + </script>
|
| +
|
| +Or do the same imperatively:
|
| +
|
| + var animation = new CoreAnimation();
|
| + animation.duration = 500;
|
| + animation.keyframes = [
|
| + {opacity: 1},
|
| + {opacity: 0}
|
| + ];
|
| + animation.target = document.getElementById('el');
|
| + animation.play();
|
| +
|
| +You can also provide a javascript function instead of keyframes to the animation. This
|
| +behaves essentially the same as `requestAnimationFrame`:
|
| +
|
| + var animation = new CoreAnimation();
|
| + animation.customEffect = function(timeFraction, target, animation) {
|
| + // do something custom
|
| + };
|
| + animation.play();
|
| +
|
| +Elements that are targets to a `core-animation` are given the `core-animation-target` class.
|
| +
|
| +@element core-animation
|
| +@status beta
|
| +@homepage github.io
|
| +-->
|
| +<polymer-element name="core-animation" constructor="CoreAnimation" attributes="target keyframes customEffect composite duration fill easing iterationStart iterationCount delay direction autoplay targetSelector">
|
| + <script>
|
| + (function() {
|
| +
|
| + function toNumber(value, allowInfinity) {
|
| + return (allowInfinity && value === 'Infinity') ? Number.POSITIVE_INFINITY : Number(value);
|
| + };
|
| +
|
| + Polymer({
|
| + /**
|
| + * Fired when the animation completes.
|
| + *
|
| + * @event core-animation-finish
|
| + */
|
| +
|
| + /**
|
| + *
|
| + * Fired when the web animation object changes.
|
| + *
|
| + * @event core-animation-change
|
| + */
|
| +
|
| + publish: {
|
| +
|
| + /**
|
| + * One or more nodes to animate.
|
| + *
|
| + * @property target
|
| + * @type HTMLElement|Node|Array<HTMLElement|Node>
|
| + */
|
| + target: {value: null, reflect: true},
|
| +
|
| + /**
|
| + * Animation keyframes specified as an array of dictionaries of
|
| + * <css properties>:<array of values> pairs. For example,
|
| + *
|
| + * @property keyframes
|
| + * @type Object
|
| + */
|
| + keyframes: {value: null, reflect: true},
|
| +
|
| + /**
|
| + * A custom animation function. Either provide this or `keyframes`. The signature
|
| + * of the callback is `EffectsCallback(timeFraction, target, animation)`
|
| + *
|
| + * @property customEffect
|
| + * @type Function(number, Object, Object)
|
| + */
|
| + customEffect: {value: null, reflect: true},
|
| +
|
| + /**
|
| + * Controls the composition behavior. If set to "replace", the effect overrides
|
| + * the underlying value for the target. If set the "add", the effect is added to
|
| + * the underlying value for the target. If set to "accumulate", the effect is
|
| + * accumulated to the underlying value for the target.
|
| + *
|
| + * In cases such as numbers or lengths, "add" and "accumulate" produce the same
|
| + * value. In list values, "add" is appending to the list, while "accumulate" is
|
| + * adding the individual components of the list.
|
| + *
|
| + * For example, adding `translateX(10px)` and `translateX(25px)` produces
|
| + * `translateX(10px) translateX(25px)` and accumulating produces `translateX(35px)`.
|
| + *
|
| + * @property composite
|
| + * @type "replace"|"add"|"accumulate"
|
| + * @default "replace"
|
| + */
|
| + composite: {value: 'replace', reflect: true},
|
| +
|
| + /**
|
| + * Animation duration in milliseconds, "Infinity", or "auto". "auto" is
|
| + * equivalent to 0.
|
| + *
|
| + * @property duration
|
| + * @type number|"Infinity"
|
| + * @default "auto"
|
| + */
|
| + duration: {value: 'auto', reflect: true},
|
| +
|
| + /**
|
| + * Controls the effect the animation has on the target when it's not playing.
|
| + * The possible values are "none", "forwards", "backwards", "both" or "auto".
|
| + *
|
| + * "none" means the animation has no effect when it's not playing.
|
| + *
|
| + * "forwards" applies the value at the end of the animation after it's finished.
|
| + *
|
| + * "backwards" applies the value at the start of the animation to the target
|
| + * before it starts playing and has no effect when the animation finishes.
|
| + *
|
| + * "both" means "forwards" and "backwards". "auto" is equivalent to "none".
|
| + *
|
| + * @property fill
|
| + * @type "none"|"forwards"|"backwards"|"both"|"auto"
|
| + * @default "auto"
|
| + */
|
| + fill: {value: 'auto', reflect: true},
|
| +
|
| + /**
|
| + * A transition timing function. The values are equivalent to the CSS
|
| + * counterparts.
|
| + *
|
| + * @property easing
|
| + * @type string
|
| + * @default "linear"
|
| + */
|
| + easing: {value: 'linear', reflect: true},
|
| +
|
| + /**
|
| + * The number of milliseconds to delay before beginning the animation.
|
| + *
|
| + * @property delay
|
| + * @type Number
|
| + * @default 0
|
| + */
|
| + delay: {value: 0, reflect: true},
|
| +
|
| + /**
|
| + * The number of milliseconds to wait after the animation finishes. This is
|
| + * useful, for example, in an animation group to wait for some time before
|
| + * beginning the next item in the animation group.
|
| + *
|
| + * @property endDelay
|
| + * @type number
|
| + * @default 0
|
| + */
|
| + endDelay: {value: 0, reflect: true},
|
| +
|
| + /**
|
| + * The number of iterations this animation should run for.
|
| + *
|
| + * @property iterations
|
| + * @type Number|'Infinity'
|
| + * @default 1
|
| + */
|
| + iterations: {value: 1, reflect: true},
|
| +
|
| + /**
|
| + * Number of iterations into the animation in which to begin the effect.
|
| + * For example, setting this property to 0.5 and `iterations` to 2 will
|
| + * cause the animation to begin halfway through the first iteration but still
|
| + * run twice.
|
| + *
|
| + * @property iterationStart
|
| + * @type Number
|
| + * @default 0
|
| + */
|
| + iterationStart: {value: 0, reflect: true},
|
| +
|
| + /**
|
| + * (not working in web animations polyfill---do not use)
|
| + *
|
| + * Controls the iteration composition behavior. If set to "replace", the effect for
|
| + * every iteration is independent of each other. If set to "accumulate", the effect
|
| + * for iterations of the animation will build upon the value in the previous iteration.
|
| + *
|
| + * Example:
|
| + *
|
| + * // Moves the target 50px on the x-axis over 5 iterations.
|
| + * <core-animation iterations="5" iterationComposite="accumulate">
|
| + * <core-animation-keyframe>
|
| + * <core-animation-prop name="transform" value="translateX(10px)"></core-animation-prop>
|
| + * </core-animation-keyframe>
|
| + * </core-animation>
|
| + *
|
| + * @property iterationComposite
|
| + * @type "replace"|"accumulate"
|
| + * @default false
|
| + */
|
| + iterationComposite: {value: 'replace', reflect: true},
|
| +
|
| + /**
|
| + * The playback direction of the animation. "normal" plays the animation in the
|
| + * normal direction. "reverse" plays it in the reverse direction. "alternate"
|
| + * alternates the playback direction every iteration such that even iterations are
|
| + * played normally and odd iterations are reversed. "alternate-reverse" plays
|
| + * even iterations in the reverse direction and odd iterations in the normal
|
| + * direction.
|
| + *
|
| + * @property direction
|
| + * @type "normal"|"reverse"|"alternate"|"alternate-reverse"
|
| + * @default "normal"
|
| + */
|
| + direction: {value: 'normal', reflect: true},
|
| +
|
| + /**
|
| + * A multiplier to the playback rate to the animation.
|
| + *
|
| + * @property playbackRate
|
| + * @type number
|
| + * @default 1
|
| + */
|
| + playbackRate: {value: 1, reflect: true},
|
| +
|
| + /**
|
| + * If set to true, play the animation when it is created or a property is updated.
|
| + *
|
| + * @property autoplay
|
| + * @type boolean
|
| + * @default false
|
| + */
|
| + autoplay: {value: false, reflect: true}
|
| +
|
| + },
|
| +
|
| + animation: false,
|
| +
|
| + observe: {
|
| + target: 'apply',
|
| + keyframes: 'apply',
|
| + customEffect: 'apply',
|
| + composite: 'apply',
|
| + duration: 'apply',
|
| + fill: 'apply',
|
| + easing: 'apply',
|
| + iterations: 'apply',
|
| + iterationStart: 'apply',
|
| + iterationComposite: 'apply',
|
| + delay: 'apply',
|
| + endDelay: 'apply',
|
| + direction: 'apply',
|
| + playbackRate: 'apply',
|
| + autoplay: 'apply'
|
| + },
|
| +
|
| + ready: function() {
|
| + this.apply();
|
| + },
|
| +
|
| + /**
|
| + * Plays the animation. If the animation is currently paused, seeks the animation
|
| + * to the beginning before starting playback.
|
| + *
|
| + * @method play
|
| + * @return AnimationPlayer The animation player.
|
| + */
|
| + play: function() {
|
| + this.apply();
|
| + if (this.animation && !this.autoplay) {
|
| + this.player = document.timeline.play(this.animation);
|
| + this.player.onfinish = this.animationFinishHandler.bind(this);
|
| + return this.player;
|
| + }
|
| + },
|
| +
|
| + /**
|
| + * Stops the animation and clears all effects on the target.
|
| + *
|
| + * @method cancel
|
| + */
|
| + cancel: function() {
|
| + if (this.player) {
|
| + this.player.cancel();
|
| + }
|
| + },
|
| +
|
| + /**
|
| + * Seeks the animation to the end.
|
| + *
|
| + * @method finish
|
| + */
|
| + finish: function() {
|
| + if (this.player) {
|
| + this.player.finish();
|
| + }
|
| + },
|
| +
|
| + /**
|
| + * Pauses the animation.
|
| + *
|
| + * @method pause
|
| + */
|
| + pause: function() {
|
| + if (this.player) {
|
| + this.player.pause();
|
| + }
|
| + },
|
| +
|
| + /**
|
| + * @method hasTarget
|
| + * @return boolean True if `target` is defined.
|
| + */
|
| + hasTarget: function() {
|
| + return this.target !== null;
|
| + },
|
| +
|
| + /**
|
| + * Creates a web animations object based on this object's properties, and
|
| + * plays it if autoplay is true.
|
| + *
|
| + * @method apply
|
| + * @return Object A web animation.
|
| + */
|
| + apply: function() {
|
| + this.animation = this.makeAnimation();
|
| + if (this.autoplay && this.animation) {
|
| + this.play();
|
| + }
|
| + return this.animation;
|
| + },
|
| +
|
| + makeSingleAnimation: function(target) {
|
| + // XXX(yvonne): for selecting all the animated elements.
|
| + target.classList.add('core-animation-target');
|
| + return new Animation(target, this.animationEffect, this.timingProps);
|
| + },
|
| +
|
| + makeAnimation: function() {
|
| + if (!this.target) {
|
| + return null;
|
| + }
|
| + var animation;
|
| + if (Array.isArray(this.target)) {
|
| + var array = [];
|
| + this.target.forEach(function(t) {
|
| + array.push(this.makeSingleAnimation(t));
|
| + }.bind(this));
|
| + animation = new AnimationGroup(array);
|
| + } else {
|
| + animation = this.makeSingleAnimation(this.target);
|
| + }
|
| + return animation;
|
| + },
|
| +
|
| + animationChanged: function() {
|
| + // Sending 'this' with the event so you can always get the animation object
|
| + // that fired the event, due to event retargetting in shadow DOM.
|
| + this.fire('core-animation-change', this);
|
| + },
|
| +
|
| + targetChanged: function(old) {
|
| + if (old) {
|
| + old.classList.remove('core-animation-target');
|
| + }
|
| + },
|
| +
|
| + get timingProps() {
|
| + var props = {};
|
| + var timing = {
|
| + delay: {isNumber: true},
|
| + endDelay: {isNumber: true},
|
| + fill: {},
|
| + iterationStart: {isNumber: true},
|
| + iterations: {isNumber: true, allowInfinity: true},
|
| + duration: {isNumber: true},
|
| + playbackRate: {isNumber: true},
|
| + direction: {},
|
| + easing: {}
|
| + };
|
| + for (t in timing) {
|
| + if (this[t] !== null) {
|
| + var name = timing[t].property || t;
|
| + props[name] = timing[t].isNumber && this[t] !== 'auto' ?
|
| + toNumber(this[t], timing[t].allowInfinity) : this[t];
|
| + }
|
| + }
|
| + return props;
|
| + },
|
| +
|
| + get animationEffect() {
|
| + var props = {};
|
| + var frames = [];
|
| + var effect;
|
| + if (this.keyframes) {
|
| + frames = this.keyframes;
|
| + } else if (!this.customEffect) {
|
| + var children = this.querySelectorAll('core-animation-keyframe');
|
| + if (children.length === 0 && this.shadowRoot) {
|
| + children = this.shadowRoot.querySelectorAll('core-animation-keyframe');
|
| + }
|
| + Array.prototype.forEach.call(children, function(c) {
|
| + frames.push(c.properties);
|
| + });
|
| + }
|
| + if (this.customEffect) {
|
| + effect = this.customEffect;
|
| + } else {
|
| + // effect = new KeyframeEffect(frames, this.composite);
|
| + effect = frames;
|
| + }
|
| + return effect;
|
| + },
|
| +
|
| + animationFinishHandler: function() {
|
| + this.fire('core-animation-finish');
|
| + }
|
| +
|
| + });
|
| + })();
|
| + </script>
|
| +</polymer-element>
|
| +
|
| +<!--
|
| +`core-animation-keyframe` represents a keyframe in a `core-animation`. Use them as children of
|
| +`core-animation` elements to create web animations declaratively. If the `offset` property is
|
| +unset, the keyframes will be distributed evenly within the animation duration. Use
|
| +`core-animation-prop` elements as children of this element to specify the CSS properties for
|
| +the animation.
|
| +
|
| +@element core-animation-keyframe
|
| +@status beta
|
| +@homepage github.io
|
| +-->
|
| +<polymer-element name="core-animation-keyframe" attributes="offset">
|
| + <script>
|
| + Polymer({
|
| + publish: {
|
| + /**
|
| + * An offset from 0 to 1.
|
| + *
|
| + * @property offset
|
| + * @type Number
|
| + */
|
| + offset: {value: null, reflect: true}
|
| + },
|
| + get properties() {
|
| + var props = {};
|
| + var children = this.querySelectorAll('core-animation-prop');
|
| + Array.prototype.forEach.call(children, function(c) {
|
| + props[c.name] = c.value;
|
| + });
|
| + if (this.offset !== null) {
|
| + props.offset = this.offset;
|
| + }
|
| + return props;
|
| + }
|
| + });
|
| + </script>
|
| +</polymer-element>
|
| +
|
| +<!--
|
| +`core-animation-prop` represents a CSS property and value pair to use with
|
| +`core-animation-keyframe`.
|
| +
|
| +@element core-animation-prop
|
| +@status beta
|
| +@homepage github.io
|
| +-->
|
| +<polymer-element name="core-animation-prop" attributes="name value">
|
| + <script>
|
| + Polymer({
|
| + publish: {
|
| + /**
|
| + * A CSS property name.
|
| + *
|
| + * @property name
|
| + * @type string
|
| + */
|
| + name: {value: '', reflect: true},
|
| +
|
| + /**
|
| + * The value for the CSS property.
|
| + *
|
| + * @property value
|
| + * @type string|number
|
| + */
|
| + value: {value: '', reflect: true}
|
| + }
|
| + });
|
| + </script>
|
| +</polymer-element>
|
|
|