diff --git a/src/js/controller/PreviewFilmController.js b/src/js/controller/PreviewFilmController.js index 5366b7bb..86ff0b1f 100644 --- a/src/js/controller/PreviewFilmController.js +++ b/src/js/controller/PreviewFilmController.js @@ -1,8 +1,6 @@ (function () { var ns = $.namespace("pskl.controller"); - var CACHE_RESET_INTERVAL = 1000 * 60 * 10; - var ACTION = { SELECT : 'select', CLONE : 'clone', @@ -18,8 +16,9 @@ this.redrawFlag = true; - this.cache_ = {}; - window.setInterval(function () {this.cache_ = {};}.bind(this), CACHE_RESET_INTERVAL); + this.cachedImageProcessor = new pskl.model.frame.CachedFrameProcessor(); + this.cachedImageProcessor.setFrameProcessor(this.frameToPreviewCanvas_.bind(this)); + this.cachedImageProcessor.setOutputCloner(this.clonePreviewCanvas_.bind(this)); }; ns.PreviewFilmController.prototype.init = function() { @@ -44,7 +43,6 @@ ns.PreviewFilmController.prototype.render = function () { if (this.redrawFlag) { - // TODO(vincz): Full redraw on any drawing modification, optimize. this.createPreviews_(); this.redrawFlag = false; } @@ -209,26 +207,25 @@ }; ns.PreviewFilmController.prototype.getCanvasForFrame = function (frame) { - var canvas = null; - var cacheKey = frame.getHash() + this.zoom; - if (this.cache_[cacheKey]) { - canvas = this.cache_[cacheKey]; - } else { - var frameAsString = JSON.stringify(frame.getPixels()); - if (this.cache_[frameAsString]) { - canvas = pskl.CanvasUtils.clone(this.cache_[frameAsString]); - } else { - var canvasRenderer = new pskl.rendering.CanvasRenderer(frame, this.zoom); - canvasRenderer.drawTransparentAs(Constants.TRANSPARENT_COLOR); - canvas = canvasRenderer.render(); - this.cache_[frameAsString] = canvas; - } - canvas.classList.add('tile-view', 'canvas'); - this.cache_[cacheKey] = canvas; - } + var canvas = this.cachedImageProcessor.get(frame, this.zoom); + canvas.classList.add('tile-view', 'canvas'); return canvas; }; + ns.PreviewFilmController.prototype.frameToPreviewCanvas_ = function (frame) { + var canvasRenderer = new pskl.rendering.CanvasRenderer(frame, this.zoom); + canvasRenderer.drawTransparentAs(Constants.TRANSPARENT_COLOR); + var canvas = canvasRenderer.render(); + canvas.classList.add('tile-view', 'canvas'); + return canvas; + }; + + ns.PreviewFilmController.prototype.clonePreviewCanvas_ = function (canvas) { + var clone = pskl.CanvasUtils.clone(canvas); + clone.classList.add('tile-view', 'canvas'); + return clone; + }; + /** * Calculate the preview zoom depending on the piskel size */ diff --git a/src/js/model/frame/CachedFrameProcessor.js b/src/js/model/frame/CachedFrameProcessor.js new file mode 100644 index 00000000..cb44e8af --- /dev/null +++ b/src/js/model/frame/CachedFrameProcessor.js @@ -0,0 +1,60 @@ +(function () { + var ns = $.namespace('pskl.model.frame'); + + var DEFAULT_RESET_INTERVAL = 10 * 60 *1000; + + var DEFAULT_FRAME_PROCESSOR = function (frame) { + return pskl.utils.FrameUtils.toImage(frame); + }; + + var DEFAULT_OUTPUT_CLONER = function (o) {return o;}; + + var DEFAULT_NAMESPACE = '__cache_default__'; + + ns.CachedFrameProcessor = function (cacheResetInterval) { + this.cache_ = {}; + this.cacheResetInterval = cacheResetInterval || DEFAULT_RESET_INTERVAL; + this.frameProcessor = DEFAULT_FRAME_PROCESSOR; + this.outputCloner = DEFAULT_OUTPUT_CLONER; + + window.setInterval(this.clear.bind(this), this.cacheResetInterval); + }; + + ns.CachedFrameProcessor.prototype.clear = function () { + this.cache_ = {}; + }; + + ns.CachedFrameProcessor.prototype.setFrameProcessor = function (frameProcessor) { + this.frameProcessor = frameProcessor; + }; + + ns.CachedFrameProcessor.prototype.setOutputCloner = function (outputCloner) { + this.outputCloner = outputCloner; + }; + + ns.CachedFrameProcessor.prototype.get = function (frame, namespace) { + var processedFrame = null; + namespace = namespace || DEFAULT_NAMESPACE; + + if (!this.cache_[namespace]) { + this.cache_[namespace] = {}; + } + + var cache = this.cache_[namespace]; + + var cacheKey = frame.getHash(); + if (this.cache_[cacheKey]) { + processedFrame = this.cache_[cacheKey]; + } else { + var frameAsString = JSON.stringify(frame.getPixels()); + if (this.cache_[frameAsString]) { + processedFrame = this.outputCloner(this.cache_[frameAsString]); + } else { + processedFrame = this.frameProcessor(frame); + this.cache_[frameAsString] = processedFrame; + } + this.cache_[cacheKey] = processedFrame; + } + return processedFrame; + }; +})(); \ No newline at end of file diff --git a/src/js/rendering/frame/TiledFrameRenderer.js b/src/js/rendering/frame/TiledFrameRenderer.js index ce8a3c9a..637c1ba1 100644 --- a/src/js/rendering/frame/TiledFrameRenderer.js +++ b/src/js/rendering/frame/TiledFrameRenderer.js @@ -1,8 +1,6 @@ (function () { var ns = $.namespace('pskl.rendering.frame'); - var CACHE_RESET_INTERVAL = 1000 * 60 * 10; - ns.TiledFrameRenderer = function (container, zoom) { this.container = container; this.setZoom(zoom); @@ -11,30 +9,18 @@ this.displayContainer.classList.add('tiled-frame-container'); container.get(0).appendChild(this.displayContainer); - this.cache_ = {}; - window.setInterval(function () {this.cache_ = {};}.bind(this), CACHE_RESET_INTERVAL); + this.cachedImageProcessor = new pskl.model.frame.CachedFrameProcessor(); + this.cachedImageProcessor.setFrameProcessor(this.frameToDataUrl_.bind(this)); + }; + + ns.TiledFrameRenderer.prototype.frameToDataUrl_ = function (frame) { + var canvas = new pskl.utils.FrameUtils.toImage(frame, this.zoom); + return canvas.toDataURL('image/png'); }; ns.TiledFrameRenderer.prototype.render = function (frame) { - var frameData = null; - - var hash = frame.getHash(); - if (this.cache_[hash]) { - frameData = this.cache_[hash]; - } else { - var frameAsString = JSON.stringify(frame.getPixels()); - if (this.cache_[frameAsString]) { - frameData = this.cache_[frameAsString]; - } else { - var canvas = new pskl.utils.FrameUtils.toImage(frame, this.zoom); - frameData = canvas.toDataURL('image/png'); - this.cache_[frameAsString] = frameData; - } - - this.cache_[hash] = frameData; - } - - this.displayContainer.style.backgroundImage = 'url(' + frameData + ')'; + var imageSrc = this.cachedImageProcessor.get(frame, this.zoom); + this.displayContainer.style.backgroundImage = 'url(' + imageSrc + ')'; }; ns.TiledFrameRenderer.prototype.show = function () { diff --git a/src/piskel-script-list.js b/src/piskel-script-list.js index 12a8e832..8891340f 100644 --- a/src/piskel-script-list.js +++ b/src/piskel-script-list.js @@ -47,6 +47,7 @@ "js/model/Frame.js", "js/model/Layer.js", "js/model/piskel/Descriptor.js", + "js/model/frame/CachedFrameProcessor.js", "js/model/Piskel.js", // Selection