import { group } from '../core/library.js';
import { mergeOver, pushUnique, removeItem, xtGet } from '../core/utilities.js';This mixin sets up the Scrawl-canvas functionality required to perform its Display cycle.
The mixin also includes code to assist drag-and-drop functionality.
import { group } from '../core/library.js';
import { mergeOver, pushUnique, removeItem, xtGet } from '../core/utilities.js';export default function (P = {}) { let defaultAttributes = {The groups attribute holds the String names of all the Group objects associated with the controller object.
groups: null,The groupBuckets attribute holds a reference to each Group object, in a set of arrays grouping Groups according to their order values.
groupBuckets: null,The batchResort Boolean flag determines whether the Groups will be sorted by their order value before instructions get passed to each in sequence. Best to leave this flag alone to do its job.
batchResort: true,
};
P.defs = mergeOver(P.defs, defaultAttributes); let G = P.getters,
S = P.setters;groups
G.groups = function () {
return [].concat(this.groups);
};
S.groups = function (item) {
this.groups = [];
this.addGroups(item);
};sortGroups - internal function - Groups are sorted from the groups Array into the groupBuckets array using a bespoke bucket sort algorithm, based on each Group object’s order attribute
P.sortGroups = function (force = false) {
if (this.batchResort) {
this.batchResort = false;
let floor = Math.floor,
groupnames = this.groups,
buckets = [],
mygroup, order;
groupnames.forEach(name => {
mygroup = group[name];
order = (mygroup) ? floor(mygroup.order) : 0;
if (!buckets[order]) buckets[order] = [];
buckets[order].push(mygroup);
});
this.groupBuckets = buckets.reduce((a, v) => a.concat(v), []);
}
};initializeCascade - internal function used by factory constructors
P.initializeCascade = function () {
this.groups = [];
this.groupBuckets = [];
};Groups should be added to, and removed from, the controller object using the addGroups and removeGroups functions. The argument can be one or more Group object’s name attribute, or the Group object(s) itself.
addGroups
P.addGroups = function (...args) {
args.forEach( item => {
if (item && item.substring) pushUnique(this.groups, item);
else if (group[item]) pushUnique(this.groups, item.name);
}, this);
this.batchResort = true;
return this;
};removeGroups
P.removeGroups = function (...args) {
args.forEach( item => {
if (item && item.substring) removeItem(this.groups, item);
else if (group[item]) removeItem(this.groups, item.name);
}, this);
this.batchResort = true;
return this;
};cascadeAction - internal helper function used by the functions below
P.cascadeAction = function (items, action) {
let grp;
console.log('cascadeAction')
this.groups.forEach( groupname => {
grp = group[groupname];
if (grp) grp[action](items);
}, this);
return this;
};updateArtefacts - Update all artefact objects in all the controller object’s Groups. The supplied argument will be passed on to each artefact’s setDelta function.
P.updateArtefacts = function (items) {
this.cascadeAction(items, 'updateArtefacts');
return this;
};updateArtefacts - Set all artefact objects in all the controller object’s Groups. The supplied argument will be passed on to each artefact’s set functions
P.setArtefacts = function (items) {
this.cascadeAction(items, 'setArtefacts');
return this;
};addArtefactClasses - specific to DOM-related artefacts (Stack, Canvas, Element)
P.addArtefactClasses = function (items) {
this.cascadeAction(items, 'addArtefactClasses');
return this;
};removeArtefactClasses - specific to DOM-related artefacts (Stack, Canvas, Element)
P.removeArtefactClasses = function (items) {
this.cascadeAction(items, 'removeArtefactClasses');
return this;
};updateByDelta - triggers the related artefact function, to update (add) its attributes by values held in its delta object attribute
P.updateByDelta = function () {
this.cascadeAction(false, 'updateByDelta');
return this;
};reverseByDelta - triggers the related artefact function, to reverse (subtract) its attributes by values held in its delta object attribute
P.reverseByDelta = function () {
this.cascadeAction(false, 'reverseByDelta');
return this;
};The getArtefactAt function checks to see if any of the controller object’s Groups’ artefacts are located at the supplied coordinates in the argument object.
P.getArtefactAt = function (items) {
items = xtGet(items, this.here, false);
if (items) {
let grp, result;
for (let i = this.groups.length - 1; i >= 0; i--) {
grp = group[this.groups[i]];
if (grp) {
result = grp.getArtefactAt(items);
if (result) return result;
}
}
}
return false;
};The getAllArtefactsAt function returns all of the controller object’s Groups’ artefacts located at the supplied coordinates in the argument object.
P.getAllArtefactsAt = function (items) {
items = xtGet(items, this.here, false);
if (items) {
let grp, result,
results = [];
for (let i = this.groups.length - 1; i >= 0; i--) {
grp = group[this.groups[i]];
if (grp) {
result = grp.getAllArtefactsAt(items);
if(result) results = results.concat(result);
}
}
return results;
}
return [];
};Return the prototype
return P;
};