Parcourir la source

Added dispose method

Ievgen Naida il y a 5 ans
Parent
commit
7966294ee0
9 fichiers modifiés avec 137 ajouts et 48 suppressions
  1. 13 0
      README.md
  2. 1 12
      demo/index.html
  3. 66 20
      lib/animation-timeline.js
  4. 0 0
      lib/animation-timeline.min.js
  5. 1 1
      package.json
  6. 48 4
      src/timeline.ts
  7. 5 5
      src/timelineEventsEmitter.ts
  8. 2 5
      tsconfig.json
  9. 1 1
      webpack.config.js

+ 13 - 0
README.md

@@ -58,6 +58,19 @@ import {
 timeline.initialize({ id: 'timeline' });
 ```
 
+### Build 
+
+run once to install development references:
+```bash
+  npm install
+```
+
+to pack JavaScript as a bundle:
+
+```bash
+  npm run build
+```
+
 ### Draw the outline tree
 
 Scroll events can be synchronized with the outline at the left side of the control.

+ 1 - 12
demo/index.html

@@ -67,18 +67,7 @@
       {
         //keyframesShape: "rect",
         drawKeyframes: true,
-        // Custom keyframes renderer:
-        renderKeyframes: function (ctx, pos, bounds, keyframe, lane) {
-          if (!bounds) {
-            return;
-          }
 
-          ctx.fillStyle = 'gray';
-          let size = 15;
-          ctx.beginPath();
-          ctx.rect(pos.x, pos.y - size / 2, 5, size);
-          ctx.fill();
-        },
         selected: false,
         hidden: false,
         keyframes: [
@@ -143,7 +132,7 @@
       },
     ];
 
-    let timeline = new timelineModule.Timeline({id:'timeline'})
+    let timeline = new timelineModule.Timeline({ id: 'timeline' })
 
     timeline.setModel({ rows: rows });
 

+ 66 - 20
lib/animation-timeline.js

@@ -207,7 +207,7 @@ var TimelineEventsEmitter = /*#__PURE__*/function () {
   function TimelineEventsEmitter() {
     _classCallCheck(this, TimelineEventsEmitter);
 
-    _defineProperty(this, "subscriptions", []);
+    _defineProperty(this, "_subscriptions", []);
   }
 
   _createClass(TimelineEventsEmitter, [{
@@ -218,7 +218,7 @@ var TimelineEventsEmitter = /*#__PURE__*/function () {
         return;
       }
 
-      this.subscriptions.push({
+      this._subscriptions.push({
         topic: topic,
         callback: callback
       });
@@ -230,7 +230,7 @@ var TimelineEventsEmitter = /*#__PURE__*/function () {
   }, {
     key: "off",
     value: function off(topic, callback) {
-      this.subscriptions = this.subscriptions.filter(function (event) {
+      this._subscriptions = this._subscriptions.filter(function (event) {
         return event && event.callback != callback && event.topic != topic;
       });
     }
@@ -241,14 +241,14 @@ var TimelineEventsEmitter = /*#__PURE__*/function () {
   }, {
     key: "offAll",
     value: function offAll() {
-      this.subscriptions.length = 0;
+      this._subscriptions.length = 0;
     } // emit event.
     // eslint-disable-next-line @typescript-eslint/no-explicit-any
 
   }, {
     key: "emit",
     value: function emit(topic, args) {
-      this.subscriptions.forEach(function (event) {
+      this._subscriptions.forEach(function (event) {
         if (event && event.topic == topic && event.callback) {
           event.callback(args);
         }
@@ -906,10 +906,7 @@ var timeline_Timeline = /*#__PURE__*/function (_TimelineEventsEmitte) {
     });
 
     timeline_defineProperty(_assertThisInitialized(_this), "handleScrollEvent", function (args) {
-      if (_this.scrollFinishedTimerRef) {
-        clearTimeout(_this.scrollFinishedTimerRef);
-        _this.scrollFinishedTimerRef = null;
-      } // Set a timeout to run event 'scrolling end'.
+      _this.clearScrollFinishedTimer(); // Set a timeout to run event 'scrolling end'.
 
 
       _this.scrollFinishedTimerRef = setTimeout(function () {
@@ -1274,6 +1271,42 @@ var timeline_Timeline = /*#__PURE__*/function (_TimelineEventsEmitte) {
       window.addEventListener('mouseup', this.handleMouseUpEvent, false);
       window.addEventListener('touchend', this.handleMouseUpEvent, false);
     }
+  }, {
+    key: "dispose",
+    value: function dispose() {
+      this._subscriptions = null;
+      this.container = null;
+      this.canvas = null;
+      this.scrollContainer = null;
+      this.scrollContent = null;
+      this.ctx = null;
+      this.cleanUpSelection();
+      this.container.removeEventListener('wheel', this.handleWheelEvent);
+
+      if (this.scrollContainer) {
+        this.scrollContainer.removeEventListener('scroll', this.handleScrollEvent);
+      }
+
+      window.removeEventListener('blur', this.handleBlurEvent);
+      window.removeEventListener('resize', this.handleWindowResizeEvent);
+      document.removeEventListener('keydown', this.handleDocumentKeydownEvent);
+      this.canvas.removeEventListener('touchstart', this.handleMouseDownEvent);
+      this.canvas.removeEventListener('mousedown', this.handleMouseDownEvent);
+      window.removeEventListener('mousemove', this.handleMouseMoveEvent);
+      window.removeEventListener('touchmove', this.handleMouseMoveEvent);
+      window.removeEventListener('mouseup', this.handleMouseUpEvent);
+      window.removeEventListener('touchend', this.handleMouseUpEvent);
+      this.stopAutoPan();
+      this.clearScrollFinishedTimer();
+    }
+  }, {
+    key: "clearScrollFinishedTimer",
+    value: function clearScrollFinishedTimer() {
+      if (this.scrollFinishedTimerRef) {
+        clearTimeout(this.scrollFinishedTimerRef);
+        this.scrollFinishedTimerRef = null;
+      }
+    }
   }, {
     key: "performClick",
     value: function performClick(pos, args, drag) {
@@ -1925,7 +1958,7 @@ var timeline_Timeline = /*#__PURE__*/function (_TimelineEventsEmitte) {
 
         if (!includeStipesBounds && (!row.keyframes || !row.keyframes.forEach || row.keyframes.length <= 0)) {
           return;
-        } // Get min and max ms to draw keyframe lane:
+        } // Get min and max ms to draw keyframe rows:
 
 
         if (row && row.keyframes) {
@@ -2057,25 +2090,25 @@ var timeline_Timeline = /*#__PURE__*/function (_TimelineEventsEmitte) {
   }, {
     key: "getKeyframesStripeSize",
     value: function getKeyframesStripeSize(row, rowY, minValue, maxValue) {
-      var keyframeLaneHeight = TimelineStyleUtils.rowStripeHeight(row, this.options.rowsStyle);
+      var stripeHeight = TimelineStyleUtils.rowStripeHeight(row, this.options.rowsStyle);
       var height = TimelineStyleUtils.getRowHeight(row, this.options.rowsStyle);
 
-      if (!keyframeLaneHeight && keyframeLaneHeight !== 0 || isNaN(keyframeLaneHeight) || keyframeLaneHeight == 'auto') {
-        keyframeLaneHeight = Math.floor(height * 0.8);
+      if (!stripeHeight && stripeHeight !== 0 || isNaN(stripeHeight) || stripeHeight == 'auto') {
+        stripeHeight = Math.floor(height * 0.8);
       }
 
-      if (keyframeLaneHeight > height) {
-        keyframeLaneHeight = height;
+      if (stripeHeight > height) {
+        stripeHeight = height;
       }
 
-      var margin = height - keyframeLaneHeight; // draw keyframes lane.
+      var margin = height - stripeHeight; // draw keyframes rows.
 
       var xMin = this.valToPx(minValue);
       var xMax = this.valToPx(maxValue);
       return {
         x: xMin,
         y: rowY + Math.floor(margin / 2),
-        height: keyframeLaneHeight,
+        height: stripeHeight,
         width: TimelineUtils.getDistance(xMin, xMax)
       };
     }
@@ -2516,21 +2549,34 @@ var timeline_Timeline = /*#__PURE__*/function (_TimelineEventsEmitte) {
         radius: radius
       };
     }
+    /**
+     * Apply container div size to the container.
+     */
+
   }, {
-    key: "rescale",
-    value: function rescale(newWidth, newHeight, scrollMode) {
+    key: "rescaleCanvas",
+    value: function rescaleCanvas() {
+      var changed = false;
       var width = this.scrollContainer.clientWidth * this.pixelRatio;
       var height = this.scrollContainer.clientHeight * this.pixelRatio;
 
       if (Math.floor(width) != Math.floor(this.ctx.canvas.width)) {
         this.ctx.canvas.width = width;
+        changed = true;
       }
 
       if (Math.floor(height) != Math.floor(this.ctx.canvas.height)) {
         this.ctx.canvas.height = height;
+        changed = true;
       }
 
       this.ctx.setTransform(this.pixelRatio, 0, 0, this.pixelRatio, 0, 0);
+      return changed;
+    }
+  }, {
+    key: "rescale",
+    value: function rescale(newWidth, newHeight, scrollMode) {
+      this.rescaleCanvas();
       var data = this.calculateRowsBounds();
 
       if (data && data.area) {
@@ -2567,7 +2613,7 @@ var timeline_Timeline = /*#__PURE__*/function (_TimelineEventsEmitte) {
       }
     }
     /**
-     * Find clickable elements under the current position.
+     * Find clickable elements under the mouse position.
      */
 
   }, {

Fichier diff supprimé car celui-ci est trop grand
+ 0 - 0
lib/animation-timeline.min.js


+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "animation-timeline-js",
-  "version": "2.0.0",
+  "version": "2.0.1",
   "description": "animation timeline control based on the canvas.",
   "main": "lib/animation-timeline.min.js",
   "types": "src/index.ts",

+ 48 - 4
src/timeline.ts

@@ -189,6 +189,36 @@ export class Timeline extends TimelineEventsEmitter {
     window.addEventListener('mouseup', this.handleMouseUpEvent, false);
     window.addEventListener('touchend', this.handleMouseUpEvent, false);
   }
+
+  public dispose(): void {
+    // Unsubscribe all events
+    this.offAll();
+    this.container = null;
+    this.canvas = null;
+    this.scrollContainer = null;
+    this.scrollContent = null;
+    this.ctx = null;
+    this.cleanUpSelection();
+
+    this.container.removeEventListener('wheel', this.handleWheelEvent);
+
+    if (this.scrollContainer) {
+      this.scrollContainer.removeEventListener('scroll', this.handleScrollEvent);
+    }
+
+    window.removeEventListener('blur', this.handleBlurEvent);
+    window.removeEventListener('resize', this.handleWindowResizeEvent);
+    document.removeEventListener('keydown', this.handleDocumentKeydownEvent);
+    this.canvas.removeEventListener('touchstart', this.handleMouseDownEvent);
+    this.canvas.removeEventListener('mousedown', this.handleMouseDownEvent);
+    window.removeEventListener('mousemove', this.handleMouseMoveEvent);
+    window.removeEventListener('touchmove', this.handleMouseMoveEvent);
+    window.removeEventListener('mouseup', this.handleMouseUpEvent);
+    window.removeEventListener('touchend', this.handleMouseUpEvent);
+    // Stop times
+    this.stopAutoPan();
+    this.clearScrollFinishedTimer();
+  }
   private handleBlurEvent = (): void => {
     this.cleanUpSelection();
   };
@@ -206,12 +236,14 @@ export class Timeline extends TimelineEventsEmitter {
     }
   };
 
-  private handleScrollEvent = (args: MouseEvent): void => {
+  private clearScrollFinishedTimer(): void {
     if (this.scrollFinishedTimerRef) {
       clearTimeout(this.scrollFinishedTimerRef);
       this.scrollFinishedTimerRef = null;
     }
-
+  }
+  private handleScrollEvent = (args: MouseEvent): void => {
+    this.clearScrollFinishedTimer();
     // Set a timeout to run event 'scrolling end'.
     this.scrollFinishedTimerRef = setTimeout(() => {
       if (!this.isPanStarted) {
@@ -1540,18 +1572,30 @@ export class Timeline extends TimelineEventsEmitter {
     } as MousePoint;
   }
 
-  private rescale(newWidth?: number, newHeight?: number, scrollMode?: string): void {
+  /**
+   * Apply container div size to the container.
+   */
+  private rescaleCanvas(): boolean {
+    let changed = false;
     const width = this.scrollContainer.clientWidth * this.pixelRatio;
     const height = this.scrollContainer.clientHeight * this.pixelRatio;
     if (Math.floor(width) != Math.floor(this.ctx.canvas.width)) {
       this.ctx.canvas.width = width;
+      changed = true;
     }
 
     if (Math.floor(height) != Math.floor(this.ctx.canvas.height)) {
       this.ctx.canvas.height = height;
+      changed = true;
     }
 
     this.ctx.setTransform(this.pixelRatio, 0, 0, this.pixelRatio, 0, 0);
+
+    return changed;
+  }
+
+  private rescale(newWidth?: number, newHeight?: number, scrollMode?: string): void {
+    this.rescaleCanvas();
     const data = this.calculateRowsBounds();
     if (data && data.area) {
       const additionalOffset = this.options.stepPx;
@@ -1592,7 +1636,7 @@ export class Timeline extends TimelineEventsEmitter {
   }
 
   /**
-   * Find clickable elements under the current position.
+   * Find clickable elements under the mouse position.
    */
   private getDraggable(pos: MousePoint): TimelineDraggableData {
     // few extra pixels to select items:

+ 5 - 5
src/timelineEventsEmitter.ts

@@ -4,7 +4,7 @@ interface Event {
 }
 
 export class TimelineEventsEmitter {
-  private subscriptions: Array<Event> = [];
+  protected _subscriptions: Array<Event> = [];
 
   // on event.
   on(topic: string, callback: Function): void {
@@ -12,7 +12,7 @@ export class TimelineEventsEmitter {
       return;
     }
 
-    this.subscriptions.push({
+    this._subscriptions.push({
       topic: topic,
       callback: callback,
     });
@@ -21,7 +21,7 @@ export class TimelineEventsEmitter {
    * Remove an event from the subscriptions list.
    */
   off(topic: string, callback: Function): void {
-    this.subscriptions = this.subscriptions.filter((event) => {
+    this._subscriptions = this._subscriptions.filter((event) => {
       return event && event.callback != callback && event.topic != topic;
     });
   }
@@ -30,13 +30,13 @@ export class TimelineEventsEmitter {
    * Unsubscribe all
    */
   offAll(): void {
-    this.subscriptions.length = 0;
+    this._subscriptions.length = 0;
   }
 
   // emit event.
   // eslint-disable-next-line @typescript-eslint/no-explicit-any
   emit(topic: string, args: any): void {
-    this.subscriptions.forEach((event) => {
+    this._subscriptions.forEach((event) => {
       if (event && event.topic == topic && event.callback) {
         event.callback(args);
       }

+ 2 - 5
tsconfig.json

@@ -10,8 +10,5 @@
     "strict": false,
     "declaration": true
   },
-  "exclude": [
-    "node_modules",
-    "dist"
-  ]
-}
+  "exclude": ["node_modules", "dist"]
+}

+ 1 - 1
webpack.config.js

@@ -24,5 +24,5 @@ module.exports = {
     // eslint-disable-next-line no-undef
     path: path.resolve(__dirname, 'lib'),
   },
-  plugins:[new UnminifiedWebpackPlugin()]
+  plugins: [new UnminifiedWebpackPlugin()],
 };

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff