mirror of
https://github.com/piskelapp/piskel.git
synced 2023-08-10 21:12:52 +03:00
Update gh-pages after PR merge : zoom-level, keyboard-shortcuts, model-size
This commit is contained in:
22
js/rendering/AbstractRenderer.js
Normal file
22
js/rendering/AbstractRenderer.js
Normal file
@ -0,0 +1,22 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.rendering');
|
||||
|
||||
ns.AbstractRenderer = function () {};
|
||||
|
||||
ns.AbstractRenderer.prototype.clear = Constants.ABSTRACT_FUNCTION;
|
||||
|
||||
ns.AbstractRenderer.prototype.getCoordinates = Constants.ABSTRACT_FUNCTION;
|
||||
|
||||
ns.AbstractRenderer.prototype.setGridEnabled = Constants.ABSTRACT_FUNCTION;
|
||||
ns.AbstractRenderer.prototype.isGridEnabled = Constants.ABSTRACT_FUNCTION;
|
||||
|
||||
ns.AbstractRenderer.prototype.setZoom = Constants.ABSTRACT_FUNCTION;
|
||||
ns.AbstractRenderer.prototype.getZoom = Constants.ABSTRACT_FUNCTION;
|
||||
|
||||
ns.AbstractRenderer.prototype.moveOffset = Constants.ABSTRACT_FUNCTION;
|
||||
ns.AbstractRenderer.prototype.setOffset = Constants.ABSTRACT_FUNCTION;
|
||||
ns.AbstractRenderer.prototype.getOffset = Constants.ABSTRACT_FUNCTION;
|
||||
|
||||
ns.AbstractRenderer.prototype.setDisplaySize = Constants.ABSTRACT_FUNCTION;
|
||||
ns.AbstractRenderer.prototype.getDisplaySize = Constants.ABSTRACT_FUNCTION;
|
||||
})();
|
@ -1,36 +1,43 @@
|
||||
(function () {
|
||||
|
||||
var ns = $.namespace("pskl.rendering");
|
||||
ns.CanvasRenderer = function (frame, dpi) {
|
||||
this.frame = frame;
|
||||
this.dpi = dpi;
|
||||
};
|
||||
var ns = $.namespace("pskl.rendering");
|
||||
ns.CanvasRenderer = function (frame, zoom) {
|
||||
this.frame = frame;
|
||||
this.zoom = zoom;
|
||||
this.transparentColor_ = 'white';
|
||||
};
|
||||
|
||||
ns.CanvasRenderer.prototype.render = function (frame, dpi) {
|
||||
var canvas = this.createCanvas_();
|
||||
var context = canvas.getContext('2d');
|
||||
for(var col = 0, width = this.frame.getWidth(); col < width; col++) {
|
||||
for(var row = 0, height = this.frame.getHeight(); row < height; row++) {
|
||||
var color = this.frame.getPixel(col, row);
|
||||
this.renderPixel_(color, col, row, context);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Decide which color should be used to represent transparent pixels
|
||||
* Default : white
|
||||
* @param {String} color the color to use either as '#ABCDEF' or 'red' or 'rgb(x,y,z)' or 'rgba(x,y,z,a)'
|
||||
*/
|
||||
ns.CanvasRenderer.prototype.drawTransparentAs = function (color) {
|
||||
this.transparentColor_ = color;
|
||||
};
|
||||
|
||||
return context;
|
||||
};
|
||||
ns.CanvasRenderer.prototype.render = function () {
|
||||
var canvas = this.createCanvas_();
|
||||
var context = canvas.getContext('2d');
|
||||
|
||||
ns.CanvasRenderer.prototype.renderPixel_ = function (color, col, row, context) {
|
||||
if(color == Constants.TRANSPARENT_COLOR) {
|
||||
color = "#FFF";
|
||||
}
|
||||
this.frame.forEachPixel(function (color, x, y) {
|
||||
this.renderPixel_(color, x, y, context);
|
||||
}.bind(this));
|
||||
|
||||
context.fillStyle = color;
|
||||
context.fillRect(col * this.dpi, row * this.dpi, this.dpi, this.dpi);
|
||||
};
|
||||
return canvas;
|
||||
};
|
||||
|
||||
ns.CanvasRenderer.prototype.createCanvas_ = function () {
|
||||
var width = this.frame.getWidth() * this.dpi;
|
||||
var height = this.frame.getHeight() * this.dpi;
|
||||
return pskl.CanvasUtils.createCanvas(width, height);
|
||||
};
|
||||
ns.CanvasRenderer.prototype.renderPixel_ = function (color, x, y, context) {
|
||||
if(color == Constants.TRANSPARENT_COLOR) {
|
||||
color = this.transparentColor_;
|
||||
}
|
||||
context.fillStyle = color;
|
||||
context.fillRect(x * this.zoom, y * this.zoom, this.zoom, this.zoom);
|
||||
};
|
||||
|
||||
ns.CanvasRenderer.prototype.createCanvas_ = function () {
|
||||
var width = this.frame.getWidth() * this.zoom;
|
||||
var height = this.frame.getHeight() * this.zoom;
|
||||
return pskl.CanvasUtils.createCanvas(width, height);
|
||||
};
|
||||
})();
|
75
js/rendering/CompositeRenderer.js
Normal file
75
js/rendering/CompositeRenderer.js
Normal file
@ -0,0 +1,75 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.rendering');
|
||||
|
||||
ns.CompositeRenderer = function () {
|
||||
this.renderers = [];
|
||||
};
|
||||
|
||||
pskl.utils.inherit(pskl.rendering.CompositeRenderer, pskl.rendering.AbstractRenderer);
|
||||
|
||||
ns.CompositeRenderer.prototype.add = function (renderer) {
|
||||
this.renderers.push(renderer);
|
||||
return this;
|
||||
};
|
||||
|
||||
ns.CompositeRenderer.prototype.clear = function () {
|
||||
this.renderers.forEach(function (renderer) {
|
||||
renderer.clear();
|
||||
});
|
||||
};
|
||||
|
||||
ns.CompositeRenderer.prototype.setZoom = function (zoom) {
|
||||
this.renderers.forEach(function (renderer) {
|
||||
renderer.setZoom(zoom);
|
||||
});
|
||||
};
|
||||
|
||||
ns.CompositeRenderer.prototype.getZoom = function () {
|
||||
return this.getSampleRenderer_().getZoom();
|
||||
};
|
||||
|
||||
ns.CompositeRenderer.prototype.setDisplaySize = function (w, h) {
|
||||
this.renderers.forEach(function (renderer) {
|
||||
renderer.setDisplaySize(w, h);
|
||||
});
|
||||
};
|
||||
|
||||
ns.CompositeRenderer.prototype.getDisplaySize = function () {
|
||||
return this.getSampleRenderer_().getDisplaySize();
|
||||
};
|
||||
|
||||
ns.CompositeRenderer.prototype.moveOffset = function (x, y) {
|
||||
this.renderers.forEach(function (renderer) {
|
||||
renderer.moveOffset(x, y);
|
||||
});
|
||||
};
|
||||
|
||||
ns.CompositeRenderer.prototype.setOffset = function (x, y) {
|
||||
this.renderers.forEach(function (renderer) {
|
||||
renderer.setOffset(x, y);
|
||||
});
|
||||
};
|
||||
|
||||
ns.CompositeRenderer.prototype.getOffset = function () {
|
||||
return this.getSampleRenderer_().getOffset();
|
||||
};
|
||||
|
||||
|
||||
ns.CompositeRenderer.prototype.setGridEnabled = function (b) {
|
||||
this.renderers.forEach(function (renderer) {
|
||||
renderer.setGridEnabled(b);
|
||||
});
|
||||
};
|
||||
|
||||
ns.CompositeRenderer.prototype.isGridEnabled = function () {
|
||||
return this.getSampleRenderer_().isGridEnabled();
|
||||
};
|
||||
|
||||
ns.CompositeRenderer.prototype.getSampleRenderer_ = function () {
|
||||
if (this.renderers.length > 0) {
|
||||
return this.renderers[0];
|
||||
} else {
|
||||
throw 'Renderer manager is empty';
|
||||
}
|
||||
};
|
||||
})();
|
@ -1,61 +1,61 @@
|
||||
(function () {
|
||||
var ns = $.namespace("pskl.rendering");
|
||||
var ns = $.namespace("pskl.rendering");
|
||||
|
||||
ns.DrawingLoop = function () {
|
||||
this.requestAnimationFrame = this.getRequestAnimationFrameShim_();
|
||||
this.isRunning = false;
|
||||
this.previousTime = 0;
|
||||
this.callbacks = [];
|
||||
};
|
||||
ns.DrawingLoop = function () {
|
||||
this.requestAnimationFrame = this.getRequestAnimationFrameShim_();
|
||||
this.isRunning = false;
|
||||
this.previousTime = 0;
|
||||
this.callbacks = [];
|
||||
};
|
||||
|
||||
ns.DrawingLoop.prototype.addCallback = function (callback, scope, args) {
|
||||
var callbackObj = {
|
||||
fn : callback,
|
||||
scope : scope,
|
||||
args : args
|
||||
};
|
||||
this.callbacks.push(callbackObj);
|
||||
return callbackObj;
|
||||
};
|
||||
ns.DrawingLoop.prototype.addCallback = function (callback, scope, args) {
|
||||
var callbackObj = {
|
||||
fn : callback,
|
||||
scope : scope,
|
||||
args : args
|
||||
};
|
||||
this.callbacks.push(callbackObj);
|
||||
return callbackObj;
|
||||
};
|
||||
|
||||
ns.DrawingLoop.prototype.removeCallback = function (callbackObj) {
|
||||
var index = this.callbacks.indexOf(callbackObj);
|
||||
if (index != -1) {
|
||||
this.callbacks.splice(index, 1);
|
||||
}
|
||||
};
|
||||
ns.DrawingLoop.prototype.removeCallback = function (callbackObj) {
|
||||
var index = this.callbacks.indexOf(callbackObj);
|
||||
if (index != -1) {
|
||||
this.callbacks.splice(index, 1);
|
||||
}
|
||||
};
|
||||
|
||||
ns.DrawingLoop.prototype.start = function () {
|
||||
this.isRunning = true;
|
||||
this.loop_();
|
||||
};
|
||||
ns.DrawingLoop.prototype.start = function () {
|
||||
this.isRunning = true;
|
||||
this.loop_();
|
||||
};
|
||||
|
||||
ns.DrawingLoop.prototype.loop_ = function () {
|
||||
var currentTime = Date.now();
|
||||
var delta = currentTime - this.previousTime;
|
||||
this.executeCallbacks_(delta);
|
||||
this.previousTime = currentTime;
|
||||
this.requestAnimationFrame.call(window, this.loop_.bind(this));
|
||||
};
|
||||
ns.DrawingLoop.prototype.loop_ = function () {
|
||||
var currentTime = Date.now();
|
||||
var delta = currentTime - this.previousTime;
|
||||
this.executeCallbacks_(delta);
|
||||
this.previousTime = currentTime;
|
||||
this.requestAnimationFrame.call(window, this.loop_.bind(this));
|
||||
};
|
||||
|
||||
ns.DrawingLoop.prototype.executeCallbacks_ = function (deltaTime) {
|
||||
for (var i = 0 ; i < this.callbacks.length ; i++) {
|
||||
var cb = this.callbacks[i];
|
||||
cb.fn.call(cb.scope, deltaTime, cb.args);
|
||||
}
|
||||
};
|
||||
ns.DrawingLoop.prototype.executeCallbacks_ = function (deltaTime) {
|
||||
for (var i = 0 ; i < this.callbacks.length ; i++) {
|
||||
var cb = this.callbacks[i];
|
||||
cb.fn.call(cb.scope, deltaTime, cb.args);
|
||||
}
|
||||
};
|
||||
|
||||
ns.DrawingLoop.prototype.stop = function () {
|
||||
this.isRunning = false;
|
||||
};
|
||||
ns.DrawingLoop.prototype.stop = function () {
|
||||
this.isRunning = false;
|
||||
};
|
||||
|
||||
ns.DrawingLoop.prototype.getRequestAnimationFrameShim_ = function () {
|
||||
var requestAnimationFrame = window.requestAnimationFrame ||
|
||||
window.mozRequestAnimationFrame ||
|
||||
window.webkitRequestAnimationFrame ||
|
||||
window.msRequestAnimationFrame ||
|
||||
function (callback) { window.setTimeout(callback, 1000/60); };
|
||||
ns.DrawingLoop.prototype.getRequestAnimationFrameShim_ = function () {
|
||||
var requestAnimationFrame = window.requestAnimationFrame ||
|
||||
window.mozRequestAnimationFrame ||
|
||||
window.webkitRequestAnimationFrame ||
|
||||
window.msRequestAnimationFrame ||
|
||||
function (callback) { window.setTimeout(callback, 1000/60); };
|
||||
|
||||
return requestAnimationFrame;
|
||||
};
|
||||
return requestAnimationFrame;
|
||||
};
|
||||
})();
|
43
js/rendering/FramesheetRenderer.js
Normal file
43
js/rendering/FramesheetRenderer.js
Normal file
@ -0,0 +1,43 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.rendering');
|
||||
|
||||
/**
|
||||
* Render an array of frames
|
||||
* @param {Array.<pskl.model.Frame>} frames
|
||||
*/
|
||||
ns.FramesheetRenderer = function (frames) {
|
||||
if (frames.length > 0) {
|
||||
this.frames = frames;
|
||||
} else {
|
||||
throw 'FramesheetRenderer : Invalid argument : frames is empty';
|
||||
}
|
||||
};
|
||||
|
||||
ns.FramesheetRenderer.prototype.renderAsCanvas = function () {
|
||||
var canvas = this.createCanvas_();
|
||||
for (var i = 0 ; i < this.frames.length ; i++) {
|
||||
var frame = this.frames[i];
|
||||
this.drawFrameInCanvas_(frame, canvas, i * frame.getWidth(), 0);
|
||||
}
|
||||
return canvas;
|
||||
};
|
||||
|
||||
ns.FramesheetRenderer.prototype.drawFrameInCanvas_ = function (frame, canvas, offsetWidth, offsetHeight) {
|
||||
var context = canvas.getContext('2d');
|
||||
frame.forEachPixel(function (color, x, y) {
|
||||
if(color != Constants.TRANSPARENT_COLOR) {
|
||||
context.fillStyle = color;
|
||||
context.fillRect(x + offsetWidth, y + offsetHeight, 1, 1);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
ns.FramesheetRenderer.prototype.createCanvas_ = function () {
|
||||
var sampleFrame = this.frames[0];
|
||||
var count = this.frames.length;
|
||||
var width = count * sampleFrame.getWidth();
|
||||
var height = sampleFrame.getHeight();
|
||||
return pskl.CanvasUtils.createCanvas(width, height);
|
||||
};
|
||||
|
||||
})();
|
14
js/rendering/PiskelRenderer.js
Normal file
14
js/rendering/PiskelRenderer.js
Normal file
@ -0,0 +1,14 @@
|
||||
(function () {
|
||||
|
||||
var ns = $.namespace("pskl.rendering");
|
||||
|
||||
ns.PiskelRenderer = function (piskelController) {
|
||||
var frames = [];
|
||||
for (var i = 0 ; i < piskelController.getFrameCount() ; i++) {
|
||||
frames.push(this.piskelController.getFrameAt(i));
|
||||
}
|
||||
ns.FramesheetRenderer.call(this, frames);
|
||||
};
|
||||
|
||||
pskl.utils.inherit(ns.PiskelRenderer, ns.FramesheetRenderer);
|
||||
})();
|
32
js/rendering/frame/CachedFrameRenderer.js
Normal file
32
js/rendering/frame/CachedFrameRenderer.js
Normal file
@ -0,0 +1,32 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.rendering.frame');
|
||||
|
||||
/**
|
||||
* FrameRenderer implementation that prevents unnecessary redraws.
|
||||
* @param {HtmlElement} container HtmlElement to use as parentNode of the Frame
|
||||
* @param {Object} renderingOptions
|
||||
* @param {Array} classes array of strings to use for css classes
|
||||
*/
|
||||
ns.CachedFrameRenderer = function (container, renderingOptions, classes) {
|
||||
pskl.rendering.frame.FrameRenderer.call(this, container, renderingOptions, classes);
|
||||
this.serializedFrame = '';
|
||||
};
|
||||
|
||||
pskl.utils.inherit(pskl.rendering.frame.CachedFrameRenderer, pskl.rendering.frame.FrameRenderer);
|
||||
|
||||
ns.CachedFrameRenderer.prototype.render = function (frame) {
|
||||
var offset = this.getOffset();
|
||||
var size = this.getDisplaySize();
|
||||
var serializedFrame = [
|
||||
this.getZoom(),
|
||||
this.isGridEnabled(),
|
||||
offset.x, offset.y,
|
||||
size.width, size.height,
|
||||
frame.serialize()
|
||||
].join('-');
|
||||
if (this.serializedFrame != serializedFrame) {
|
||||
this.serializedFrame = serializedFrame;
|
||||
this.superclass.render.call(this, frame);
|
||||
}
|
||||
};
|
||||
})();
|
259
js/rendering/frame/FrameRenderer.js
Normal file
259
js/rendering/frame/FrameRenderer.js
Normal file
@ -0,0 +1,259 @@
|
||||
(function () {
|
||||
var ns = $.namespace("pskl.rendering.frame");
|
||||
|
||||
/**
|
||||
* FrameRenderer will display a given frame inside a canvas element.
|
||||
* @param {HtmlElement} container HtmlElement to use as parentNode of the Frame
|
||||
* @param {Object} renderingOptions
|
||||
* @param {Array} classes array of strings to use for css classes
|
||||
*/
|
||||
ns.FrameRenderer = function (container, renderingOptions, classes) {
|
||||
this.defaultRenderingOptions = {
|
||||
'supportGridRendering' : false,
|
||||
'zoom' : 1
|
||||
};
|
||||
|
||||
renderingOptions = $.extend(true, {}, this.defaultRenderingOptions, renderingOptions);
|
||||
|
||||
if(container === undefined) {
|
||||
throw 'Bad FrameRenderer initialization. <container> undefined.';
|
||||
}
|
||||
|
||||
if(isNaN(renderingOptions.zoom)) {
|
||||
throw 'Bad FrameRenderer initialization. <zoom> not well defined.';
|
||||
}
|
||||
|
||||
this.container = container;
|
||||
|
||||
this.zoom = renderingOptions.zoom;
|
||||
|
||||
this.offset = {
|
||||
x : 0,
|
||||
y : 0
|
||||
};
|
||||
|
||||
this.margin = {
|
||||
x : 0,
|
||||
y : 0
|
||||
};
|
||||
|
||||
this.isGridEnabled_ = false;
|
||||
this.supportGridRendering = renderingOptions.supportGridRendering;
|
||||
|
||||
this.classes = classes || [];
|
||||
this.classes.push('canvas');
|
||||
|
||||
/**
|
||||
* Off dom canvas, will be used to draw the frame at 1:1 ratio
|
||||
* @type {HTMLElement}
|
||||
*/
|
||||
this.canvas = null;
|
||||
|
||||
/**
|
||||
* Displayed canvas, scaled-up from the offdom canvas
|
||||
* @type {HTMLElement}
|
||||
*/
|
||||
this.displayCanvas = null;
|
||||
this.setDisplaySize(renderingOptions.width, renderingOptions.height);
|
||||
|
||||
this.setGridEnabled(pskl.UserSettings.get(pskl.UserSettings.SHOW_GRID));
|
||||
|
||||
this.updateBackgroundClass_(pskl.UserSettings.get(pskl.UserSettings.CANVAS_BACKGROUND));
|
||||
$.subscribe(Events.USER_SETTINGS_CHANGED, $.proxy(this.onUserSettingsChange_, this));
|
||||
};
|
||||
|
||||
pskl.utils.inherit(pskl.rendering.frame.FrameRenderer, pskl.rendering.AbstractRenderer);
|
||||
|
||||
ns.FrameRenderer.prototype.render = function (frame) {
|
||||
if (frame) {
|
||||
this.clear();
|
||||
this.renderFrame_(frame);
|
||||
}
|
||||
};
|
||||
|
||||
ns.FrameRenderer.prototype.clear = function () {
|
||||
pskl.CanvasUtils.clear(this.canvas);
|
||||
pskl.CanvasUtils.clear(this.displayCanvas);
|
||||
};
|
||||
|
||||
ns.FrameRenderer.prototype.setZoom = function (zoom) {
|
||||
// back up center coordinates
|
||||
var centerX = this.offset.x + (this.displayWidth/(2*this.zoom));
|
||||
var centerY = this.offset.y + (this.displayHeight/(2*this.zoom));
|
||||
|
||||
this.zoom = Math.max(1, zoom);
|
||||
|
||||
// recenter
|
||||
this.setOffset(
|
||||
centerX - (this.displayWidth/(2*this.zoom)),
|
||||
centerY - (this.displayHeight/(2*this.zoom))
|
||||
);
|
||||
};
|
||||
|
||||
ns.FrameRenderer.prototype.getZoom = function () {
|
||||
return this.zoom;
|
||||
};
|
||||
|
||||
ns.FrameRenderer.prototype.setDisplaySize = function (width, height) {
|
||||
this.displayWidth = width;
|
||||
this.displayHeight = height;
|
||||
if (this.displayCanvas) {
|
||||
$(this.displayCanvas).remove();
|
||||
this.displayCanvas = null;
|
||||
}
|
||||
this.createDisplayCanvas_();
|
||||
};
|
||||
|
||||
ns.FrameRenderer.prototype.getDisplaySize = function () {
|
||||
return {
|
||||
height : this.displayHeight,
|
||||
width : this.displayWidth
|
||||
};
|
||||
};
|
||||
|
||||
ns.FrameRenderer.prototype.getOffset = function () {
|
||||
return {
|
||||
x : this.offset.x,
|
||||
y : this.offset.y
|
||||
};
|
||||
};
|
||||
|
||||
ns.FrameRenderer.prototype.moveOffset = function (x, y) {
|
||||
this.setOffset(this.offset.x + x, this.offset.y + y);
|
||||
};
|
||||
|
||||
ns.FrameRenderer.prototype.setOffset = function (x, y) {
|
||||
// TODO : provide frame size information to the FrameRenderer constructor
|
||||
// here I first need to verify I have a 'canvas' which I can use to infer the frame information
|
||||
// and then perform my boundaries checking. This sucks
|
||||
if (this.canvas) {
|
||||
var maxX = this.canvas.width - (this.displayWidth/this.zoom);
|
||||
x = pskl.utils.Math.minmax(x, 0, maxX);
|
||||
var maxY = this.canvas.height - (this.displayHeight/this.zoom);
|
||||
y = pskl.utils.Math.minmax(y, 0, maxY);
|
||||
}
|
||||
this.offset.x = x;
|
||||
this.offset.y = y;
|
||||
};
|
||||
|
||||
ns.FrameRenderer.prototype.setGridEnabled = function (flag) {
|
||||
this.isGridEnabled_ = flag && this.supportGridRendering;
|
||||
};
|
||||
|
||||
ns.FrameRenderer.prototype.isGridEnabled = function () {
|
||||
return this.isGridEnabled_;
|
||||
};
|
||||
|
||||
ns.FrameRenderer.prototype.updateMargins_ = function () {
|
||||
var deltaX = this.displayWidth - (this.zoom * this.canvas.width);
|
||||
this.margin.x = Math.max(0, deltaX) / 2;
|
||||
|
||||
var deltaY = this.displayHeight - (this.zoom * this.canvas.height);
|
||||
this.margin.y = Math.max(0, deltaY) / 2;
|
||||
};
|
||||
|
||||
ns.FrameRenderer.prototype.createDisplayCanvas_ = function () {
|
||||
var height = this.displayHeight;
|
||||
var width = this.displayWidth;
|
||||
|
||||
this.displayCanvas = pskl.CanvasUtils.createCanvas(width, height, this.classes);
|
||||
if (true || this.zoom > 2) {
|
||||
pskl.CanvasUtils.disableImageSmoothing(this.displayCanvas);
|
||||
}
|
||||
this.container.append(this.displayCanvas);
|
||||
};
|
||||
|
||||
ns.FrameRenderer.prototype.onUserSettingsChange_ = function (evt, settingName, settingValue) {
|
||||
if(settingName == pskl.UserSettings.SHOW_GRID) {
|
||||
this.setGridEnabled(settingValue);
|
||||
} else if (settingName == pskl.UserSettings.CANVAS_BACKGROUND) {
|
||||
this.updateBackgroundClass_(settingValue);
|
||||
}
|
||||
};
|
||||
|
||||
ns.FrameRenderer.prototype.updateBackgroundClass_ = function (newClass) {
|
||||
var currentClass = this.container.data('current-background-class');
|
||||
if (currentClass) {
|
||||
this.container.removeClass(currentClass);
|
||||
}
|
||||
this.container.addClass(newClass);
|
||||
this.container.data('current-background-class', newClass);
|
||||
};
|
||||
|
||||
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.
|
||||
* @public
|
||||
*/
|
||||
ns.FrameRenderer.prototype.getCoordinates = function(x, y) {
|
||||
var containerOffset = this.container.offset();
|
||||
x = x - containerOffset.left;
|
||||
y = y - containerOffset.top;
|
||||
|
||||
// apply margins
|
||||
x = x - this.margin.x;
|
||||
y = y - this.margin.y;
|
||||
|
||||
var cellSize = this.zoom;
|
||||
// apply frame offset
|
||||
x = x + this.offset.x * cellSize;
|
||||
y = y + this.offset.y * cellSize;
|
||||
|
||||
return {
|
||||
x : Math.floor(x / cellSize),
|
||||
y : Math.floor(y / cellSize)
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
ns.FrameRenderer.prototype.renderFrame_ = function (frame) {
|
||||
if (!this.canvas || frame.getWidth() != this.canvas.width || frame.getHeight() != this.canvas.height) {
|
||||
this.canvas = pskl.CanvasUtils.createCanvas(frame.getWidth(), frame.getHeight());
|
||||
}
|
||||
|
||||
var context = this.canvas.getContext('2d');
|
||||
for(var x = 0, width = frame.getWidth(); x < width; x++) {
|
||||
for(var y = 0, height = frame.getHeight(); y < height; y++) {
|
||||
var color = frame.getPixel(x, y);
|
||||
this.renderPixel_(color, x, y, context);
|
||||
}
|
||||
}
|
||||
|
||||
this.updateMargins_();
|
||||
|
||||
context = this.displayCanvas.getContext('2d');
|
||||
context.save();
|
||||
|
||||
if (this.canvas.width*this.zoom < this.displayCanvas.width) {
|
||||
context.fillStyle = Constants.ZOOMED_OUT_BACKGROUND_COLOR;
|
||||
context.fillRect(0,0,this.displayCanvas.width, this.displayCanvas.height);
|
||||
}
|
||||
|
||||
context.translate(
|
||||
this.margin.x-this.offset.x*this.zoom,
|
||||
this.margin.y-this.offset.y*this.zoom
|
||||
);
|
||||
|
||||
context.clearRect(0, 0, this.canvas.width*this.zoom, this.canvas.height*this.zoom);
|
||||
|
||||
var isIE10 = pskl.utils.UserAgent.isIE && pskl.utils.UserAgent.version === 10;
|
||||
if (this.isGridEnabled() || isIE10) {
|
||||
var gridWidth = this.isGridEnabled() ? Constants.GRID_STROKE_WIDTH : 0;
|
||||
var scaled = pskl.utils.ImageResizer.resizeNearestNeighbour(this.canvas, this.zoom, gridWidth);
|
||||
context.drawImage(scaled, 0, 0);
|
||||
} else {
|
||||
context.scale(this.zoom, this.zoom);
|
||||
context.drawImage(this.canvas, 0, 0);
|
||||
}
|
||||
context.restore();
|
||||
};
|
||||
})();
|
67
js/rendering/layer/LayersRenderer.js
Normal file
67
js/rendering/layer/LayersRenderer.js
Normal file
@ -0,0 +1,67 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.rendering.layer');
|
||||
|
||||
ns.LayersRenderer = function (container, renderingOptions, piskelController) {
|
||||
pskl.rendering.CompositeRenderer.call(this);
|
||||
|
||||
this.piskelController = piskelController;
|
||||
|
||||
// Do not use CachedFrameRenderers here, since the caching will be performed in the render method of LayersRenderer
|
||||
this.belowRenderer = new pskl.rendering.frame.FrameRenderer(container, renderingOptions, ["layers-canvas", "layers-below-canvas"]);
|
||||
this.aboveRenderer = new pskl.rendering.frame.FrameRenderer(container, renderingOptions, ["layers-canvas", "layers-above-canvas"]);
|
||||
|
||||
this.add(this.belowRenderer);
|
||||
this.add(this.aboveRenderer);
|
||||
|
||||
this.serializedRendering = '';
|
||||
};
|
||||
|
||||
pskl.utils.inherit(pskl.rendering.layer.LayersRenderer, pskl.rendering.CompositeRenderer);
|
||||
|
||||
ns.LayersRenderer.prototype.render = function () {
|
||||
var offset = this.getOffset();
|
||||
var size = this.getDisplaySize();
|
||||
var layers = this.piskelController.getLayers();
|
||||
var currentFrameIndex = this.piskelController.currentFrameIndex;
|
||||
var currentLayerIndex = this.piskelController.currentLayerIndex;
|
||||
|
||||
var serializedRendering = [
|
||||
this.getZoom(),
|
||||
this.isGridEnabled(),
|
||||
offset.x,
|
||||
offset.y,
|
||||
size.width,
|
||||
size.height,
|
||||
currentFrameIndex,
|
||||
currentLayerIndex,
|
||||
layers.length
|
||||
].join("-");
|
||||
|
||||
|
||||
if (this.serializedRendering != serializedRendering) {
|
||||
this.serializedRendering = serializedRendering;
|
||||
|
||||
this.clear();
|
||||
|
||||
var downLayers = layers.slice(0, currentLayerIndex);
|
||||
if (downLayers.length > 0) {
|
||||
var downFrame = this.getFrameForLayersAt_(currentFrameIndex, downLayers);
|
||||
this.belowRenderer.render(downFrame);
|
||||
}
|
||||
|
||||
var upLayers = layers.slice(currentLayerIndex + 1, layers.length);
|
||||
if (upLayers.length > 0) {
|
||||
var upFrame = this.getFrameForLayersAt_(currentFrameIndex, upLayers);
|
||||
this.aboveRenderer.render(upFrame);
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
ns.LayersRenderer.prototype.getFrameForLayersAt_ = function (frameIndex, layers) {
|
||||
var frames = layers.map(function (l) {
|
||||
return l.getFrameAt(frameIndex);
|
||||
});
|
||||
return pskl.utils.FrameUtils.merge(frames);
|
||||
};
|
||||
})();
|
Reference in New Issue
Block a user