2022-08-28 02:14:39 +02:00
|
|
|
import { Attributes } from './attributes.mjs'
|
2022-09-18 15:11:10 +02:00
|
|
|
import { Point } from './point.mjs'
|
2018-07-23 11:12:06 +00:00
|
|
|
|
2022-09-18 15:11:10 +02:00
|
|
|
//////////////////////////////////////////////
|
|
|
|
// CONSTRUCTOR //
|
|
|
|
//////////////////////////////////////////////
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructor for a Snippet
|
|
|
|
*
|
|
|
|
* @constructor
|
|
|
|
* @param {string} def - The id of the snippet in the SVG defs section
|
|
|
|
* @param {Point} anchor - The Point to anchor this Snippet on
|
|
|
|
* @return {Snippet} this - The Snippet instance
|
|
|
|
*/
|
|
|
|
export function Snippet(def, anchor) {
|
2019-08-03 15:03:33 +02:00
|
|
|
this.def = def
|
|
|
|
this.anchor = anchor
|
|
|
|
this.attributes = new Attributes()
|
2018-07-23 11:12:06 +00:00
|
|
|
|
2019-08-03 15:03:33 +02:00
|
|
|
return this
|
2018-07-23 11:12:06 +00:00
|
|
|
}
|
|
|
|
|
2022-09-18 15:11:10 +02:00
|
|
|
//////////////////////////////////////////////
|
|
|
|
// PUBLIC METHODS //
|
|
|
|
//////////////////////////////////////////////
|
2020-07-23 10:26:04 +02:00
|
|
|
|
2022-09-18 15:11:10 +02:00
|
|
|
/**
|
|
|
|
* Chainable way to add an attribute
|
|
|
|
*
|
|
|
|
* @param {string} name - Name of the attribute to add
|
|
|
|
* @param {string} value - Value of the attribute to add
|
|
|
|
* @param {bool} overwrite - Whether to overwrite an existing attrubute or not
|
|
|
|
* @return {Snippet} this - The Snippet instance
|
|
|
|
*/
|
2020-07-18 16:48:29 +02:00
|
|
|
Snippet.prototype.attr = function (name, value, overwrite = false) {
|
2019-08-03 15:03:33 +02:00
|
|
|
if (overwrite) this.attributes.set(name, value)
|
|
|
|
else this.attributes.add(name, value)
|
2018-08-17 20:24:10 +02:00
|
|
|
|
2019-08-03 15:03:33 +02:00
|
|
|
return this
|
|
|
|
}
|
2018-08-17 20:24:10 +02:00
|
|
|
|
2022-09-18 15:11:10 +02:00
|
|
|
/**
|
|
|
|
* Returns a deep copy of this snippet
|
|
|
|
*
|
|
|
|
* @return {Snippet} clone - A clone of this Snippet instance
|
|
|
|
*/
|
2020-07-18 16:48:29 +02:00
|
|
|
Snippet.prototype.clone = function () {
|
2022-09-18 15:11:10 +02:00
|
|
|
let clone = new Snippet(this.def, this.anchor.clone()).__withLog(this.log)
|
2019-08-03 15:03:33 +02:00
|
|
|
clone.attributes = this.attributes.clone()
|
2018-08-03 14:20:28 +02:00
|
|
|
|
2019-08-03 15:03:33 +02:00
|
|
|
return clone
|
|
|
|
}
|
2022-09-18 15:11:10 +02:00
|
|
|
|
2023-06-21 11:46:35 +02:00
|
|
|
/**
|
|
|
|
* Helper method to scale a snippet
|
|
|
|
*
|
|
|
|
* @param {number} scale - The scale to set
|
|
|
|
* @param {bool} overwrite - Whether to overwrite the existing scale or not (default is true)
|
|
|
|
*
|
|
|
|
* @return {Snippet} this - The snippet instance
|
|
|
|
*/
|
|
|
|
Snippet.prototype.scale = function (scale, overwrite = true) {
|
|
|
|
return this.attr('data-scale', scale, overwrite)
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Helper method to rotate a snippet
|
|
|
|
*
|
|
|
|
* @param {number} rotation - The rotation to set
|
|
|
|
* @param {bool} overwrite - Whether to overwrite the existing rotation or not (default is true)
|
|
|
|
*
|
|
|
|
* @return {Snippet} this - The snippet instance
|
|
|
|
*/
|
|
|
|
Snippet.prototype.rotate = function (rotation, overwrite = true) {
|
|
|
|
return this.attr('data-rotate', rotation, overwrite)
|
|
|
|
}
|
|
|
|
|
feat(core): Added Pattern.getLogs() and updated Pattern.getRenderProps()
The data returned by `Pattern.getRenderProps()` was not serializable as
we were returning `this` all over the place, thereby including marcors,
log methods, cyclic object references, and so on.
This commit changes that by implementing a `.asRenderProp()` method on
all of the various objects (stack, part, path, point, snippet,
attributes, svg) and only including data that can be serialized.
In addition, we no longer include the logs in the renderProps because
they are not related to rendering the pattern.
Instead, the new method `Pattern.getLogs()` gives you the logs.
2023-06-01 16:45:13 +02:00
|
|
|
/**
|
|
|
|
* Returns a snippet as an object suitable for inclusion in renderprops
|
|
|
|
*
|
|
|
|
* @return {object} snippet - A plain object representing the snippet
|
|
|
|
*/
|
|
|
|
Snippet.prototype.asRenderProps = function () {
|
|
|
|
return {
|
|
|
|
def: this.def,
|
|
|
|
anchor: this.anchor.asRenderProps(),
|
|
|
|
attributes: this.attributes.asRenderProps(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-18 15:11:10 +02:00
|
|
|
//////////////////////////////////////////////
|
|
|
|
// PRIVATE METHODS //
|
|
|
|
//////////////////////////////////////////////
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Adds the log method for a snippet not created through the proxy
|
|
|
|
*
|
|
|
|
* @private
|
|
|
|
* @return {Snippet} this - The Snippet instance
|
|
|
|
*/
|
|
|
|
Snippet.prototype.__withLog = function (log = false) {
|
|
|
|
if (log) Object.defineProperty(this, 'log', { value: log })
|
|
|
|
|
|
|
|
return this
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////
|
|
|
|
// PUBLIC STATIC METHODS //
|
|
|
|
//////////////////////////////////////////////
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a ready-to-proxy that logs when things aren't exactly ok
|
|
|
|
*
|
|
|
|
* @private
|
|
|
|
* @param {object} snippets - The snippets object to proxy
|
|
|
|
* @param {object} log - The logging object
|
|
|
|
* @return {object} proxy - The object that is ready to be proxied
|
|
|
|
*/
|
|
|
|
export function snippetsProxy(snippets, log) {
|
|
|
|
return {
|
|
|
|
get: function (...args) {
|
|
|
|
return Reflect.get(...args)
|
|
|
|
},
|
|
|
|
set: (snippets, name, value) => {
|
|
|
|
// Constructor checks
|
|
|
|
if (value instanceof Snippet !== true)
|
|
|
|
log.warning(`\`snippets.${name}\` was set with a value that is not a \`Snippet\` object`)
|
|
|
|
if (typeof value.def !== 'string')
|
|
|
|
log.warning(
|
|
|
|
`\`snippets.${name}\` was set with a \`def\` parameter that is not a \`string\``
|
|
|
|
)
|
|
|
|
if (value.anchor instanceof Point !== true)
|
|
|
|
log.warning(
|
|
|
|
`\`snippets.${name}\` was set with an \`anchor\` parameter that is not a \`Point\``
|
|
|
|
)
|
|
|
|
try {
|
|
|
|
value.name = name
|
|
|
|
} catch (err) {
|
|
|
|
log.warning(`Could not set \`name\` property on \`snippets.${name}\``)
|
|
|
|
}
|
|
|
|
return (snippets[name] = value)
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|