transition.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. // Copyright 2011 The Closure Library Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS-IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. /**
  15. * @fileoverview CSS3 transition base library.
  16. *
  17. * @author chrishenry@google.com (Chris Henry)
  18. */
  19. goog.provide('goog.fx.css3.Transition');
  20. goog.require('goog.Timer');
  21. goog.require('goog.asserts');
  22. goog.require('goog.fx.TransitionBase');
  23. goog.require('goog.style');
  24. goog.require('goog.style.transition');
  25. /**
  26. * A class to handle targeted CSS3 transition. This class
  27. * handles common features required for targeted CSS3 transition.
  28. *
  29. * Browser that does not support CSS3 transition will still receive all
  30. * the events fired by the transition object, but will not have any transition
  31. * played. If the browser supports the final state as set in setFinalState
  32. * method, the element will ends in the final state.
  33. *
  34. * Transitioning multiple properties with the same setting is possible
  35. * by setting Css3Property's property to 'all'. Performing multiple
  36. * transitions can be done via setting multiple initialStyle,
  37. * finalStyle and transitions. Css3Property's delay can be used to
  38. * delay one of the transition. Here is an example for a transition
  39. * that expands on the width and then followed by the height:
  40. *
  41. * <pre>
  42. * var animation = new goog.fx.css3.Transition(
  43. * element,
  44. * duration,
  45. * {width: 10px, height: 10px},
  46. * {width: 100px, height: 100px},
  47. * [
  48. * {property: width, duration: 1, timing: 'ease-in', delay: 0},
  49. * {property: height, duration: 1, timing: 'ease-in', delay: 1}
  50. * ]
  51. * );
  52. * </pre>
  53. *
  54. * @param {Element} element The element to be transitioned.
  55. * @param {number} duration The duration of the transition in seconds.
  56. * This should be the longest of all transitions.
  57. * @param {Object} initialStyle Initial style properties of the element before
  58. * animating. Set using {@code goog.style.setStyle}.
  59. * @param {Object} finalStyle Final style properties of the element after
  60. * animating. Set using {@code goog.style.setStyle}.
  61. * @param {goog.style.transition.Css3Property|
  62. * Array<goog.style.transition.Css3Property>} transitions A single CSS3
  63. * transition property or an array of it.
  64. * @extends {goog.fx.TransitionBase}
  65. * @constructor
  66. * @struct
  67. */
  68. goog.fx.css3.Transition = function(
  69. element, duration, initialStyle, finalStyle, transitions) {
  70. goog.fx.css3.Transition.base(this, 'constructor');
  71. /**
  72. * Timer id to be used to cancel animation part-way.
  73. * @private {number}
  74. */
  75. this.timerId_;
  76. /**
  77. * @type {Element}
  78. * @private
  79. */
  80. this.element_ = element;
  81. /**
  82. * @type {number}
  83. * @private
  84. */
  85. this.duration_ = duration;
  86. /**
  87. * @type {Object}
  88. * @private
  89. */
  90. this.initialStyle_ = initialStyle;
  91. /**
  92. * @type {Object}
  93. * @private
  94. */
  95. this.finalStyle_ = finalStyle;
  96. /**
  97. * @type {Array<goog.style.transition.Css3Property>}
  98. * @private
  99. */
  100. this.transitions_ = goog.isArray(transitions) ? transitions : [transitions];
  101. };
  102. goog.inherits(goog.fx.css3.Transition, goog.fx.TransitionBase);
  103. /** @override */
  104. goog.fx.css3.Transition.prototype.play = function() {
  105. if (this.isPlaying()) {
  106. return false;
  107. }
  108. this.onBegin();
  109. this.onPlay();
  110. this.startTime = goog.now();
  111. this.setStatePlaying();
  112. if (goog.style.transition.isSupported()) {
  113. goog.style.setStyle(this.element_, this.initialStyle_);
  114. // Allow element to get updated to its initial state before installing
  115. // CSS3 transition.
  116. this.timerId_ = goog.Timer.callOnce(this.play_, undefined, this);
  117. return true;
  118. } else {
  119. this.stop_(false);
  120. return false;
  121. }
  122. };
  123. /**
  124. * Helper method for play method. This needs to be executed on a timer.
  125. * @private
  126. */
  127. goog.fx.css3.Transition.prototype.play_ = function() {
  128. // This measurement of the DOM element causes the browser to recalculate its
  129. // initial state before the transition starts.
  130. goog.style.getSize(this.element_);
  131. goog.style.transition.set(this.element_, this.transitions_);
  132. goog.style.setStyle(this.element_, this.finalStyle_);
  133. this.timerId_ = goog.Timer.callOnce(
  134. goog.bind(this.stop_, this, false), this.duration_ * 1000);
  135. };
  136. /** @override */
  137. goog.fx.css3.Transition.prototype.stop = function() {
  138. if (!this.isPlaying()) return;
  139. this.stop_(true);
  140. };
  141. /**
  142. * Helper method for stop method.
  143. * @param {boolean} stopped If the transition was stopped.
  144. * @private
  145. */
  146. goog.fx.css3.Transition.prototype.stop_ = function(stopped) {
  147. goog.style.transition.removeAll(this.element_);
  148. // Clear the timer.
  149. goog.Timer.clear(this.timerId_);
  150. // Make sure that we have reached the final style.
  151. goog.style.setStyle(this.element_, this.finalStyle_);
  152. this.endTime = goog.now();
  153. this.setStateStopped();
  154. if (stopped) {
  155. this.onStop();
  156. } else {
  157. this.onFinish();
  158. }
  159. this.onEnd();
  160. };
  161. /** @override */
  162. goog.fx.css3.Transition.prototype.disposeInternal = function() {
  163. this.stop();
  164. goog.fx.css3.Transition.base(this, 'disposeInternal');
  165. };
  166. /**
  167. * Pausing CSS3 Transitions in not supported.
  168. * @override
  169. */
  170. goog.fx.css3.Transition.prototype.pause = function() {
  171. goog.asserts.assert(false, 'Css3 transitions does not support pause action.');
  172. };