nehan-speech-border
Version:
nehan plugin to display speech border
99 lines • 4.16 kB
JavaScript
import { CssStyleSheet, LogicalPos, LogicalEdgeMap, LogicalCssEvaluator } from "nehan";
;
const defaultStyle = {
selector: ".speech-border",
direction: "start",
bgColor: "white",
borderColor: "#bcbcbc",
borderSize: 2,
borderRadius: 4,
triangleOffset: 12,
};
const TriangleClipPath = {
"top": "polygon(50% 0, 100% 100%, 0 100%)",
"right": "polygon(0 0, 100% 50%, 0 100%)",
"bottom": "polygon(0 0, 100% 0, 50% 100%)",
"left": "polygon(0 50%, 100% 0, 100% 100%)",
};
function getTrianglePos(direction, triangleOffset) {
switch (direction) {
case "before": return {
containerPos: { before: "0px", start: "0px" },
outerPos: new LogicalPos({ start: triangleOffset, after: 0 }),
innerPos: new LogicalPos({ start: triangleOffset + 2, after: 0 })
};
case "after": return {
containerPos: { after: "0px", start: "0px" },
outerPos: new LogicalPos({ start: triangleOffset, before: 0 }),
innerPos: new LogicalPos({ start: triangleOffset + 2, before: 0 }),
};
case "start": return {
containerPos: { before: "0px", start: "0px" },
outerPos: new LogicalPos({ start: -16, before: triangleOffset }),
innerPos: new LogicalPos({ start: -12, before: triangleOffset + 2 }),
};
case "end": return {
containerPos: { before: "0px", end: "0px" },
outerPos: new LogicalPos({ end: -16, before: triangleOffset }),
innerPos: new LogicalPos({ end: -12, before: triangleOffset + 2 }),
};
}
}
;
function getClipPath(writingMode, direction) {
const logicalMap = LogicalEdgeMap.select(writingMode);
const clipDir = logicalMap.get(direction);
return TriangleClipPath[clipDir];
}
export const create = (args) => {
const style = Object.assign(Object.assign({}, defaultStyle), args);
const trianglePos = getTrianglePos(style.direction, style.triangleOffset);
return new CssStyleSheet({
[`${style.selector}`]: {
marginAfter: "1em",
},
[`${style.selector}.${style.direction}>.content`]: {
[`margin-${style.direction}`]: "1em",
"padding": "0.5em",
"background": style.bgColor,
"border": `${style.borderSize}px solid ${style.borderColor}`,
"borderRadius": `${style.borderRadius}px`,
},
[`${style.selector}.${style.direction}>.content::before`]: {
"display": "block",
"position": "absolute",
"content": " ",
"measure": "0",
"extent": "0",
"!logical-pos": (ctx) => {
return trianglePos.containerPos;
},
"@oncreate": (ctx) => {
const writingMode = ctx.box.env.writingMode;
const evaluator = new LogicalCssEvaluator(writingMode);
const clipPath = getClipPath(writingMode, style.direction);
const $outer = document.createElement("div");
$outer.style.position = "absolute";
$outer.style.display = "block";
$outer.style.content = " ";
$outer.style.width = "16px";
$outer.style.height = "16px";
$outer.style.backgroundColor = style.borderColor;
$outer.style.clipPath = clipPath;
const $inner = document.createElement("div");
$inner.style.position = "absolute";
$inner.style.display = "block";
$inner.style.content = " ";
$inner.style.width = "12px";
$inner.style.height = "12px";
$inner.style.backgroundColor = style.bgColor;
$inner.style.clipPath = clipPath;
trianglePos.outerPos.acceptCssEvaluator(evaluator).applyTo($outer.style);
trianglePos.innerPos.acceptCssEvaluator(evaluator).applyTo($inner.style);
ctx.dom.appendChild($outer);
ctx.dom.appendChild($inner);
}
}
});
};
//# sourceMappingURL=index.js.map