diff --git a/src/js/Events.js b/src/js/Events.js index fb2203a3..21eb133b 100644 --- a/src/js/Events.js +++ b/src/js/Events.js @@ -5,6 +5,7 @@ var Events = { SELECT_TOOL : "SELECT_TOOL", TOOL_RELEASED : "TOOL_RELEASED", + TOOL_PRESSED : "TOOL_PRESSED", SELECT_PRIMARY_COLOR: "SELECT_PRIMARY_COLOR", SELECT_SECONDARY_COLOR: "SELECT_SECONDARY_COLOR", PRIMARY_COLOR_SELECTED : 'PRIMARY_COLOR_SELECTED', diff --git a/src/js/controller/AnimatedPreviewController.js b/src/js/controller/AnimatedPreviewController.js index 43269e4a..9d5f2eb4 100644 --- a/src/js/controller/AnimatedPreviewController.js +++ b/src/js/controller/AnimatedPreviewController.js @@ -1,5 +1,5 @@ (function () { - var ns = $.namespace("pskl.controller"); + var ns = $.namespace('pskl.controller'); // Preview is a square of PREVIEW_SIZE x PREVIEW_SIZE var PREVIEW_SIZE = 200; @@ -11,6 +11,11 @@ this.elapsedTime = 0; this.currentIndex = 0; + this.renderFlag = true; + + this.fpsRangeInput = $('#preview-fps'); + this.fpsCounterDisplay = $('#display-fps'); + this.setFPS(Constants.DEFAULT.FPS); var frame = this.piskelController.getCurrentFrame(); @@ -22,10 +27,10 @@ // the oninput event won't work on IE10 unfortunately, but at least will provide a // consistent behavior across all other browsers that support the input type range // see https://bugzilla.mozilla.org/show_bug.cgi?id=853670 - $("#preview-fps").on('input change', this.onFPSSliderChange.bind(this)); - document.querySelector(".right-column").style.width = Constants.ANIMATED_PREVIEW_WIDTH + 'px'; + this.fpsRangeInput.on('input change', this.onFPSSliderChange.bind(this)); + document.querySelector('.right-column').style.width = Constants.ANIMATED_PREVIEW_WIDTH + 'px'; - this.toggleOnionSkinEl = document.querySelector(".preview-toggle-onion-skin"); + this.toggleOnionSkinEl = document.querySelector('.preview-toggle-onion-skin'); this.toggleOnionSkinEl.addEventListener('click', this.toggleOnionSkin_.bind(this)); pskl.app.shortcutService.addShortcut('alt+O', this.toggleOnionSkin_.bind(this)); @@ -33,6 +38,9 @@ $.subscribe(Events.FRAME_SIZE_CHANGED, this.onFrameSizeChange_.bind(this)); $.subscribe(Events.USER_SETTINGS_CHANGED, $.proxy(this.onUserSettingsChange_, this)); + $.subscribe(Events.TOOL_RELEASED, this.setRenderFlag_.bind(this, true)); + $.subscribe(Events.TOOL_PRESSED, this.setRenderFlag_.bind(this, false)); + this.updateZoom_(); this.updateOnionSkinPreview_(); this.updateContainerDimensions_(); @@ -78,14 +86,16 @@ }; ns.AnimatedPreviewController.prototype.onFPSSliderChange = function (evt) { - this.setFPS(parseInt($("#preview-fps")[0].value, 10)); + this.setFPS(parseInt(this.fpsRangeInput[0].value, 10)); + }; ns.AnimatedPreviewController.prototype.setFPS = function (fps) { - if (fps) { + if (typeof fps === 'number') { this.fps = fps; - $("#preview-fps").val(this.fps); - $("#display-fps").html(this.fps + " FPS"); + this.fpsRangeInput.val(this.fps); + this.fpsRangeInput.blur(); + this.fpsCounterDisplay.html(this.fps + ' FPS'); } }; @@ -94,7 +104,24 @@ }; ns.AnimatedPreviewController.prototype.render = function (delta) { - this.elapsedTime += delta; + if (this.renderFlag) { + this.elapsedTime += delta; + if (this.fps === 0) { + this._renderSelectedFrame(); + } else { + this._renderCurrentAnimationFrame(); + } + } + }; + + ns.AnimatedPreviewController.prototype._renderSelectedFrame = function (delta) { + // the selected frame is the currentFrame from the PiskelController perspective + var selectedFrameIndex = this.piskelController.getCurrentFrameIndex(); + var selectedFrame = this.piskelController.getFrameAt(selectedFrameIndex); + this.renderer.render(selectedFrame); + }; + + ns.AnimatedPreviewController.prototype._renderCurrentAnimationFrame = function (delta) { var index = Math.floor(this.elapsedTime / (1000/this.fps)); if (index != this.currentIndex) { this.currentIndex = index; @@ -112,9 +139,8 @@ */ ns.AnimatedPreviewController.prototype.calculateZoom_ = function () { var frame = this.piskelController.getCurrentFrame(); - var previewSize = 200, - hZoom = previewSize / frame.getHeight(), - wZoom = previewSize / frame.getWidth(); + var hZoom = PREVIEW_SIZE / frame.getHeight(), + wZoom = PREVIEW_SIZE / frame.getWidth(); return Math.min(hZoom, wZoom); }; @@ -139,16 +165,21 @@ width = frame.getWidth() * zoom; } - containerEl.style.height = height + "px"; - containerEl.style.width = width + "px"; + containerEl.style.height = height + 'px'; + containerEl.style.width = width + 'px'; var horizontalPadding = (PREVIEW_SIZE - height) / 2; - containerEl.style.marginTop = horizontalPadding + "px"; - containerEl.style.marginBottom = horizontalPadding + "px"; + containerEl.style.marginTop = horizontalPadding + 'px'; + containerEl.style.marginBottom = horizontalPadding + 'px'; var verticalPadding = (PREVIEW_SIZE - width) / 2; - containerEl.style.marginLeft = verticalPadding + "px"; - containerEl.style.marginRight = verticalPadding + "px"; + containerEl.style.marginLeft = verticalPadding + 'px'; + containerEl.style.marginRight = verticalPadding + 'px'; + }; + + ns.AnimatedPreviewController.prototype.setRenderFlag_ = function (bool) { + console.log('setRenderFlag_', bool); + this.renderFlag = bool; }; ns.AnimatedPreviewController.prototype.toggleOnionSkin_ = function () { diff --git a/src/js/controller/DrawingController.js b/src/js/controller/DrawingController.js index f8fa153f..f6ed0653 100644 --- a/src/js/controller/DrawingController.js +++ b/src/js/controller/DrawingController.js @@ -31,8 +31,6 @@ "yOffset" : 0 }; - console.log('DrawingController:getContainerWidth_', this.getContainerWidth_()); - this.overlayRenderer = new pskl.rendering.frame.CachedFrameRenderer(this.container, renderingOptions, ["canvas-overlay"]); this.renderer = new pskl.rendering.frame.CachedFrameRenderer(this.container, renderingOptions, ["drawing-canvas"]); this.onionSkinRenderer = new pskl.rendering.OnionSkinRenderer(this.container, renderingOptions, piskelController); @@ -153,7 +151,7 @@ this.dragHandler.startDrag(event.clientX, event.clientY); } else { this.currentToolBehavior.hideHighlightedPixel(this.overlayFrame); - + $.publish(Events.TOOL_PRESSED); this.currentToolBehavior.applyToolAt( coords.x, coords.y, diff --git a/src/js/model/frame/CachedFrameProcessor.js b/src/js/model/frame/CachedFrameProcessor.js index 4f884b91..7e20b9d4 100644 --- a/src/js/model/frame/CachedFrameProcessor.js +++ b/src/js/model/frame/CachedFrameProcessor.js @@ -65,7 +65,7 @@ if (cache[cacheKey]) { processedFrame = cache[cacheKey]; } else { - var frameAsString = JSON.stringify(frame.getPixels()); + var frameAsString = pskl.utils.hashCode(JSON.stringify(frame.getPixels())); if (cache[frameAsString]) { processedFrame = this.outputCloner(cache[frameAsString], frame); } else { diff --git a/src/js/rendering/frame/FrameRenderer.js b/src/js/rendering/frame/FrameRenderer.js index ee746b75..9a0eaa74 100644 --- a/src/js/rendering/frame/FrameRenderer.js +++ b/src/js/rendering/frame/FrameRenderer.js @@ -164,13 +164,6 @@ } }; - ns.FrameRenderer.prototype.renderPixel_ = function (color, x, y, context) { - if(color != Constants.TRANSPARENT_COLOR) { - context.fillStyle = color; - context.fillRect(x, y, 1, 1); - } - }; - /** * Transform a screen pixel-based coordinate (relative to the top-left corner of the rendered * frame) into a sprite coordinate in column and row. @@ -264,4 +257,11 @@ } displayContext.restore(); }; + + ns.FrameRenderer.prototype.renderPixel_ = function (color, x, y, context) { + if(color != Constants.TRANSPARENT_COLOR) { + context.fillStyle = color; + context.fillRect(x, y, 1, 1); + } + }; })(); \ No newline at end of file diff --git a/src/js/utils/core.js b/src/js/utils/core.js index 2fd92c14..af71c3de 100644 --- a/src/js/utils/core.js +++ b/src/js/utils/core.js @@ -89,6 +89,18 @@ if (!Function.prototype.bind) { } }; + ns.hashCode = function(str) { + var hash = 0; + if (str.length !== 0) { + for (var i = 0, l = str.length; i < l; i++) { + var chr = str.charCodeAt(i); + hash = ((hash << 5) - hash) + chr; + hash |= 0; // Convert to 32bit integer + } + } + return hash; + }; + var entityMap = { "&": "&", "<": "<", @@ -97,7 +109,6 @@ if (!Function.prototype.bind) { "'": ''', "/": '/' }; - ns.escapeHtml= function (string) { return String(string).replace(/[&<>"'\/]/g, function (s) { return entityMap[s]; diff --git a/src/templates/preview.html b/src/templates/preview.html index b0bfe93e..7c01cca4 100644 --- a/src/templates/preview.html +++ b/src/templates/preview.html @@ -10,6 +10,6 @@ data-placement="bottom" class="piskel-icon-onion preview-toggle-onion-skin"> - + \ No newline at end of file