BaseElement

BaseElement

这类节点由两部分组成,背景(background)和价值物(value),通常 value 被放置在 background 的中心。这是一个抽象类,不应该被实例化。

API 列表

class BaseElement extends SD2DNode {
    constructor(target: SDNode | RenderNode, value?: any);

    rate(): number;
    rate(rate: number): this;
    color(): PacketColor;
    color(color: SDColor): this;
    fill(): HexColor;
    fill(fill: HexColor): this;
    fillOpacity(): number;
    fillOpacity(opacity: number): this;
    stroke(): HexColor;
    stroke(stroke: HexColor): this;
    strokeOpacity(): number;
    strokeOpacity(opacity: number): this;
    strokeWidth(): number;
    strokeWidth(width: number): this;
    background(): SDNode;
    text(): string;
    text(text: string): this;
    intValue(): number;
    value(): SDNode | undefined;
    value(value: any, rule?: SDRule): this;
    valueFromExist(value: SDNode, rule?: SDRule): this;
    drop(): SDNode | undefined;
}

rate

class BaseElement {
    rate(): number;
    rate(rate: number): this;
}

用于管理 value 相对于 background 的空闲率。空闲率越大,value 看上去就越小。默认情况下空闲率为 1.2。

const svg = sd.svg();
const box = new sd.Box(svg, "V");
sd.main(async () => {
    await sd.pause();
    box.startAnimate().rate(2).endAnimate(); // 提高空闲率,"V" 会显得很小
    await sd.pause();
    box.startAnimate().rate(1).endAnimate(); // 降低空闲率,"V" 会显得很大
});

空闲率对不同形状的背景图形,影响略有不同。秉持汤多加盐,盐多加汤的原则去使用即可(即 value 看起来太小了就调小空闲率,value 看起来太大了就调大空闲率)。

如果在添加 value 的时候人为指定了布局规则,则此属性失效。

const svg = sd.svg();
const R = sd.rule();
const box = new sd.Box(svg).value("V", R.centerOnly()); // 人为指定布局规则
sd.main(async () => {
	await sd.pause();
    box.startAnimate().rate(2).endAnimate(); // 提高空闲率,"V" 不会变化
    await sd.pause();
    box.startAnimate().rate(1).endAnimate(); // 降低空闲率,"V" 不会变化
});

color

class BaseElement {
    color(): PacketColor;
    color(color: SDColor): this;
}

用于管理 background 的颜色。

fill

class BaseElement {
    fill(): HexColor;
    fill(fill: HexColor): this;
}

用于管理 background 的填充色。默认为白色。

fillOpacity

class BaseElement {
    fillOpacity(): number;
    fillOpacity(opacity: number): this;
}

用于管理 background 的填充透明度。默认为 1。

stroke

class BaseElement {
    stroke(): HexColor;
    stroke(stroke: HexColor): this;
}

用于管理 background 的边框色。默认为黑色。

strokeOpacity

class BaseElement {
    strokeOpacity(): number;
    strokeOpacity(opacity: number): this;
}

用于管理 background 的边框透明度。默认为 1。

strokeWidth

class BaseElement {
    strokeWidth(): number;
    strokeWidth(width: number): this;
}

用于管理 background 的边框宽度。默认为 1。

background

class BaseElement {
    background(): SDNode;
}

用于获取背景节点。对于不同特化的元素,获取到的背景节点也有所不同。

const svg = sd.svg();
const box = new sd.Box(svg);
const vertex = new sd.Vertex(svg);
const ellipseVertex = new sd.EllipseVertex(svg);
console.log(box.background()); // 一个 sd.Rect
console.log(vertex.background()); // 一个 sd.Circle
console.log(ellipseVertex.background()); // 一个 sd.Ellipse

text

class BaseElement {
    text(): string;
    text(text: string): this;
}

管理 value 的文本。当且仅当 value 是文本元素时才有效。

