@freesewing/core
Version:
A library for creating made-to-measure sewing patterns
147 lines (129 loc) • 4.38 kB
JavaScript
import { Attributes } from './attributes.mjs'
import { Point } from './point.mjs'
//////////////////////////////////////////////
// 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
* @param {boolean} force - Whether to force rendering of this snippet when complete is falsy (or not)
* @return {Snippet} this - The Snippet instance
*/
export function Snippet(def, anchor, force = false) {
this.def = def
this.anchor = anchor
this.attributes = new Attributes()
if (force) this.attributes.set('data-force', 1)
return this
}
//////////////////////////////////////////////
// PUBLIC METHODS //
//////////////////////////////////////////////
/**
* 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) {
if (overwrite) this.attributes.set(name, value)
else this.attributes.add(name, value)
return this
}
/**
* Returns a deep copy of this snippet
*
* @return {Snippet} clone - A clone of this Snippet instance
*/
Snippet.prototype.clone = function () {
let clone = new Snippet(this.def, this.anchor.clone()).__withLog(this.log)
clone.attributes = this.attributes.clone()
return clone
}
/**
* 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(),
}
}
//////////////////////////////////////////////
// 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.warn(`\`snippets.${name}\` was set with a value that is not a \`Snippet\` object`)
if (typeof value.def !== 'string')
log.warn(`\`snippets.${name}\` was set with a \`def\` parameter that is not a \`string\``)
if (value.anchor instanceof Point !== true)
log.warn(
`\`snippets.${name}\` was set with an \`anchor\` parameter that is not a \`Point\``
)
try {
value.name = name
} catch (err) {
log.warn(`Could not set \`name\` property on \`snippets.${name}\``)
}
return (snippets[name] = value)
},
}
}