import { constructors } from '../core/library.js';
import { mergeOver, Ωempty, λnull, λthis, xt, isa_fn } from '../core/utilities.js';
import baseMix from '../mixin/base.js';
import assetMix from '../mixin/asset.js';The Scrawl-canvas RawAsset object allows developers to extend the ability and functionality of the library. It can:
import { constructors } from '../core/library.js';
import { mergeOver, Ωempty, λnull, λthis, xt, isa_fn } from '../core/utilities.js';
import baseMix from '../mixin/base.js';
import assetMix from '../mixin/asset.js';const RawAsset = function (items = Ωempty) {
this.makeName(items.name);
this.register();
this.subscribers = [];
this.set(this.defs);
this.updateSource = λnull;
let keytypes = items.keytypes || {};
if (items.userAttributes) {
items.userAttributes.forEach(att => {
this.addAttribute(att);
if (att.type) keytypes[att.key] = att.type;
});
}
this.initializeAttributes(keytypes);
this.set(items);
let cell = document.createElement('canvas');
cell.width = 0;
cell.height = 0;
this.element = cell;
this.engine = cell.getContext('2d', {willReadFrequently: true});
if (items.subscribe) this.subscribers.push(items.subscribe);
return this;
};let P = RawAsset.prototype = Object.create(Object.prototype);
P.type = 'RawAsset';
P.lib = 'asset';
P.isArtefact = false;
P.isAsset = true;P = baseMix(P);
P = assetMix(P);let defaultAttributes = {keytypes - a Javascript object made up of key:String attributes. Used as part of the factory when generating assets which use user-defined attributes that need to be Scrawl-canvas Quaternions, Vectors (like gravity) or Coordinates.
key should be the attribute’s namevalue should be a String - either 'Quaternion', 'Vector' or 'Coordinate'. keytypes: null,data - can be anything which needs to be processed and then applied to the canvas to create a source image for Picture entitys, Pattern styles, or filters.
data: null,updateSource - a user-defined function which will be run every time a subscriber invokes checkSource when the dirtyData flag is set to true
updateSource: null,
};
P.defs = mergeOver(P.defs, defaultAttributes);Assets do not take part in the packet or clone systems; they can, however, be used for importing and actioning packets as they retain those base functions
P.saveAsPacket = function () {
return [this.name, this.type, this.lib, {}];
};
P.stringifyFunction = λnull;
P.processPacketOut = λnull;
P.finalizePacketOut = λnull;P.clone = λthis;let G = P.getters,
S = P.setters,
D = P.deltaSetters;source, engine
S.source = λnull;
S.element = λnull;
S.engine = λnull;
S.data = function (item) {
if (item) {
this.data = item;
this.dirtyData = true;
}
};
S.updateSource = function (item) {
if (item && isa_fn(item)) {
this.updateSource = item;
this.dirtyData = true;
}
};checkSource
P.checkSource = function (width, height) {
if (!this.source) this.source = this.element;
let source = this.source;
if (source) {
let notify = false;
if (this.dirtyData) {
this.dirtyData = false;
this.updateSource(this);
notify = true;
}
this.sourceLoaded = true;
if (!this.sourceNaturalWidth || !this.sourceNaturalHeight || this.sourceNaturalWidth !== width || this.sourceNaturalHeight !== height) {
this.sourceNaturalWidth = source.width;
this.sourceNaturalHeight = source.height;
notify = true;
}
if (notify && this.sourceNaturalWidth && this.sourceNaturalHeight) this.notifySubscribers();
}
else this.sourceLoaded = false;
};subscribeAction - Overrides mixin/asset.js function
P.subscribeAction = function (sub = {}) {
this.subscribers.push(sub);
sub.asset = this;
sub.source = this.element;
this.notifySubscriber(sub)
};addAttribute, removeAttribute - we can use these functions to add and remove other attributes to the RawAsset object.
P.addAttribute = function (items = Ωempty) {
let {key, defaultValue, setter, deltaSetter, getter} = items;
if (key && key.substring) {
this.defs[key] = xt(defaultValue) ? defaultValue : null;
this[key] = xt(defaultValue) ? defaultValue : null;
if (isa_fn(setter)) S[key] = setter;
if (isa_fn(deltaSetter)) D[key] = deltaSetter;
if (isa_fn(getter)) G[key] = getter;
}
return this;
};
P.removeAttribute = function (key) {
if (key && key.substring) {
delete this.defs[key];
delete this[key];
delete G[key];
delete S[key];
delete D[key];
}
return this;
};initializeAttributes - internal function called by the constructor.
P.initializeAttributes = function (types) {
for (let [key, value] of Object.entries(types)) {
switch (value) {
case 'Quaternion' :
this[key] = makeQuaternion();
break;
case 'Vector' :
this[key] = makeVector();
break;
case 'Coordinate' :
this[key] = makeCoordinate();
break;
}
}
};const makeRawAsset = function (items) {
if (!items) return false;
return new RawAsset(items);
};
constructors.RawAsset = RawAsset;export {
makeRawAsset,
};