1
0
Fork 0
freesewing/plugins/plugin-annotations/src/crossbox.mjs
2023-10-18 17:27:30 +02:00

122 lines
3.3 KiB
JavaScript

/*
* Defaults for the title macro
*/
const macroDefaults = {
classes: {
box: 'lining dotted stroke-sm',
cross: 'lining dotted stroke-sm',
text: 'center fill-lining',
},
id: 'crossbox',
offset: 0.1,
text: '',
}
/*
* The rmcrossbox macro
*/
const rmcrossbox = (id = macroDefaults.id, { store, part }) =>
store.removeMacroNodes(id, 'crossbox', part)
/*
* The crossbox macro
*/
const crossbox = function (config, { points, Point, paths, Path, complete, store, log }) {
/*
* Don't add a title when complete is false, unless force is true
*/
if (!complete && !config.force) return
/*
* Merge macro defaults with user-provided config to create the macro config (mc)
*/
const mc = {
...macroDefaults,
...config,
classes: macroDefaults.classes,
}
if (config.classes) mc.classes = { ...mc.classes, ...config.classes }
/*
* Make sure mc.topLeft and mc.bottomRight are Point instances
*/
if (!mc.topLeft || typeof mc.topLeft.attr !== 'function') {
log.warn(`Crossbox macro called without a valid topLeft point. Using (0,0) for topLeft.`)
mc.topLeft = new Point(0, 0)
}
if (!mc.bottomRight || typeof mc.bottomRight.attr !== 'function') {
log.warn(
`Crossbox macro called without a valid bottomRight point. Using (666,666) for bottomRight.`
)
mc.bottomRight = new Point(666, 666)
}
/*
* Get the list of IDs
*/
const flatIds = store.generateMacroIds(['box', 'cross', 'text'], mc.id)
const ids = {
paths: {
box: flatIds.box,
cross: flatIds.cross,
},
points: { text: flatIds.text },
}
/*
* Calculate the cross offset as [offset]% of the shortest side of the box
*/
const offset =
Math.abs(mc.topLeft.dx(mc.bottomRight)) > Math.abs(mc.topLeft.dy(mc.bottomRight))
? Math.abs(mc.topLeft.dx(mc.bottomRight)) * mc.offset
: Math.abs(mc.topLeft.dy(mc.bottomRight)) * mc.offset
/*
* Draw the box
*/
paths[ids.paths.box] = new Path()
.move(mc.topLeft)
.line(new Point(mc.topLeft.x, mc.bottomRight.y))
.line(mc.bottomRight)
.line(new Point(mc.bottomRight.x, mc.topLeft.y))
.line(mc.topLeft)
.close()
.attr('class', mc.classes.box)
/*
* Draw the cross
*/
paths[ids.paths.cross] = new Path()
.move(mc.topLeft.shift(315, offset))
.line(new Point(mc.bottomRight.x, mc.topLeft.y).shift(225, offset))
.line(mc.bottomRight.shift(135, offset))
.line(new Point(mc.topLeft.x, mc.bottomRight.y).shift(45, offset))
.line(mc.topLeft.shift(315, offset))
.line(mc.bottomRight.shift(135, offset))
.move(new Point(mc.bottomRight.x, mc.topLeft.y).shift(225, offset))
.line(new Point(mc.topLeft.x, mc.bottomRight.y).shift(45, offset))
.attr('class', mc.classes.box)
/*
* If there is text, add it
*/
if (mc.text)
points[ids.points.text] = mc.topLeft
.shiftFractionTowards(mc.bottomRight, 0.5)
.addText(mc.text, mc.classes.text)
else delete ids.points.text
/*
* Store all IDs in the store so we can remove this macro with rmtitle
* Just make sure to keep points and paths apart
*/
store.storeMacroIds(mc.id, ids)
/*
* Returning ids is a best practice for FreeSewing macros
*/
return store.getMacroIds(mc.id)
}
// Export macros
export const crossboxMacros = { crossbox, rmcrossbox }