Add composite object implementation

master
Sven Slootweg 7 years ago
parent 34842e4803
commit 7805c2fe06

@ -0,0 +1,93 @@
'use strict';
const dotty = require("dotty");
const defaultValue = require("default-value");
const createObject = require("./create-object");
const createPropertyMapper = require("./property-mapper");
const max = require("./util/max");
const min = require("./util/min");
function getPosition(object) {
return {
x: defaultValue(object.x, 0),
y: defaultValue(object.y, 0)
}
}
module.exports = function createCompositeObject(options) {
let mapProperties = createPropertyMapper(options.propertyMap);
let compositeObject = createObject(Object.assign({
onSet: function setCompositeProperties(properties) {
let mappedProperties = mapProperties(properties);
Object.keys(mappedProperties).forEach((objectName) => {
if (objectName !== "_") {
if (this.objects[objectName] != null) {
this.objects[objectName].set(mappedProperties[objectName]);
} else {
throw new Error(`The object specified in the property map as '${objectName}' does not exist`);
}
}
});
/* We return the `_` object here, which contains all the unmapped
* properties - we assume that all unmapped properties are meant to
* apply to the composite object rather than its child objects. The
* original `.set` method (as defined in createObject) will then use
* this result. */
return defaultValue(mappedProperties._, {});
},
onRender: function onRender(context) {
Object.keys(this.objects).forEach((objectName) => {
let object = this.objects[objectName];
let position = getPosition(object);
object.render(context, {
x: object.x - this.renderOffsetX,
y: object.y - this.renderOffsetY
});
});
},
onRecalculateSize: function onRecalculateSize() {
let objectMetrics = Object.keys(this.objects).map((objectName) => {
let object = this.objects[objectName];
let position = getPosition(object);
console.log(object.type, [object.x, object.y], [position.x, position.y], object.renderWidth, object.renderHeight);
return {
x1: position.x,
y1: position.y,
x2: position.x + object.renderWidth,
y2: position.y + object.renderHeight
}
});
let x1 = min(objectMetrics.map(object => object.x1));
let y1 = min(objectMetrics.map(object => object.y1));
let x2 = max(objectMetrics.map(object => object.x2));
let y2 = max(objectMetrics.map(object => object.y2));
return {
width: x2 - x1,
height: y2 - y1,
offsetX: x1,
offsetY: y1
}
}
}, options));
Object.keys(compositeObject.objects).forEach((objectName) => {
compositeObject.objects[objectName].on("recalculatedSize", () => {
compositeObject.recalculateSize();
});
compositeObject.objects[objectName].on("renderedToCache", () => {
compositeObject.bustCache();
});
});
return compositeObject;
};

@ -2,5 +2,6 @@
module.exports = {
validateSync: require("./validate-sync"),
createObject: require("./create-object")
createObject: require("./create-object"),
createCompositeObject: require("./create-composite-object")
}

@ -0,0 +1,5 @@
'use strict';
module.exports = function max(values) {
return Math.max(...values);
}

@ -0,0 +1,5 @@
'use strict';
module.exports = function min(values) {
return Math.min(...values);
}
Loading…
Cancel
Save