const svg = sd.svg();
const box1 = new sd.Box(svg, "A");
const box2 = new sd.Box(svg, new sd.Circle(svg)).x(100);
console.log(box1.text()); // "A"
// console.log(box2.text()); // this is invalid invoke
sd.main(async () => {
	await sd.pause();
	box1.text("B");
});

intValue

class BaseElement {
    intValue(): number;
}

value 对应的文本解析为整数类型,并返回。如果 value 不存在,或者对应文本是空串,则会解析为整数 0。在解析其他非数值文本的情况下会抛出错误。

const svg = sd.svg();
const box1 = new sd.Box(svg, "1");
const box2 = new sd.Box(svg, "1.8").x(100);
const box3 = new sd.Box(svg).x(200);
const box4 = new sd.Box(svg, "A").x(300);
console.log(box1.intValue()); // 1
console.log(box2.intValue()); // 1
console.log(box3.intValue()); // 0
// console.log(box4.intValue()); // this is an invalid invoke

value & valueFromExist

class BaseElement {
    value(): SDNode | undefined;
    value(value: any, rule?: SDRule): this;
    valueFromExist(value: SDNode, rule?: SDRule): this;
}

管理 value 节点。可以在添加 value 节点时使用自定义布局规则,若不提供则使用默认规则(即尽量把 value 放在正中间,并且适当缩放 value,让它匹配 background 的大小)。

const svg = sd.svg();
const EN = sd.enter();
const box1 = new sd.Box(svg);
const box2 = new sd.Box(svg).x(100);
const box3 = new sd.Box(svg).x(200);
const box4 = new sd.Box(svg).x(300);
const value2 = new sd.Text(svg, "B").cy(100).cx(box2.cx());
const value3 = new sd.Circle(svg).cy(100).cx(box3.cx());
const value4 = new sd.Text(svg, "C").cy(100).cx(box4.cx());
sd.main(async () => {
	await sd.pause();
	box1.startAnimate().value("A").endAnimate();
	box2.startAnimate().value(value2).endAnimate();
	box3.startAnimate().value(value3.onEnter(EN.moveTo())).endAnimate();
	box4.startAnimate().valueFromExist(value4).endAnimate();
});

试一试,前两个 box 中,value 是浮现在 box 的正中心的;而后两个 box 中,value 是从自己原本的位置平移过去的。这就是 value 和 valueFromExist 的区别。valueFromExist 会指定 value 进入元素的方式是从当前位置平移过去

如果在一个元素已经存在 value 的情况下设置其 value,则原来那个 value 会被删掉,这里的删除将会导致原始 value 永远地离开场景。

const svg = sd.svg();
const box = new sd.Box(svg, "A");
sd.main(async () => {
    await sd.pause();
    box.startAnimate().value("B").endAnimate(); // "A" 被删除
    await sd.pause();
    box.startAnimate().value(null).endAnimate(); // "B" 被删除
});

drop

class BaseElement {
    drop(): SDNode | undefined;
}

前文提到,如果 value 方法去删除已存在的 value,会导致 value 永远地离开场景,但部分情况下,我们可能希望被删除的 value 只是被元素丢弃了,它仍然存在于场景之中。有两种达成这个目的的解决方案,最直接的便是 drop 方法:

const svg = sd.svg();
const EX = sd.exit();
const box11 = new sd.Box(svg, "A");
const box12 = new sd.Box(svg).x(100);
const box21 = new sd.Box(svg, "B").y(50);
const box22 = new sd.Box(svg).x(100).y(50);
sd.main(async () => {
    await sd.pause();
    box12.startAnimate().valueFromExist(box11.drop()).endAnimate(); // 直接使用 drop 方法丢弃 box11 中的 value
    const b = box21.value().onExit(EX.drop()); // 设置 box21 的 value 以 drop 的形式从 box21 中删除
    box21.value(null); // 删除 box21 中的 value
    box22.startAnimate().valueFromExist(b).endAnimate();
});

试一试,在上例中,当 box11 或者 box21 中的 value 被删除时,它们并不会被移除到场景之外,而仅仅是被元素所丢弃了。所以我们能在之后的代码中,将这两个 value 分别转交给 box12 和 box22。