tentone 5 年之前
父節點
當前提交
c90af81372
共有 4 個文件被更改,包括 51 次插入19 次删除
  1. 2 1
      source/Escher.js
  2. 46 17
      source/Renderer.js
  3. 1 1
      source/input/Pointer.js
  4. 2 0
      source/utils/AnimationTimer.js

+ 2 - 1
source/Escher.js

@@ -1,4 +1,4 @@
-export {EventManager} from "./EventManager.js";
+export {EventManager} from "./utils/EventManager.js";
 export {Object2D} from "./Object2D.js";
 export {Renderer} from "./Renderer.js";
 export {Viewport} from "./Viewport.js";
@@ -33,5 +33,6 @@ export {NodeGraph} from "./objects/node/NodeGraph.js";
 
 export {ViewportControls} from "./controls/ViewportControls.js";
 
+export {AnimationTimer} from "./utils/AnimationTimer.js";
 export {Helpers} from "./utils/Helpers.js";
 export {FileUtils} from "./utils/FileUtils.js";

+ 46 - 17
source/Renderer.js

@@ -1,39 +1,54 @@
 import {Pointer} from "./input/Pointer.js";
 import {ViewportControls} from "./controls/ViewportControls.js";
+import {AnimationTimer} from "./utils/AnimationTimer";
 
 /**
  * The renderer is responsible for drawing the objects structure into the canvas element and manage its rendering state.
  *
+ * Object are updated by the renderer before drawing, the renderer sorts the objects by layer, checks for pointer events and draw the objects into the screen.
+ *
+ * Input handling is also performed by the renderer (it is also used for the event handling).
+ *
  * @class
- * @param {Element} canvas Canvas to render the content.
+ * @param {Element} canvas Canvas to render the content to.
  * @param {Object} options Renderer canvas options.
  */
 function Renderer(canvas, options)
 {
 	if(options === undefined)
 	{
-		options = 
+		options =
 		{
-			alpha: true
+			alpha: true,
+			imageSmoothingEnabled: true,
+			imageSmoothingQuality: "low",
+			globalCompositeOperation: "source-over"
 		};
 	}
 
 	/**
-	 * Canvas DOM element, has to be managed by the user.
+	 * Canvas DOM element, the user needs to manage the canvas state.
+	 *
+	 * The canvas size (width and height) should always match its actual display size (adjusted for the device pixel ratio).
 	 */
 	this.canvas = canvas;
 
 	/**
 	 * Canvas 2D rendering context used to draw content.
+	 *
+	 * The options passed thought the constructor are applied to the context created.
 	 */
-	this.context = canvas.getContext("2d", {alpha: options.alpha});
-	this.context.imageSmoothingEnabled = true;
-	this.context.globalCompositeOperation = "source-over";
+	this.context = this.canvas.getContext("2d", {alpha: options.alpha});
+	this.context.imageSmoothingEnabled = options.imageSmoothingEnabled;
+	this.context.imageSmoothingQuality = options.imageSmoothingQuality;
+	this.context.globalCompositeOperation = options.globalCompositeOperation;
 
 	/**
-	 * Pointer input handler object.
+	 * Pointer input handler object, automatically updated by the renderer.
+	 *
+	 * The pointer is attached to the DOM window and to the canvas provided by the user.
 	 */
-	this.pointer = new Pointer(window, canvas);
+	this.pointer = new Pointer(window, this.canvas);
 
 	/**
 	 * Indicates if the canvas should be automatically cleared before new frame is drawn.
@@ -46,18 +61,21 @@ function Renderer(canvas, options)
 /**
  * Creates a infinite render loop to render the group into a viewport each frame.
  *
- * The render loop cannot be destroyed, and it automatically creates a viewport controls object.
+ * Automatically creates a viewport controls object, used for the user to control the viewport.
+ *
+ * The render loop can be accessed trough the animation timer returned. Should be stopped when no longer necessary to prevent memory/code leaks.
  *
- * @param {Object2D} group Group to be rendered.
- * @param {Viewport} viewport Viewport into the objects.
- * @param {Function} onUpdate Function called before rendering the frame.
+ * @param {Object2D} group Object to be rendered, alongside with all its children. Object2D can be used as a container to group objects.
+ * @param {Viewport} viewport Viewport into the scene.
+ * @param {Function} onUpdate Function called before rendering the frame, can be used for additional logic code. Object logic should be directly written in the update method of objects.
+ * @return {AnimationTimer} Animation timer created for this render loop. Should be stopped when no longer necessary.
  */
 Renderer.prototype.createRenderLoop = function(group, viewport, onUpdate)
 {
 	var self = this;
-	var controls = new ViewportControls(viewport);
 
-	function loop()
+	var controls = new ViewportControls(viewport);
+	var timer = new AnimationTimer(function()
 	{
 		if(onUpdate !== undefined)
 		{
@@ -67,9 +85,20 @@ Renderer.prototype.createRenderLoop = function(group, viewport, onUpdate)
 		controls.update(self.pointer);
 		self.update(group, viewport);
 		requestAnimationFrame(loop);
-	}
+	});
+	timer.start();
+
+	return timer;
+};
 
-	loop();
+/**
+ * Dispose the renderer object, clears the pointer events attached to the window/canvas.
+ *
+ * Should be called if the renderer is no longer in use to prevent code/memory leaks.
+ */
+Renderer.prototype.dispose = function(group, viewport, onUpdate)
+{
+	this.pointer.dispose();
 };
 
 /**

+ 1 - 1
source/input/Pointer.js

@@ -1,4 +1,4 @@
-import {EventManager} from "../EventManager.js";
+import {EventManager} from "../utils/EventManager.js";
 import {Vector2} from "../math/Vector2.js";
 import {Key} from "./Key.js";
 

+ 2 - 0
source/utils/AnimationTimer.js

@@ -66,3 +66,5 @@ AnimationTimer.prototype.stop = function()
 	this.running = false;
 	cancelAnimationFrame(this.id);
 };
+
+export {AnimationTimer};