You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

94 lines
2.3 KiB
JavaScript

'use strict';
const createEventEmitter = require("create-event-emitter");
const defaultValue = require("default-value");
const validateSync = require("./validate-sync");
module.exports = function createObject(options) {
validateSync(options, {
type: "required",
onRecalculateSize: "required"
});
let object = createEventEmitter(Object.assign({
isCached: false,
cacheCanvas: document.createElement("canvas"),
flipX: false,
flipY: false,
scaleX: 1,
scaleY: 1,
opacity: 1,
set: function setProperties(properties) {
Object.assign(this, properties);
if (properties.some(property => this.sizeBustingProperties.includes(property))) {
this.emit("bustedSize");
this.recalculateSize();
}
if (properties.some(property => this.cacheBustingProperties.includes(property))) {
this.emit("bustedCache");
this.isCached = false;
}
},
render: function renderObject(context, options = {}) {
if (this.isCached === false) {
this.renderToCache(this.cacheCanvas);
// TODO: render cached canvas
}
this.emit("rendering");
context.drawImage(this.cacheCanvas, defaultValue(options.x, 0), defaultValue(options.y, 0));
this.emit("rendered");
},
recalculateSize: function recalculateSize() {
this.emit("recalculatingSize");
let newSize = this.onRecalculateSize();
this.renderWidth = newSize.width * this.scaleX;
this.renderHeight = newSize.height * this.scaleY;
this.cacheCanvas.width = this.width;
this.cacheCanvas.height = this.height;
// TODO: bounding box?
this.emit("recalculatedSize");
},
renderToCache: function renderToCache(targetCanvas) {
let context = targetCanvas.getContext("2d", {
alpha: true
});
context.save();
this.emit("renderingToCache");
let scaleX = (this.flipX === false) ? this.scaleX : (0 - this.scaleX);
let scaleY = (this.flipY === false) ? this.scaleY : (0 - this.scaleY);
context.scale(scaleX, scaleY);
context.globalAlpha = this.opacity;
this.onRender(context);
this.emit("renderedToCache");
context.restore();
}
}, options, {
cacheBustingProperties: ["scaleX", "scaleY", "opacity", "flipX", "flipY"].concat(options.cacheBustingProperties),
sizeBustingProperties: ["scaleX", "scaleY"].concat(options.sizeBustingProperties)
}));
object.recalculateSize();
// ...
return object;
};