tds_shapes
Version:
User interface components created with [svg.js](https://github.com/svgdotjs/svg.js)
142 lines (123 loc) • 3.24 kB
text/typescript
import { G, Element } from '@svgdotjs/svg.js'
import {
Create_ID,
TitleToBackgroundRules,
Indents,
BackgroundStyle,
Position,
TitleStyle,
} from './common'
import { title } from './title'
import { background } from './background'
// export type TitleToBackgroundRules =
// | 'none' // label does not have background
// | 'direct' // coordinates defined directly
// | 'indent' // static indents
// | 'centered' // allign title center to background
export type LabelAttr = {
title: title | TitleStyle
backgroundRule?: TitleToBackgroundRules[]
background?: background | BackgroundStyle
indents?: Indents
position?: Position
}
export class label extends G {
title: title
background: background
rules: TitleToBackgroundRules[] = []
indents: Indents
constructor(attr: LabelAttr) {
super()
this.id(Create_ID()).addClass('tds-label')
attr.backgroundRule ??= ['none']
this.rules.push(...attr.backgroundRule)
attr.indents ??= [0, 0, 0, 0]
this.indents = attr.indents
attr.title instanceof title
? Object.assign(attr.title, this.title)
: (this.title = new title(attr.title))
if (attr.background && !this.rules.includes('none')) {
attr.background instanceof background
? Object.assign(attr.background, this.background)
: (this.background = new background(
attr.background
))
}
applyRules(
this.title,
this.background,
this.rules,
this.indents
)
this.background && this.add(this.background)
this.add(this.title)
attr.position &&
this.move(attr.position.x, attr.position.y)
}
// value operations
/** get value from title */
get value() {
return this.title.value
}
/** set title value and apply rules */
set value(v: string) {
this.title.value = v
this.applyRules(this.rules, this.indents)
}
/**
* alling 'background' position to 'title' by rules
* the rules are applied in the order of definition
* @param r new rules
* @param i new indents
*/
applyRules(
r: TitleToBackgroundRules[],
i: Indents = [0, 0, 0, 0]
) {
// store rules and indents
this.rules = []
this.rules.push(...r)
this.indents = i
applyRules(
this.title,
this.background,
this.rules,
this.indents
)
}
}
/**
* alling 'background' position to 'title' by rules
* the rules are applied in the order of definition
* @param t title
* @param b background
* @param r array of rules from TitleToBackgroundRules
* @param i indents array [0,0,0,0] by default
*/
const applyRules = (
t: Element,
b: Element,
r: TitleToBackgroundRules[],
i?: Indents //| { sp: Position; tp: Position }
): void => {
r.forEach((rule) => {
switch (rule) {
case 'centered':
// set background to title
b.cx(t.cx())
b.cy(t.cy())
break
case 'indent':
// change background size accordind
// title size and indents
let tb = t.bbox()
b.width(tb.width + i[0] + i[2])
b.height(tb.height + i[1] + i[3])
b.x(tb.x - i[0])
b.y(tb.y - i[1])
break
default:
break
}
})
}