Doodle3D-Core/src/d2/ShapesManager.js

124 lines
3.6 KiB
JavaScript
Raw Normal View History

2017-11-22 12:35:00 +01:00
import { shapeDataToShape, determineActiveShape2d } from '../shape/shapeDataUtils.js';
2017-12-14 12:29:28 +01:00
import _ from 'lodash';
2017-11-15 15:13:49 +01:00
export default class ShapesManager {
constructor(objectContainerActive, objectContainerInactive) {
this.objectContainerActive = objectContainerActive;
this.objectContainerInactive = objectContainerInactive;
this._shapes = {};
this._activeObjectUIDs = [];
this._inactiveObjectUIDs = [];
}
// activeShapes is an array with object id's that are active
update(state) {
const needRender = { active: false, inactive: false };
// determine if shape is "active", meaning it will be updated frequently
2017-11-22 12:35:00 +01:00
const activeShapes = determineActiveShape2d(state);
2017-11-15 15:13:49 +01:00
const { objectsById } = state;
if (
this._objectsById === objectsById &&
2017-12-14 12:29:28 +01:00
_.isEqual(activeShapes, this._activeShapes) &&
2017-11-15 15:13:49 +01:00
state.activeSpace === this._activeSpace
2017-12-14 12:29:28 +01:00
) return needRender;
2017-11-15 15:13:49 +01:00
// object ids that are in the current space
const spaceObjectIds = state.spaces[state.activeSpace].objectIds;
// remove shapes
if (this._objectsById !== undefined) {
for (const id in this._objectsById) {
if (spaceObjectIds.indexOf(id) === -1) {
this._handleShapeRemove(id, needRender);
}
}
}
const newActiveObjectUIDs = [];
const newInactiveObjectUIDs = [];
for (const UID of spaceObjectIds) {
2017-11-18 21:21:16 +01:00
const active = activeShapes[UID];
2017-11-15 15:13:49 +01:00
if (active) {
newActiveObjectUIDs.push(UID);
} else {
newInactiveObjectUIDs.push(UID);
}
const shapeData = objectsById[UID];
const shape = this._shapes[shapeData.UID] || this._createShape(shapeData);
// Put shapes into the right container; active or inactive
if (!active && this._activeObjectUIDs.indexOf(UID) !== -1) {
this.objectContainerActive.remove(shape);
needRender.active = true;
} else if (active && this._inactiveObjectUIDs.indexOf(UID) !== -1) {
this.objectContainerInactive.remove(shape);
needRender.inactive = true;
}
if (!active && this._inactiveObjectUIDs.indexOf(UID) === -1) {
this.objectContainerInactive.add(shape);
needRender.inactive = true;
} else if (active && this._activeObjectUIDs.indexOf(UID) === -1) {
this.objectContainerActive.add(shape);
needRender.active = true;
}
// update shape properties
if (!this._objectsById || !this._objectsById[UID]) continue;
const update = shape.update(shapeData);
if (update) {
if (active) needRender.active = true;
else needRender.inactive = true;
}
}
this._activeObjectUIDs = newActiveObjectUIDs;
this._inactiveObjectUIDs = newInactiveObjectUIDs;
this._objectsById = objectsById;
this._activeShapes = activeShapes;
this._activeSpace = state.activeSpace;
return needRender;
}
updateTransparent(selectedUIDs) {
for (const UID in this._shapes) {
const shape = this._shapes[UID];
const selected = selectedUIDs.indexOf(UID) !== -1;
const opaque = selected || selectedUIDs.length === 0;
shape.setOpaque(opaque);
}
}
_handleShapeRemove(UID, needRender) {
const shape = this._shapes[UID];
delete this._shapes[UID];
// check which container
const active = this._activeObjectUIDs.indexOf(UID) !== -1;
if (active) {
this.objectContainerActive.remove(shape);
needRender.active = true;
} else {
this.objectContainerInactive.remove(shape);
needRender.inactive = true;
}
}
_createShape(shapeData) {
const shape = shapeDataToShape(shapeData);
this._shapes[shapeData.UID] = shape;
return shape;
}
}