animation.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. "use strict";
  5. const {
  6. Front,
  7. FrontClassWithSpec,
  8. custom,
  9. preEvent
  10. } = require("devtools/shared/protocol");
  11. const {
  12. animationPlayerSpec,
  13. animationsSpec
  14. } = require("devtools/shared/specs/animation");
  15. const { Task } = require("devtools/shared/task");
  16. const AnimationPlayerFront = FrontClassWithSpec(animationPlayerSpec, {
  17. initialize: function (conn, form, detail, ctx) {
  18. Front.prototype.initialize.call(this, conn, form, detail, ctx);
  19. this.state = {};
  20. },
  21. form: function (form, detail) {
  22. if (detail === "actorid") {
  23. this.actorID = form;
  24. return;
  25. }
  26. this._form = form;
  27. this.state = this.initialState;
  28. },
  29. destroy: function () {
  30. Front.prototype.destroy.call(this);
  31. },
  32. /**
  33. * If the AnimationsActor was given a reference to the WalkerActor previously
  34. * then calling this getter will return the animation target NodeFront.
  35. */
  36. get animationTargetNodeFront() {
  37. if (!this._form.animationTargetNodeActorID) {
  38. return null;
  39. }
  40. return this.conn.getActor(this._form.animationTargetNodeActorID);
  41. },
  42. /**
  43. * Getter for the initial state of the player. Up to date states can be
  44. * retrieved by calling the getCurrentState method.
  45. */
  46. get initialState() {
  47. return {
  48. type: this._form.type,
  49. startTime: this._form.startTime,
  50. previousStartTime: this._form.previousStartTime,
  51. currentTime: this._form.currentTime,
  52. playState: this._form.playState,
  53. playbackRate: this._form.playbackRate,
  54. name: this._form.name,
  55. duration: this._form.duration,
  56. delay: this._form.delay,
  57. endDelay: this._form.endDelay,
  58. iterationCount: this._form.iterationCount,
  59. iterationStart: this._form.iterationStart,
  60. easing: this._form.easing,
  61. fill: this._form.fill,
  62. direction: this._form.direction,
  63. isRunningOnCompositor: this._form.isRunningOnCompositor,
  64. propertyState: this._form.propertyState,
  65. documentCurrentTime: this._form.documentCurrentTime
  66. };
  67. },
  68. /**
  69. * Executed when the AnimationPlayerActor emits a "changed" event. Used to
  70. * update the local knowledge of the state.
  71. */
  72. onChanged: preEvent("changed", function (partialState) {
  73. let {state} = this.reconstructState(partialState);
  74. this.state = state;
  75. }),
  76. /**
  77. * Refresh the current state of this animation on the client from information
  78. * found on the server. Doesn't return anything, just stores the new state.
  79. */
  80. refreshState: Task.async(function* () {
  81. let data = yield this.getCurrentState();
  82. if (this.currentStateHasChanged) {
  83. this.state = data;
  84. }
  85. }),
  86. /**
  87. * getCurrentState interceptor re-constructs incomplete states since the actor
  88. * only sends the values that have changed.
  89. */
  90. getCurrentState: custom(function () {
  91. this.currentStateHasChanged = false;
  92. return this._getCurrentState().then(partialData => {
  93. let {state, hasChanged} = this.reconstructState(partialData);
  94. this.currentStateHasChanged = hasChanged;
  95. return state;
  96. });
  97. }, {
  98. impl: "_getCurrentState"
  99. }),
  100. reconstructState: function (data) {
  101. let hasChanged = false;
  102. for (let key in this.state) {
  103. if (typeof data[key] === "undefined") {
  104. data[key] = this.state[key];
  105. } else if (data[key] !== this.state[key]) {
  106. hasChanged = true;
  107. }
  108. }
  109. return {state: data, hasChanged};
  110. }
  111. });
  112. exports.AnimationPlayerFront = AnimationPlayerFront;
  113. const AnimationsFront = FrontClassWithSpec(animationsSpec, {
  114. initialize: function (client, {animationsActor}) {
  115. Front.prototype.initialize.call(this, client, {actor: animationsActor});
  116. this.manage(this);
  117. },
  118. destroy: function () {
  119. Front.prototype.destroy.call(this);
  120. }
  121. });
  122. exports.AnimationsFront = AnimationsFront;