User:Mantaroh/Scroll-driven animations: Difference between revisions

From MozillaWiki
Jump to navigation Jump to search
(Update sample code.)
(Fix typo.)
 
(10 intermediate revisions by the same user not shown)
Line 1: Line 1:
'''** Note : This Document is WIP(Doesn't translate yet.) **'''
== Scroll-driven animations. ==
== Scroll-driven animations. ==
For previous discussion, see [[Platform/Layout/Extended Timelines|Extended Timeline]].
For previous discussion, see [[Platform/Layout/Extended Timelines|Extended Timeline]].
Line 7: Line 5:
Dean proposed [https://lists.w3.org/Archives/Public/www-style/2014Sep/0135.html the features of animation-trigger / animation-timebases / animation-behavior].<br/>
Dean proposed [https://lists.w3.org/Archives/Public/www-style/2014Sep/0135.html the features of animation-trigger / animation-timebases / animation-behavior].<br/>
And, Brian/Botond proposed the [[Platform/Layout/Extended Timelines|Extended Timeline]].<br/>
And, Brian/Botond proposed the [[Platform/Layout/Extended Timelines|Extended Timeline]].<br/>
These ideas is similar to each idea.
These ideas are similar to each idea.
Especially, We can create common architect which we can use at CSS Animations and Web Animation. Because these common idea is that we map the scroll value and timeline's value.
Especially, an amount of animation changes related to a number of scroll changes. We can create architect which using this common idea.
 
また、Firefox 49 から有効になった Bug 1178662「wrietable timeline」のバグで、タイムラインの設定 / 構築が容易に行えるようになったことから
ScrollTimeline のようにスクロール量とマッピングされたタイムラインを作成することが可能になりました。
 
そのため、このドキュメントでは Web Animation / CSS Animation を考慮したスクロールベースのアニメーションについて記述しています。


=== Interface of script proposal ===
=== Script API proposal ===
Same as DocumentTimeline, we should set ScrollTimeline to timeline property of animation.<br/>
Same as DocumentTimeline, we should set ScrollTimeline to timeline property of animation.<br/>
Perhaps, WebIDL of ScrollTimeline is same to [[Platform/Layout/Extended|previous API proposal]].
Perhaps, WebIDL of ScrollTimeline is same to [[Platform/Layout/Extended|previous API proposal]].
Line 21: Line 14:
  [Constructor ((Window or Element) scrollSource, Orientation orientation, optional double maxTime)
  [Constructor ((Window or Element) scrollSource, Orientation orientation, optional double maxTime)
  interface ScrollTimeline : AnimationTimeline {
  interface ScrollTimeline : AnimationTimeline {
  attribute Orientation orientation;
  attribute Orientation orientation;
  attribute double maxTime;
  attribute double maxTime;
  };
  };
   
   
Line 28: Line 21:
  enum Orientation { "vertical", "horizontal" };
  enum Orientation { "vertical", "horizontal" };


We will specify the third parameter when iterations of animation is 'Infinite'.
We will specify the third parameter for infinite animation iterations.<br />
And update the range of ScrollTimeline based on the first maching conditions:
And update the range of ScrollTimeline based on the first matching conditions:<br />
- If ScrollTimeline doesn't have any related animation, maxRange should be 0ms.
- If ScrollTimeline doesn't have any related animation, maxRange should be 0ms.<br />
- If ScrollTimeline has related animation, maxRnage should be max value in animations.  
- If ScrollTimeline has related animation, maxRange should be a maximum value of target effect end time of animations. <br />
  (We should ignore the infinity duration.)
(If target effect end time is infinite, presumably we might use dose duration of animation.)
- If all of related animation's duration is infinity, maxRange should be max value in animation's duration.<br />
 
  e.g. we have two animations.
==== Examples ====
    target1.animation = "anim1 10s linear infinite";
  // example: we have two finite animations.
    target2.animation = "anim2 20s linear infinite";<br />
  var scrollTimeline = new ScrollTimeline(scrollElem, "vertical");
  Then we should be max value of ScrollTimeline is 20s.
  var keyframe1 = new KeyframeEffect(target, {transform:['none','translate(100px)']}, 1000);
  var anim1 = new Animation(keyframe1, scrollTimeline);
  var keyframe2 = new KeyframeEffect(target, {transform:['none','translate(100px)']}, 4000);
  var anim2 = new Animation(keyframe2, scrollTimeline);<br/>
  Then we should use '''4000 ms''' as max scroll range.


=== Interface of CSS proposal ===
  // example: we have three animations.
  target1.style.animation = "animation1 50s linear Infinite";
  target2.style.animation = "animation2 100s linear Infinite";
  target3.style.animation = "animation3 70s linear 10s";<br/>
  var anim1 = target1.getAnimations()[0];
  var anim2 = target1.getAnimations()[0];
  var anim3 = target1.getAnimations()[0];<br/>
  var scrollTimeline = new ScrollTimeline(scrollElem, "horizontal");
  anim1.timeline = timeline;
  anim2.timeline = timeline;
  anim3.timeline = timeline;<br/>
  Then we should use '''100s''' as max scroll range.


  // example: we have two animation which having infinite iterations.
  var scrollTimeline = new ScrollTimeline(scrollElem, "vertical");
  var keyframe1 = new KeyframeEffect(target, {transform:['none','translate(100px)']}, {duration:1000, iterations:Infinite});
  var keyframe2 = new KeyframeEffect(target, {transform:['none','translate(100px)']}, {duration:3000, iterations:Infinite});<br/>
  var anim1 = new Animation(keyframe1, scrollTimeline);
  var anim2 = new Animation(keyframe2, scrollTimeline);<br/>
  Then we should use '''3000 ms''' as max scroll range.


=== Usage of this API ===
  // example: we have two infinite animations and specified scroll range.
1) Duration of animation is finite.
   var scrollTimeline = new ScrollTimeline(scrollElem, "vertical", 2000);
   var scrollTimeline = new ScrollTimeline(div, "vertical");
   var keyframe1 = new KeyframeEffect(target, {transform:['none','translate(100px)']}, {duration:1000, iterations:Infinite};
   var animation1 = new Animation(new KeyframeEffect( { marginLeft: ['0px', '200px'] }, 10000), null);
   var keyframe2 = new KeyframeEffect(target, {transform:['none','translate(100px)']}, {duration:3000, iterations:Infinite};<br/>
   var animation2 = new Animation(new KeyframeEffect( { marginLeft: ['100px', '300px'] }, 20000), null);
   var anim1 = new Animation(keyframe1, scrollTimeline);
   animation1.timeline = scrollTimeline;
   var anim2 = new Animation(keyframe2, scrollTimeline);<br/>
   animation2.timeline = scrollTimeline;
  Then we should use 2000 ms as max scroll range.


Demonstration:
=== CSS Interface proposal ===
  http://output.jsbin.com/wiwode


2) Duration of animation is infinite.
The CSS interface is same to [https://lists.w3.org/Archives/Public/www-style/2014Sep/0135.html Dean's proposal].
  var scrollTimeline = new ScrollTimeline(div, "horizontal", "20s");  // scroll range is mapped 0s - 20s.
There is three feature in his proposal, but 'animation-behavior' is not related to timeline.
  var animation1 = new Animation(new KeyframeEffect( { marginLeft: ['0px', '200px'] }, 10 * 1000), null);
So in this document, we explain 'animation-timeline'(Original name is 'animation-timebase') and 'animation-trigger' interface only.
  var animation2 = new Animation(new KeyframeEffect( { marginLeft: ['100px', '300px'] }, {duration:20 * 1000, iterations:Infinity}), null);
  animation1.timeline = scrollTimeline;
  animation2.timeline = scrollTimeline;


== Design (Gecko) ==
Common features:
- The scroll container should notify the changes value of scroll to related ScrollTimeline.
- The difference point is that animation target element and scroll container object is same or subelement.
- If the direction of scroll is reverse(like from bottom to top, from right to left), the timeline time is decreasing.
- ScrollTimeline should remain the animation status in order to use fill mode.


== Implement overview ==
=== Demonstration ===
  http://output.jsbin.com/wiwode


== Problem of implementation. ==
== Design ==
1) The concept of time value<br/>
We managed [https://w3c.github.io/web-animations/#time-value| time value] in Timeline, However ScrollTimeline doesn't have the concept of time. Because start position of ScrollTimeline is corresponding the start of animation. So ScrollTimeline doesn't have timve value but have relative position of animation.
In order to implement these, ScrollTimeline should have the start time of animation.


2) Supporting multi ScrollTimeline<br/>
== Implement overview ==
The animation have same timeline object each other.
We need to implement several features as follow.
  - Notify the scroll value to related ScrollTimeline from scroll containers.
  - (ScrollTimeline requests to scroll container for receivable scroll notification?)
  - ScrollTimeline should implement AnimationTimeline interface and RefreshObserver interface.
  - ScrollTimeline needs to remain the scroll value which notified from scroll container in order to calculate several times when tick.
  - ScrollTimeline needs to override AnimationTimeline::GetCurrentTime in order to notify current progress of animation to own animations.


3) End delay<br/>
[Consideration]
ScrollTimeline has limited range. i.e. timeline is finite range.
- How notify the scroll value from parent to child process? Especially e10s environment.

Latest revision as of 03:20, 30 June 2016

Scroll-driven animations.

For previous discussion, see Extended Timeline.

Introduction

Dean proposed the features of animation-trigger / animation-timebases / animation-behavior.
And, Brian/Botond proposed the Extended Timeline.
These ideas are similar to each idea. Especially, an amount of animation changes related to a number of scroll changes. We can create architect which using this common idea.

Script API proposal

Same as DocumentTimeline, we should set ScrollTimeline to timeline property of animation.
Perhaps, WebIDL of ScrollTimeline is same to previous API proposal.

[Constructor ((Window or Element) scrollSource, Orientation orientation, optional double maxTime)
interface ScrollTimeline : AnimationTimeline {
 attribute Orientation orientation;
 attribute double maxTime;
};

// Is there an existing enum somewhere we can use for this?
enum Orientation { "vertical", "horizontal" };

We will specify the third parameter for infinite animation iterations.
And update the range of ScrollTimeline based on the first matching conditions:
- If ScrollTimeline doesn't have any related animation, maxRange should be 0ms.
- If ScrollTimeline has related animation, maxRange should be a maximum value of target effect end time of animations.
(If target effect end time is infinite, presumably we might use dose duration of animation.)

Examples

 // example: we have two finite animations.
 var scrollTimeline = new ScrollTimeline(scrollElem, "vertical");
 var keyframe1 = new KeyframeEffect(target, {transform:['none','translate(100px)']}, 1000);
 var anim1 = new Animation(keyframe1, scrollTimeline);
 var keyframe2 = new KeyframeEffect(target, {transform:['none','translate(100px)']}, 4000);
 var anim2 = new Animation(keyframe2, scrollTimeline);
Then we should use 4000 ms as max scroll range.
 // example: we have three animations.
 target1.style.animation = "animation1 50s linear Infinite";
 target2.style.animation = "animation2 100s linear Infinite";
 target3.style.animation = "animation3 70s linear 10s";
var anim1 = target1.getAnimations()[0]; var anim2 = target1.getAnimations()[0]; var anim3 = target1.getAnimations()[0];
var scrollTimeline = new ScrollTimeline(scrollElem, "horizontal"); anim1.timeline = timeline; anim2.timeline = timeline; anim3.timeline = timeline;
Then we should use 100s as max scroll range.
 // example: we have two animation which having infinite iterations.
 var scrollTimeline = new ScrollTimeline(scrollElem, "vertical");
 var keyframe1 = new KeyframeEffect(target, {transform:['none','translate(100px)']}, {duration:1000, iterations:Infinite});
 var keyframe2 = new KeyframeEffect(target, {transform:['none','translate(100px)']}, {duration:3000, iterations:Infinite});
var anim1 = new Animation(keyframe1, scrollTimeline); var anim2 = new Animation(keyframe2, scrollTimeline);
Then we should use 3000 ms as max scroll range.
 // example: we have two infinite animations and specified scroll range.
 var scrollTimeline = new ScrollTimeline(scrollElem, "vertical", 2000);
 var keyframe1 = new KeyframeEffect(target, {transform:['none','translate(100px)']}, {duration:1000, iterations:Infinite};
 var keyframe2 = new KeyframeEffect(target, {transform:['none','translate(100px)']}, {duration:3000, iterations:Infinite};
var anim1 = new Animation(keyframe1, scrollTimeline); var anim2 = new Animation(keyframe2, scrollTimeline);
Then we should use 2000 ms as max scroll range.

CSS Interface proposal

The CSS interface is same to Dean's proposal. There is three feature in his proposal, but 'animation-behavior' is not related to timeline. So in this document, we explain 'animation-timeline'(Original name is 'animation-timebase') and 'animation-trigger' interface only.

Common features:

- The scroll container should notify the changes value of scroll to related ScrollTimeline.
- The difference point is that animation target element and scroll container object is same or subelement.
- If the direction of scroll is reverse(like from bottom to top, from right to left), the timeline time is decreasing.
- ScrollTimeline should remain the animation status in order to use fill mode. 

Demonstration

 http://output.jsbin.com/wiwode

Design

Implement overview

We need to implement several features as follow.
 - Notify the scroll value to related ScrollTimeline from scroll containers.
 - (ScrollTimeline requests to scroll container for receivable scroll notification?)
 - ScrollTimeline should implement AnimationTimeline interface and RefreshObserver interface.
 - ScrollTimeline needs to remain the scroll value which notified from scroll container in order to calculate several times when tick.
 - ScrollTimeline needs to override AnimationTimeline::GetCurrentTime in order to notify current progress of animation to own animations.

[Consideration] - How notify the scroll value from parent to child process? Especially e10s environment.