1
0
Fork 0
freesewing/packages/core/src/snippet.mjs

146 lines
4.1 KiB
JavaScript
Raw Normal View History

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
*/
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
*/
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
/**
* 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)
}
/**
* 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)
},
}
}