@yunser/ui-std
Version:
UI standard specification.
2,064 lines • 81.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.StdUI = exports._if = exports.ui = void 0;
// const uiUtil = require('./util')
const helper_1 = require("./helper");
// import * as fs from 'fs'
const Color = require("color");
const angleToCoordinates = require("css-gradient-angle-to-svg-gradient-coordinates");
// const angleToCoordinates = require('css-gradient-angle-to-svg-gradient-coordinates')
const svgpath = require('svgpath');
const caster = require('svg-path-bounding-box');
var parse = require('parse-svg-path');
var translate = require('translate-svg-path');
var serialize = require('serialize-svg-path');
const svg_default_stroke_dasharray = '8';
function max(arr) {
let max = arr[0];
for (let num of arr) {
if (num > max) {
max = num;
}
}
return max;
}
function getStyle(node) {
if (node.visible == false) {
return {
display: 'none',
};
}
return {};
}
function styleToText(style) {
return Object.keys(style).map(key => `${key}: ${style[key]}`).join(';');
}
function getStyleText(node) {
return styleToText(getStyle(node));
}
function getTransform(node, center) {
if (node.rotate) {
return `translate(${center.x}, ${center.y}) rotate(${node.rotate}) translate(${-center.x}, ${-center.y})`;
}
return null;
}
function breakPoint() {
throw new Error('breakPoint');
}
const Align = {
Center: 'center',
};
exports.ui = {
Align,
};
const BORDER_INSIDE = true;
// const bbbox = caster(
// 'M300,200 h-150 a150,150 0 1,0 150,-150 z'
// )
// // .toString()
// console.log('bbbox', bbbox)
// console.log('a', a)
const NodeType = {
Root: 'root',
// if (node.type == 'root') {
};
function calcPolygon(node) {
function min(arr) {
let min = arr[0];
for (let num of arr) {
if (num < min) {
min = num;
}
}
return min;
}
let xList = node.points.map(item => item.x);
let yList = node.points.map(item => item.y);
let left = min(xList);
let right = max(xList);
let top = min(yList);
let bottom = max(yList);
// console.log('left', left, right, top, bottom)
// for (let pt of node.points) {
// if (pt.x < left) {
// }
// }
const height = bottom - top;
const width = right - left;
return {
left,
right,
top,
bottom,
height,
width,
};
}
const StdUiNodeType = {
Root: 'root',
Rect: 'rect',
Text: 'text',
Image: 'image',
Circle: 'circle',
Ellipse: 'ellipse',
Polygon: 'polygon',
Polyline: 'polyline',
Line: 'line',
Path: 'path',
};
// console.log('uiUtil', uiUtil, uiUtil.treeMap)
function objectSomeAttr(obj, attrs) {
let result = {};
for (let attr of attrs) {
if (obj[attr] != undefined) {
result[attr] = obj[attr];
}
}
return result;
}
// const uiObj: StdUiRoot = {
// "_type": "root",
// "width": 1000,
// "height": 1000,
// "_children": [
// {
// "_type": "rect",
// "x": 0,
// "y": 0,
// "width": 100,
// "height": 100,
// "color": "#f00",
// radius: 8,
// },
// {
// "_type": "rect",
// "x": 100,
// "y": 100,
// "width": 100,
// "height": 100,
// "color": "#09c"
// },
// {
// "_type": "circle",
// "cx": 150,
// "cy": 50,
// // "width": 100,
// // "height": 100,
// radius: 50,
// "color": "#f00"
// },
// {
// "_type": "rect",
// "x": 200,
// "y": 0,
// "width": 100,
// "height": 100,
// // "color": "#09c",
// // "stroke": "#09c",
// "border": {
// color: "#09c",
// width: 10,
// }
// },
// {
// "_type": "text",
// "x": 200,
// "y": 0,
// // "width": 100,
// // "height": 100,
// "color": "#f00",
// // radius: 8,
// text: '你好',
// textSize: 100,
// },
// {
// "_type": "circle",
// "cx": 350,
// "cy": 50,
// // "width": 100,
// // "height": 100,
// radius: 50,
// "border": {
// color: "#09c",
// width: 1,
// }
// // "color": "#f00"
// },
// {
// "_type": "line",
// "x1": 0,
// "y1": 100,
// x2: 100,
// y2: 200,
// "border": {
// color: "#f00",
// width: 1,
// }
// // "width": 100,
// // "height": 100,
// // "color": "#f00",
// // radius: 8,
// },
// ]
// }
function convertUiObj2XmlObject(obj) {
let out = helper_1.uiUtil.treeMap(obj, {
childrenKey: '_children',
nodeHandler(node) {
// let type
let attrs = {};
for (let key in node) {
if (!key.match(/^_/)) {
attrs[key] = node[key];
}
}
// if (node._type == 'root') {
// type = 'root'
// } else if (node._type == 'tag') {
// type = node.name
// attrs = node.attribs
// } else {
// if (node._type == 'text') {
// console.log('node', node)
// const { data } = node
// if (data.match(/^\s+$/)) {
// return null
// }
// }
// type = 'other:' + node._type
// }
let result = {
type: node._type,
// children: node._children as any,
attr: attrs,
// _type: type,
// ...attrs,
};
return result;
}
});
return out;
}
function _if(condition, obj) {
return condition ? [obj] : [];
}
exports._if = _if;
function convertUiObj2HtmlObject(rootObj) {
function calcLine(node) {
let x = Math.min(node.x1, node.x2);
let y = Math.min(node.y1, node.y2);
let width = Math.abs(node.x1 - node.x2);
let height = Math.abs(node.y1 - node.y2);
return {
x,
y,
width,
height,
};
}
function getTranslatePoints(points, translate) {
return points.map(item => {
return {
x: item.x + translate.x,
y: item.y + translate.y,
};
});
}
function commonStyle(node) {
let ret = {};
// TODO 0
if (node.opacity) {
ret.opacity = node.opacity;
}
if (node.shadow) {
const shadow = node.shadow;
const color = Color(shadow.color || '#000');
const rgb = color.object();
const rgba = `rgba(${rgb.r * 255}, ${rgb.g * 255}, ${rgb.b * 255}, ${shadow.alpha || 1})`;
ret['box-shadow'] = `${shadow.x || 0}px ${shadow.y || 0}px ${shadow.blur || 0}px ${shadow.spread || 0}px ${rgba}`;
}
// shadow: {
// x: 5,
// y: 5,
// blur: 10,
// alpha: 0.2,
// },
return ret;
}
function borderStyle(node) {
let ret = {};
if (node.border) {
ret.border = `${node.border.width || 1}px solid ${node.border.color || '#000'}`;
}
return ret;
}
function borderRadius(node) {
let ret = {};
if (node.borderRadius) {
ret['border-radius'] = `${node.borderRadius || 0}px`;
}
return ret;
}
function fillStyle(node) {
let ret = {};
// if (node.border) {
// ret.border = `${node.border.width || 1}px solid ${node.border.color || '#000'}`
// }
if (node.fill) {
const gradient = node.fill;
if (node.fill.type == 'linearGradient') {
if (gradient.stops) {
ret['background-image'] = `linear-gradient(to ${gradient.direction}deg, ${gradient.stops.map(stop => `${stop.color}`).join(', ')})`;
}
else {
ret['background-image'] = `linear-gradient(to ${node.fill.direction}, ${node.fill.colors[0]}, ${node.fill.colors[1]})`;
}
}
// direction: 'bottom',
// colors: ['#09c', '#c90'],
}
// fill: {
// type: '',
// },
else if (node.color != null) {
ret['background-color'] = node.color || '#fff';
}
return ret;
}
function getHtmlStyle(attrs) {
let _arr = [];
for (let key in attrs) {
_arr.push(`${key}: ${attrs[key]}`);
}
return _arr.join('; ');
}
return {
type: 'html',
children: [
{
type: 'head',
children: [
{
type: 'style',
_data: `* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-color: #fff;
}
@font-face {
font-family: 'iconfont'; /* Project id 2831085 */
src: url('//at.alicdn.com/t/font_2831085_rw79b312ut.woff2?t=1632424896907') format('woff2'),
url('//at.alicdn.com/t/font_2831085_rw79b312ut.woff?t=1632424896907') format('woff'),
url('//at.alicdn.com/t/font_2831085_rw79b312ut.ttf?t=1632424896907') format('truetype');
}
.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-shixinzhengfangxing:before {
content: "\e606";
}
`
}
]
},
{
type: 'body',
children: [
helper_1.uiUtil.treeMap(rootObj, {
childrenKey: '_children',
nodeHandler(node) {
// if (node._type == StdUiNodeType.Rect) {
// return {}
// }
if (node._type === StdUiNodeType.Root) {
return {
type: 'div',
attr: {
class: 'std-ui-root',
style: getHtmlStyle({
width: node.width,
height: node.height,
// border: '1px solid #999',
'background-color': node.color || '#fff'
})
},
};
}
if (node._type == StdUiNodeType.Rect) {
// let _attr = objectSomeAttr(attrs, ['width', 'height', 'x', 'y'])
let _node = {
type: 'div',
attr: {
style: getHtmlStyle(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, commonStyle(node)), { position: 'absolute', left: node.x || 0, top: node.y || 0, width: node.width, height: node.height }), borderStyle(node)), borderRadius(node)), fillStyle(node)))
},
};
return _node;
}
if (node._type == StdUiNodeType.Circle) {
// let _attr = objectSomeAttr(attrs, ['width', 'height', 'x', 'y'])
let style = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, commonStyle(node)), { position: 'absolute', left: ((node.cx || 0) - (node.radius || 0)) || 0, top: ((node.cy || 0) - (node.radius || 0)) || 0, width: (node.radius || 0) * 2, height: (node.radius || 0) * 2 }), borderStyle(node)), fillStyle(node)), { 'border-radius': `${(node.radius || 0)}px` });
let _node = {
type: 'div',
attr: {
style: getHtmlStyle(style)
},
// _data: '元',
};
return _node;
}
if (node._type == StdUiNodeType.Ellipse) {
// let _attr = objectSomeAttr(attrs, ['width', 'height', 'x', 'y'])
let rx = node.rx || 0;
let ry = node.ry || 0;
let style = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, commonStyle(node)), { position: 'absolute', left: ((node.cx || 0) - (node.rx || 0)) || 0, top: ((node.cy || 0) - (node.ry || 0)) || 0, width: (node.rx || 0) * 2, height: (node.ry || 0) * 2 }), borderStyle(node)), fillStyle(node)), { 'border-radius': `${rx}px ${rx}px ${rx}px ${rx}px/${ry}px ${ry}px ${ry}px ${ry}px` });
let _node = {
type: 'div',
attr: {
style: getHtmlStyle(style)
},
// _data: '元',
};
return _node;
}
if (node._type == StdUiNodeType.Polygon) {
// let _attr = objectSomeAttr(attrs, ['width', 'height', 'x', 'y'])
const { left, top, width, height } = calcPolygon(node);
let _node = {
type: 'div',
attr: {
class: 'polygon',
style: getHtmlStyle(Object.assign(Object.assign({}, commonStyle(node)), { position: 'absolute', left: left, top: top, width: width, height: height }))
},
_data: helper_1.uiUtil.xmlObj2Xml(convertUiObj2SvgObject({
_type: 'svg',
width: 100,
height: 100,
color: null,
_children: [
Object.assign(Object.assign({}, node), { points: getTranslatePoints(node.points, {
x: 0 - left,
y: 0 - top,
}) })
],
})),
};
return _node;
}
if (node._type == StdUiNodeType.Polyline) {
// let _attr = objectSomeAttr(attrs, ['width', 'height', 'x', 'y'])
const { left, top, width, height } = calcPolygon(node);
let _node = {
type: 'div',
attr: {
class: 'polygon',
style: getHtmlStyle(Object.assign(Object.assign({}, commonStyle(node)), { position: 'absolute', left: left, top: top, width: width, height: height }))
},
_data: helper_1.uiUtil.xmlObj2Xml(convertUiObj2SvgObject({
_type: 'svg',
width: 100,
height: 100,
color: null,
_children: [
Object.assign(Object.assign({}, node), { points: getTranslatePoints(node.points, {
x: 0 - left,
y: 0 - top,
}) })
],
})),
};
return _node;
}
if (node._type == StdUiNodeType.Line) {
// let _attr = objectSomeAttr(attrs, ['width', 'height', 'x', 'y'])
const { x, y, width, height } = calcLine(node);
let _node = {
type: 'div',
attr: {
class: 'line',
style: getHtmlStyle(Object.assign(Object.assign({}, commonStyle(node)), { position: 'absolute', left: x, top: y, width: width, height: height }))
},
_data: helper_1.uiUtil.xmlObj2Xml(convertUiObj2SvgObject({
_type: 'svg',
width: 100,
height: 100,
color: null,
_children: [
Object.assign(Object.assign({}, node), { x1: (node.x1 || 0) - x, y1: (node.y1 || 0) - y, x2: (node.x2 || 0) - x, y2: (node.y2 || 0) - y })
],
})),
};
return _node;
}
if (node._type == StdUiNodeType.Path) {
// let _attr = objectSomeAttr(attrs, ['width', 'height', 'x', 'y'])
// const { x, y, width, height } = calcLine(node)
const bbbox = caster(node.d);
// .toString()
// console.log('bbbox', bbbox)
const newD = serialize(translate(parse(node.d), 0 - bbbox.x1, 0 - bbbox.y1));
// console.log('newD', newD)
let _node = {
type: 'div',
attr: {
class: 'path',
style: getHtmlStyle(Object.assign(Object.assign({}, commonStyle(node)), { position: 'absolute', left: bbbox.x1, top: bbbox.y1, width: bbbox.width, height: bbbox.height }))
},
_data: helper_1.uiUtil.xmlObj2Xml(convertUiObj2SvgObject({
_type: 'svg',
width: bbbox.width,
height: bbbox.height,
color: null,
_children: [
Object.assign(Object.assign({}, node), { d: newD })
],
})),
};
return _node;
}
if (node._type == StdUiNodeType.Image) {
// let _attr = objectSomeAttr(attrs, ['width', 'height', 'x', 'y'])
let _node = {
type: 'img',
attr: {
src: node.href,
style: getHtmlStyle(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, commonStyle(node)), { position: 'absolute', left: node.x || 0, top: node.y || 0, width: node.width, height: node.height }), borderStyle(node)), borderRadius(node)), { 'background-color': node.color || '#fff' }))
},
};
return _node;
}
if (node._type == StdUiNodeType.Text) {
// let _attr = objectSomeAttr(attrs, ['width', 'height', 'x', 'y'])
let style = Object.assign(Object.assign({}, commonStyle(node)), { position: 'absolute', left: node.x || 0, top: node.y || 0,
// width: node.width,
// height: node.height,
// border: '1px solid #999',
// 'color': node.color || '#000',
'color': node.color || '#000', 'font-size': `${node.textSize || 14}px`, 'line-height': `${node.lineHeight || node.textSize || 14}px` });
if (node.fill) {
let reverseDirection = {
top: 'bottom',
bottom: 'top',
left: 'right',
right: 'left',
};
if (node.fill.type == 'linearGradient') {
style['background-image'] = `-webkit-linear-gradient(${reverseDirection[node.fill.direction]}, ${node.fill.colors[0]}, ${node.fill.colors[1]})`;
style['-webkit-background-clip'] = 'text';
style['-webkit-text-fill-color'] = 'transparent';
// style['background-image'] = `linear-gradient(to ${node.fill.direction}, ${node.fill.colors[0]}, ${node.fill.colors[1]})`
}
// direction: 'bottom',
// colors: ['#09c', '#c90'],
}
if (node.fontFamily) {
style['font-family'] = node.fontFamily;
}
// style['outline'] = '1px solid #f00'
if (node.width) {
style['width'] = `${node.width}px`;
}
if (node.height) {
style['height'] = `${node.height}px`;
}
style['display'] = `flex`;
if (node.align == exports.ui.Align.Center) {
style['justify-content'] = `center`;
}
if (node.vAlign == exports.ui.Align.Center) {
style['align-items'] = `center`;
}
// node['class'] = 'iconfont'
if (node.border) {
let stroke = `${node.border.width || 1}px ${node.border.color || '#000'}`;
style['text-stroke'] = stroke;
style['-webkit-text-stroke'] = stroke;
}
let _node = {
type: 'div',
attr: {
// 'class': 'iconfont icon-shixinzhengfangxing',
style: getHtmlStyle(style),
},
_data: node.text
};
return _node;
}
return {
type: 'div',
// _data:
// attr: _attr,
};
}
})
]
},
]
};
}
function convertUiObj2SvgObject(rootObj, toSvgOpts = {
borderPosition: BorderPositionKey.Center,
}) {
// console.log('rootObj', JSON.stringify(rootObj, null, 4))
// breakPoint()
function createShadow(shadow, node) {
const id = (0, helper_1.uid)(8);
const color = Color(shadow.color || '#000');
const rgb = color.object();
// console.log('rgb', rgb)
// console.log('color', )
// fillStyle = {
// color: color.rgb().array().join(','),
let json = {
type: 'filter',
attr: {
id,
// x: node.x,
// y: node.x,
width: 400,
height: 400, // TODO
},
children: [
{
type: 'feOffset',
attr: {
result: "offOut",
in: "SourceAlpha",
dx: shadow.x || 0,
dy: shadow.y || 0,
},
},
{
type: 'feGaussianBlur',
attr: {
result: "blurOut",
in: "offOut",
stdDeviation: shadow.blur ? (shadow.blur / 2) : 0,
},
},
{
type: 'feMorphology',
attr: {
in: "feGaussianBlur",
operator: "dilate",
radius: shadow.spread || 0,
result: "big",
},
},
{
type: 'feBlend',
attr: {
in: "SourceGraphic",
in2: "big",
mode: "normal",
},
children: [],
},
{
type: 'feColorMatrix',
attr: {
type: "matrix",
values: `0 0 0 0 ${rgb.r / 255}
0 0 0 0 ${rgb.g / 255}
0 0 0 0 ${rgb.b / 255}
0 0 0 ${shadow.alpha || 1} 0`,
// radius: shadow.spread || 0,
// result: "big",
},
},
{
type: 'feBlend',
attr: {
in: "SourceGraphic",
// in2: "big",
mode: "normal",
},
children: [],
},
// <feBlend mode="normal" in="SourceGraphic" in2 = "effect1_dropShadow" result = "shape" />
],
};
return {
id,
json,
};
}
function createInnerShadow(shadow, node) {
const id = (0, helper_1.uid)(8);
const color = Color(shadow.color || '#000');
const rgb = color.object();
// console.log('rgb', rgb)
// console.log('color', )
// fillStyle = {
// color: color.rgb().array().join(','),
let json = {
type: 'filter',
attr: {
id,
// x: node.x,
// y: node.x,
// width: 400, // TODO
// height: 400, // TODO
x: "-15.5%",
y: "-15.5%",
width: "131.0%",
height: "131.0%",
filterUnits: "objectBoundingBox",
},
children: [
{
type: 'feGaussianBlur',
attr: {
result: "shadowBlurInner1",
in: "SourceAlpha",
stdDeviation: shadow.blur ? (shadow.blur / 2) : 0,
},
},
{
type: 'feOffset',
attr: {
result: "shadowOffsetInner1",
in: "shadowBlurInner1",
dx: shadow.x || 0,
dy: shadow.y || 0,
},
},
{
type: 'feComposite',
attr: {
in: "shadowOffsetInner1",
in2: "SourceAlpha",
operator: "arithmetic",
k2: "-1",
k3: "1",
result: "shadowInnerInner1",
},
},
{
type: 'feColorMatrix',
attr: {
type: "matrix",
in: 'shadowInnerInner1',
values: `0 0 0 0 ${rgb.r / 255}
0 0 0 0 ${rgb.g / 255}
0 0 0 0 ${rgb.b / 255}
0 0 0 ${shadow.alpha || 1} 0`,
// radius: shadow.spread || 0,
// result: "big",
},
},
],
};
return {
id,
json,
};
}
function createBlur(blur, node) {
const id = (0, helper_1.uid)(8);
// 100 -> 282
// 0 -> 0
// 40 正常
let json = {
type: 'filter',
attr: {
id,
// 太大一般不会怎样,x 不能随便设置,不然可能显示不出来
x: "-400%",
y: "-400%",
width: "881.0%",
height: "881.0%", // TODO
},
children: [
{
type: 'feGaussianBlur',
attr: {
in: "SourceGraphic",
stdDeviation: blur,
},
},
],
};
return {
id,
json,
};
}
const defs = [];
function createTextBg(backgroundColor) {
const id = (0, helper_1.uid)(16);
defs.push({
type: 'filter',
attr: {
id,
x: 0,
y: 0,
width: 1,
height: 1,
},
children: [
{
type: 'feFlood',
attr: {
'flood-color': backgroundColor,
},
},
{
type: 'feComposite',
attr: {
in: 'SourceGraphic',
},
},
],
});
return id;
}
function setStroke(attrs, _attr) {
if (attrs.border) {
const { width = 1, color = '#000' } = attrs.border;
_attr.stroke = color;
// svg stroke-width 有默认值,不能为空
// if (width > 0) {
// }
_attr['stroke-width'] = width;
if (attrs.border.opacity != 1) {
_attr['stroke-opacity'] = attrs.border.opacity || 1;
}
if (attrs.border.dashed) {
_attr['stroke-dasharray'] = Array.isArray(attrs.border.dashed) ? attrs.border.dashed.join(' ') : svg_default_stroke_dasharray;
}
}
}
function fillAndStroke(attrs, _attr) {
if (attrs.fill) {
if (attrs.fill.type == 'linearGradient') {
let ret = createLinearGradient(attrs.fill);
defs.push(ret.json);
_attr.fill = `url(#${ret.id})`;
}
}
else {
if (attrs.color) {
_attr.fill = attrs.color;
}
else {
_attr.fill = 'none';
}
}
setStroke(attrs, _attr);
}
function handleShadow(attrs, _attr, node) {
if (attrs.shadow) {
let ret = createShadow(attrs.shadow, node);
defs.push(ret.json);
_attr.filter = `url(#${ret.id})`;
}
if (attrs.innerShadow) {
let ret = createInnerShadow(attrs.innerShadow, node);
defs.push(ret.json);
_attr.filter = `url(#${ret.id})`;
}
}
function handleCommon(node, attrs) {
handleBlur(node, attrs);
}
function handleBlur(node, attrs) {
if (node.blur) {
let ret = createBlur(node.blur, node);
defs.push(ret.json);
attrs.filter = `url(#${ret.id})`;
}
}
function handleOpacity(attrs, _attr) {
if (attrs.opacity) {
_attr.opacity = attrs.opacity;
}
}
let out = helper_1.uiUtil.treeMap(rootObj, {
childrenKey: '_children',
nodeHandler(node) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
// let type
let attrs = {};
for (let key in node) {
if (!key.match(/^_/)) {
attrs[key] = node[key];
}
}
// if (node._type == 'root') {
// type = 'root'
// } else if (node._type == 'tag') {
// type = node.name
// attrs = node.attribs
// } else {
// if (node._type == 'text') {
// console.log('node', node)
// const { data } = node
// if (data.match(/^\s+$/)) {
// return null
// }
// }
// type = 'other:' + node._type
// }
let _type = node._type;
if (_type === 'root') {
const attrs = {
xmlns: 'http://www.w3.org/2000/svg',
version: '1.1',
};
if (node.width) {
attrs.width = node.width;
}
if (node.height) {
attrs.height = node.height;
}
return {
type: 'svg',
attr: Object.assign(Object.assign({}, attrs), node._svgProps),
};
}
if (_type === StdUiNodeType.Rect) {
let _attr = {};
const borderPosition = ((_a = node.border) === null || _a === void 0 ? void 0 : _a.position) || toSvgOpts.borderPosition;
const borderWidth = ((_b = attrs.border) === null || _b === void 0 ? void 0 : _b.width) || 0;
if (borderPosition == BorderPositionKey.Inside) {
_attr.x = attrs.x + borderWidth / 2;
_attr.y = attrs.y + borderWidth / 2;
_attr.width = attrs.width - borderWidth;
_attr.height = attrs.height - borderWidth;
}
else if (borderPosition == BorderPositionKey.Center) {
// const borderWidth = attrs.border?.width || 0
_attr.x = attrs.x;
_attr.y = attrs.y;
// _attr.width = attrs.width - borderWidth / 2
// _attr.height = attrs.height - borderWidth / 2
_attr.width = attrs.width;
_attr.height = attrs.height;
}
else {
// borderPosition == BorderPositionKey.Outside
_attr.x = attrs.x - borderWidth / 2;
_attr.y = attrs.y - borderWidth / 2;
_attr.width = attrs.width + borderWidth;
_attr.height = attrs.height + borderWidth;
}
// let _attr = objectSomeAttr(attrs, ['width', 'height', 'x', 'y'])
fillAndStroke(attrs, _attr);
if (attrs.radius) {
_attr.rx = attrs.radius;
_attr.ry = attrs.radius;
}
handleShadow(attrs, _attr, node);
handleOpacity(attrs, _attr);
handleCommon(node, _attr);
if (attrs.borderRadius) {
_attr.rx = attrs.borderRadius;
_attr.ry = attrs.borderRadius;
}
const center = {
x: _attr.x + _attr.width / 2,
y: _attr.y + _attr.height / 2,
};
let _node = {
type: 'rect',
attr: Object.assign(Object.assign(Object.assign({}, _attr), node._svgProps), { transform: getTransform(node, center) || undefined, style: getStyleText(node) || undefined }),
};
return _node;
}
if (_type === 'image') {
let _attr = {};
if (BORDER_INSIDE && !(toSvgOpts === null || toSvgOpts === void 0 ? void 0 : toSvgOpts.forceImage)) {
const borderWidth = ((_c = attrs.border) === null || _c === void 0 ? void 0 : _c.width) || 0;
_attr.x = attrs.x + borderWidth / 2;
_attr.y = attrs.y + borderWidth / 2;
_attr.width = attrs.width - borderWidth;
_attr.height = attrs.height - borderWidth;
}
else {
_attr.x = attrs.x;
_attr.y = attrs.y;
_attr.width = attrs.width;
_attr.height = attrs.height;
}
// fillAndStroke(attrs, _attr)
setStroke(attrs, _attr);
if (attrs.radius) {
_attr.rx = attrs.radius;
_attr.ry = attrs.radius;
}
if (!(toSvgOpts === null || toSvgOpts === void 0 ? void 0 : toSvgOpts.forceImage)) {
createImage(node, _attr, defs);
}
// defs.push(ret.json)
// _attr.fill = `url(#pattern0)`
handleShadow(attrs, _attr, node);
handleOpacity(attrs, _attr);
setStroke(attrs, _attr);
handleCommon(node, _attr);
if (attrs.borderRadius) {
_attr.rx = attrs.borderRadius;
_attr.ry = attrs.borderRadius;
}
const center = {
x: _attr.x + _attr.width / 2,
y: _attr.y + _attr.height / 2,
};
if (toSvgOpts === null || toSvgOpts === void 0 ? void 0 : toSvgOpts.forceImage) {
_attr.href = attrs.href;
let _node = {
type: 'image',
attr: Object.assign(Object.assign(Object.assign({}, _attr), node._svgProps), { transform: getTransform(node, center) || undefined, style: getStyleText(node) || undefined }),
};
return _node;
}
else {
let _node = {
type: 'rect',
attr: Object.assign(Object.assign(Object.assign({}, _attr), node._svgProps), { transform: getTransform(node, center) || undefined, style: getStyleText(node) || undefined }),
};
return _node;
}
}
if (_type === StdUiNodeType.Circle) {
// let _attr: any = {}
let _attr = objectSomeAttr(attrs, ['cx', 'cy']);
fillAndStroke(attrs, _attr);
handleShadow(attrs, _attr, node);
handleOpacity(attrs, _attr);
if (!attrs.radius) {
throw new Error('circle need radius attr');
}
const borderPosition = ((_d = node.border) === null || _d === void 0 ? void 0 : _d.position) || toSvgOpts.borderPosition;
const borderWidth = ((_e = attrs.border) === null || _e === void 0 ? void 0 : _e.width) || 0;
if (borderPosition == BorderPositionKey.Inside) {
_attr.r = attrs.radius - borderWidth / 2;
}
else if (borderPosition == BorderPositionKey.Center) {
_attr.r = attrs.radius;
// _attr.r = attrs.radius - borderWidth / 4
}
else {
// outside
_attr.r = attrs.radius + borderWidth / 2;
}
const center = {
x: _attr.cx,
y: _attr.cy,
};
let _node = {
type: 'circle',
attr: Object.assign(Object.assign(Object.assign({}, _attr), node._svgProps), { transform: getTransform(node, center) || undefined, style: getStyleText(node) || undefined }),
};
return _node;
}
if (_type === StdUiNodeType.Text) {
let _attr = objectSomeAttr(attrs, ['x', 'y']);
let _style = Object.assign({}, getStyle(node));
const lineHeight = node.lineHeight || attrs.textSize * 1; // TODO
const fontSize = node.textSize || 12;
if (attrs.textSize) {
// Sketch 默认行高 1.4
//
_style['font-size'] = `${attrs.textSize}px`;
_style['line-height'] = `${lineHeight}px`;
}
if (attrs.fontFamily) {
_style['font-family'] = `${attrs.fontFamily}`;
}
// style += `outline: 1px dashed #666;`
const { fontStyle = {} } = node;
const { bold = false, italic = false, underline = false } = fontStyle;
if (bold) {
_style['font-weight'] = `bold`;
}
if (italic) {
_style['font-style'] = `italic`;
}
if (underline) {
_style['text-decoration'] = `underline`;
}
const extraStyle = node._svgStyle || {};
for (let key in extraStyle) {
_style[key] = extraStyle[key];
}
fillAndStroke(attrs, _attr);
handleShadow(attrs, _attr, node);
handleOpacity(attrs, _attr);
_attr.style = styleToText(_style);
// _attr['dominant-baseline'] = 'text-before-edge'
// refer https://www.zhihu.com/question/58620241
// _attr['alignment-baseline'] = 'before-edge'
_attr['alignment-baseline'] = 'hanging';
// Attribute("alignment-baseline", "hanging");
if (attrs.centerd) {
_attr['text-anchor'] = 'middle'; // 水平方向居中
_attr['alignment-baseline'] = undefined;
_attr['dominant-baseline'] = 'middle';
// : ;
// : middle; //垂直居中
}
if (attrs.align == exports.ui.Align.Center) {
_attr['text-anchor'] = 'middle'; // 水平方向居中
if (attrs.width) {
_attr.x = parseFloat(attrs.x) + parseFloat(attrs.width) / 2;
}
}
if (attrs.vAlign == exports.ui.Align.Center) {
_attr['alignment-baseline'] = 'middle';
// _attr['dominant-baseline'] = 'middle'
if (attrs.height) {
_attr.y = parseFloat(attrs.y) + parseFloat(attrs.height) / 2;
}
}
if (attrs.backgroundColor) {
const id = createTextBg(attrs.backgroundColor);
_attr.filter = `url(#${id})`;
}
// baselineY = lineHeight ? fontSize
// 105 = (140 - 100) / 2 + 100 * 0.85
// 136 = (200 - 100) / 2 + 100 * 0.85
// 143 = (200 - 120) / 2 + 120 * 0.8583333333333333
// baselineY = (lineHeight - fontSize) / 2 + fontSize * 0.8583333333333333
const baselineY = (lineHeight - fontSize) / 2 + fontSize * 0.8583333333333333;
const children = [];
if (node.rich) {
node.rich.forEach((row, rowIdx) => {
row.forEach((cell, colIdx) => {
const attr = {
// x: _attr.x,
// y: _attr.y + lineHeight,
y: _attr.y + rowIdx * lineHeight + baselineY,
};
if (colIdx == 0) {
attr.x = _attr.x;
}
const _style = {};
const extraStyle = cell._svgStyle || {};
for (let key in extraStyle) {
_style[key] = extraStyle[key];
}
attr.style = styleToText(_style);
children.push({
type: 'tspan',
attr: Object.assign(Object.assign({}, attr), cell._svgProps),
_data: cell.text,
});
});
});
}
else {
const lines = attrs.text.split('\n');
lines.forEach((line, lineIdx) => {
children.push({
type: 'tspan',
attr: {
x: _attr.x,
// y: _attr.y + lineHeight,
y: _attr.y + lineIdx * lineHeight + baselineY,
},
_data: line
});
});
}
let _node = {
type: 'text',
attr: Object.assign(Object.assign({}, _attr), node._svgProps),
// _data: attrs.text
children,
// children: [
// {
// },
// // {
// // type: 'tspan',
// // // attr: {
// // // x: _attr.x,
// // // y: _attr.y + lineHeight,
// // // },
// // _data: 'append'
// // }
// ]
};
// < tspan xmlns = "http://www.w3.org/2000/svg" x = "100" y = "106" > 你好 < /tspan>
return _node;
}
if (_type === 'line') {
let _attr = objectSomeAttr(attrs, ['x1', 'y1', 'x2', 'y2']);
handleOpacity(attrs, _attr);
// if (attrs.radius) {
// _attr.r = attrs.radius
// }
// if (attrs.color) {
// _attr.fill = attrs.color
// }
// let style = ''
// if (attrs.textSize) {
// style += `font-size: ${attrs.textSize}px`
// }
// _attr.style = style
// _attr['stroke'] = '#000'
// if (attrs.color) {
// _attr.stroke = attrs.color
// } else {
// _attr.stroke = '#000'
// }
// _attr['stroke-width'] = 1
const { border = {} } = attrs;
const { color = '#000', width = 1 } = border;
_attr.stroke = color;
_attr['stroke-width'] = width;
const center = {
x: (_attr.x1 + _attr.x2) / 2,
y: (_attr.y1 + _attr.y2) / 2,
};
let _node = {
type: 'line',
attr: Object.assign(Object.assign(Object.assign({}, _attr), node._svgProps), { transform: getTransform(node, center) || undefined, style: getStyleText(node) || undefined }),
// _data: attrs.text
// _attrs: attrs,
};
// < tspan xmlns = "http://www.w3.org/2000/svg" x = "100" y = "106" > 你好 < /tspan>
return _node;
}
if (_type === StdUiNodeType.Polygon) {
let _attr = objectSomeAttr(attrs, []);
const { left, top, width, height } = calcPolygon(node);
const center = {
x: left + width / 2,
y: top + height / 2,
};
fillAndStroke(attrs, _attr);
handleShadow(attrs, _attr, node);
handleOpacity(attrs, _attr);
if (attrs.points) {
const borderPosition = ((_f = node.border) === null || _f === void 0 ? void 0 : _f.position) || toSvgOpts.borderPosition;
const borderWidth = ((_g = attrs.border) === null || _g === void 0 ? void 0 : _g.width) || 0;
if (borderPosition == BorderPositionKey.Inside || borderPosition == BorderPositionKey.Outside) {
const scale = (width - borderWidth * (borderPosition == BorderPositionKey.Inside ? 1 : -1)) / width;
_attr['points'] = attrs.points.map(pt => `${pt.x},${pt.y}`).join(' ');
_attr['points'] = attrs.points
.map(pt => {
return {
x: center.x + (pt.x - center.x) * scale,
y: center.y + (pt.y - center.y) * scale,
};
})
.map(pt => `${pt.x},${pt.y}`).join(' ');
}
else {
_attr['points'] = attrs.points.map(pt => `${pt.x},${pt.y}`).join(' ');
}
}
let _node = {
type: 'polygon',
attr: Object.assign(Object.assign(Object.assign({}, _attr), node._svgProps), { transform: getTransform(node, center) || undefined, style: getStyleText(node) || undefined }),
// _attrs: attrs,
};
return _node;
}
if (_type === 'polyline') {
let _attr = objectSomeAttr(attrs, []);
// if (attrs.color) {
// _attr.fill = attrs.color
// } else {
// _attr.fill = 'none'
// }
const { left, top, width: _width, height } = calcPolygon(node);
const center = {
x: left + _width / 2,
y: top + height / 2,
};
const { border = {} } = attrs;
const { color = '#000', width = 1 } = border;
_attr.stroke = color;
_attr['stroke-width'] = width;
handleOpacity(attrs, _attr);
// if (attrs.border) {
// } else {
// }
// if (attrs.color) {
// _attr.stroke = attrs.color
// } else {
// _attr.stroke = '#000'
// }
_attr.fill = 'none';
if (attrs.points) {
_attr['points'] = attrs.points.map(pt => `${pt.x},${pt.y}`).join(' ');
}
// if (attrs.radius) {
// _attr.rx = attrs.radius
// _attr.ry = attrs.radius
// }
let _node = {
type: 'polyline',
attr: Object.assign(Object.assign(Object.assign({}, _attr), node._svgProps), { transform: getTransform(node, center) || undefined, style: getStyleText(node) || undefined }),
// _attrs: attrs,
};
return _node;
}
if (_type === StdUiNodeType.Ellipse) {
let _attr = {};
_attr.cx = attrs.cx;
_attr.cy = attrs.cy;
const borderPosition = ((_h = node.border) === null || _h === void 0 ? void 0 : _h.position) || toSvgOpts.borderPosition;
const borderWidth = ((_j = attrs.border) === null || _j === void 0 ? void 0 : _j.width) || 0;
if (borderPosition == BorderPositionKey.Inside) {
_attr.rx = attrs.rx - borderWidth / 2;
_attr.ry = attrs.ry - borderWidth / 2;
}
else if (borderPosition == BorderPositionKey.Center) {
_attr.rx = attrs.rx - borderWidth / 4;
_attr.ry = attrs.ry - borderWidth / 4;
}
else {
// outside
_attr.rx = attrs.rx;
_attr.ry = attrs.ry;
}
fillAndStroke(attrs, _attr);
handleShadow(attrs, _attr, node);
handleOpacity(attrs, _attr);
let _node = {
type: 'ellipse',
attr: Object.assign(Object.assign(Object.assign({}, _attr), node._svgProps), { transform: getTransform(node, { x: attrs.cx, y: attrs.cy }) || undefined, style: getStyleText(node) || undefined }),
// _attrs: attrs,
};
return _node;
}
if (_type === 'path') {
let _attr = {};
fillAndStroke(attrs, _attr);
handleShadow(attrs, _attr, node);
handleOpacity(attrs, _attr);
// if (attrs.points) {
// _attr['points'] = attrs.points.map(pt => `${pt.x},${pt.y}`).join(' ')
// }
// let borderWidth = 0
// if (attrs.border) {
// // _attr.stroke = attrs.border.color || '#000'
// borderWidth = attrs.border.width || 1
// }
let pathD = attrs.d;
// console.log('pathD', pathD)
const bbox = caster(pathD);
const center = {
x: bbox.x1 + bbox.width / 2,
y: bbox.y1 + bbox.height / 2,
};
const borderPosition = ((_k = node.border) === null || _k === void 0 ? void 0 : _k.position) || toSvgOpts.borderPosition;
const borderWidth = ((_l = attrs.border) === null || _l === void 0 ? void 0 : _l.width) || 0;
if (borderPosition == BorderPositionKey.Inside) {
// const bbox = caster(pathD)
if (bbox.width != 0) {
// console.log('bbox', bbox, (bbox.width - (borderWidth)) / bbox.width)
const transformedD = svgpath(pathD)
.translate(-bbox.x1, -bbox.y1)
.scale((bbox.width - (borderWidth)) / bbox.width)
// .rel()
.translate(bbox.x1 + borderWidth / 2, bbox.y1 + borderWidth / 2)
// .round(1)
.toString();
pathD = transformedD;
// console.log('pathD', pathD)
}
}
else if (borderPosition == BorderPositionKey.Outside) {
// const bbox = caster(pathD)
if (bbox.width != 0) {
// console.log('bbox', bbox, (bbox.width - (borderWidth)) / bbox.width)
const transformedD = svgpath(pathD)
.translate(-bbox.x1, -bbox.y1)
.scale((bbox.width + (borderWidth)) / bbox.width)
// .rel()
.translate(bbox.x1 - borderWidth / 2, bbox.y1 - borderWidth / 2)
// .round(1)
.toString();
pathD = transformedD;
// console.log('pathD', pathD)
}
}
_attr.d = pathD;
// breakPoint()
if (node.arrow) {
const { start = false, end = false } = node.arrow;
function addArrow(direction, type) {
var _a;
const markerId = (0, helper_1.uid)(16);
// 0 14
// 10 30
const markerLength = 14 + borderWidth * ((30 - 14) / (10 - 0));
// const markerWidth = borderWidth + 10
// const markerLength = 30
// 0 10
// 10 26
const markerWidth = 10 + borderWidth * ((26 - 10) / (10 - 0));
// const markerWidth = 26
const markerColor = ((_a = node.border) === null || _a === void 0 ? void 0 : _a.color) || '#000';
// console.log('markerWidth', markerWidth)
// console.log('markerLength', markerLength)
// console.log('refX', markerLength / 30 * 18)
// breakPoint()
defs.push({
type: 'marker',
attr: {
xmlns: "http://www.w3.org/2000/svg",
id: markerId,
markerWidth: markerLength,
markerHeight: markerWidth,
refX: markerLength / 30 * 18,
refY: markerWidth / 2,
viewBox: `0 0 ${markerLength} ${markerWidth}`,
orient: "auto",
markerUnits: "userSpaceOnUse",
// 'stroke-dasharray': "0,0",
},
children: [
{
type: 'path',
attr: {
// end
d: direction == 'start' ? `M${markerLength},0 L0,${markerWidth / 2} L${markerLength},${markerWidth} L${markerLength},0`
: `M0,0 L${markerLength},${markerWidth / 2} L0,${markerWidth} L0,0`,
// d: direction == 'start' ? `M${markerLength},0 L0,${markerWidth / 2} L${markerLength},${markerWidth}`
// : `M0,0 L${markerLength},${markerWidth / 2} L0,${markerWidth}`,
// fill: 'none',
fill: type == 'normal' ? 'none' : type == 'dashedArrow' ? '#fff' : markerColor,
stroke: markerColor,
'stroke-width': "2",
}
}
]
});
_attr['marker-' + direction] = `url(#${markerId})`;
}
if (start) {
addArrow('start', start);
}
if (end) {
addArrow('end', end);
}
}
let _node = {
type: 'path',
attr: Object.assign(Object.assign(Object.assign({}, _attr), node._svgProps), { transform: getTransform(node, center) || undefined, style: getStyleText(node) || undefined }),
};
return _node;
}
if (_type === 'group') {
let _attr = objectSomeAttr(attrs, ['d']);
handleOpacity(attrs, _attr);
let _node = {
type: 'g',
attr: Object.assign(Object.assign(Object.assign({}, _attr), node._svgProps), { style: getStyleText(node) || undefined }),
// _attrs: attrs,
};
return _node;
}
if (attrs.border) {
attrs.stroke = attrs.border.color;
attrs['stroke-width'] = attrs.border.width || 1;
// TODO
delete attrs.border;
}
let result = {
type: node._type,
// children: node._children as any,
attr: Object.assign(Object.assign({}, attrs), node._svgProps),
// _attrs: attrs,
// _type: type,
// ...attrs,
};
return result;
}
});
function createImage(node, _attr, defs) {
const patternId = `pattern${(0, helper_1.uid)(8)}`;
const imgId = `image${(0, helper_1.uid)(8)}`;
defs.push({
type: 'pattern',
attr: {
id: patternId,
patternContentUnits: "objectBoundingBox",
width: "1",
height: "1",
},
children: [
{
type: 'use',
attr: {
href: `#${imgId}`,
transform: "scale(0.005)",
},
}
]
});
defs.push({
type: 'image',
attr: {
id: imgId,
width: node.originWidth,
height: node.originWidth,
// width: 200,
// height: 200,
href: node.href,
}
});
_attr.fill = `url(#${patternId})`;
}
function createLinearGradient(gradient) {
const { direction, colors = [], stops = [], from, to } = gradient;
// colors: ['#09c', '#c90'],
const [color1, color2] = colors;
const id = (0, helper_1.uid)(8);
let dradientAttrs = {
right: {
x1: "0%",
y1: "0%",
x2: "100%",
y2: "0%",
},
left: {
x1: "100%",
y1: "0%",
x2: "0%",
y2: "0%",
},
top: {
x1: "0%",
y1: "100%",
x2: "0%",
y2: "0%",
},
bottom: {
x1: "0%",
y1: "0%",
x2: "0%",
y2: "100%",
},
};
let dradientAttr;
if (from && to) {
dradientAttr = {
x1: (from.x * 100) + '%',
y1: (from.y * 100) + '%',
x2: (to.x * 100) + '%',
y2: (to.y * 100) + '%',
};
}
else if (typeof direction == 'string') {
dradientAttr = dradientAttrs[direction];
}
else {
const coordinates = angleToCoordinates(direction);
dradientAttr = {
x1: (coordinates.x1 * 100) + '%',
y1: (coordinates.y1 * 100) + '%',
x2: (coordinates.x2 * 100) + '%',
y2: (coordinates.y2 * 100) + '%',
};
// console.log('coordinates', coordinates)
// throw new Error('asd')
}
// if (direction == 'right') {
// dradientAttr =
// }
let children;
if (stops.length > 0) {
children = stops.map(stop => {
return {
type: 'stop',
attr: {
offset: (stop.position * 100) + '%',
style: `stop-color:${stop.color};stop-opacity:1`,
},
};
});
// ret['background-image'] = `linear-gradient(to ${gradient.direction}deg, ${gradient.stops.map(stop => `${stop.color}`).join(', ')})`
}
else {
children = [
{
type: 'stop',
attr: {
offset: "0%",
style: `stop-color:${color1};stop-opacity:1`,
},
},
{
type: 'stop',
attr: {
offset: "100%",
style: `stop-color:${color2};stop-opacity:1`,
},
},
];
}
return {
id,
json: {
type: 'linearGradient',
attr: Object.assign({ id }, dradientAttr),
children,
}
};
}
// bg
out.children = [
{
type: 'defs',
attr: {},
children: defs,
},
// 背景在前面
{
type: 'rect',
attr: {
x: 0,
y: 0,
width: rootObj.width,
height: rootObj.height,
fill: rootObj.color == null ? 'none' : (rootObj.color || '#fff'),
},
},
{
type: 'g',
attr: {},
children: out.children,
},
];
// out.children.unshift()
// console.debug(out)
return out;
}
// html css box-sizing border-box 默认 inside
// svg default center
// Sketch default center,can set
const BorderPositionKey = {
Inside: 'inside',
Outside: 'outside',
Center: 'center',
};
class StdUI {
constructor(doc) {
this.root = doc.root;
}
toSvg(toSvgOpts) {
// console.log('svgObj', JSON.stringify(convertUiObj2SvgObject(uiObj), null, 4))
// fs.writeFileSync('out.svg', , 'utf8')
const result = helper_1.uiUtil.xmlObj2Xml(convertUiObj2SvgObject(this.root, toSvgOpts));
return result.replace(/\s+?<tspan/g, '<tspan');
}
toProcessOn() {
function createNode(node, otherAttr) {
let fillStyle = {};
if (node.color) {
const color = Color(node.color);
// console.log('color', )
fillStyle = {
color: color.rgb().array().join(','),
"type": "solid"
};
}
return Object.assign({ "parent": "", "link": "", "shapeStyle": {
"alpha": 1
}, "textBlock": [
{
"position": {
"w": "w-20",
"x": 10,
"h": "h",
"y": 0
},
"text": ""
}
], "lineStyle": {}, "children": [], "resizeDir": [
"tl",
"tr",
"br",
"bl"
], fillStyle, "theme": {}, "category": "basic", "locked": false, "group": "" }, otherAttr);
}
function createRect(node) {
return createNode(node, {
"name": "rectangle",
"anchors": [
{
"x": "w/2",
"y": "0"
},
{
"x": "w/2",
"y": "h"
},
{
"x": "0",
"y": "h/2"
},
{
"x": "w",
"y": "h/2"
}
],
"title": "矩形",
"props": {
"zindex": 1,
"w": node.width,
"x": node.x,
"h": node.height,
"y": node.y,
"angle": 0
},
"path": [
{
"actions": [
{
"x": "0",
"action": "move",
"y": "0"
},
{
"x": "w",
"action": "line",
"y": "0"
},
{
"x": "w",
"action": "line",
"y": "h"
},
{
"x": "0",
"action": "line",
"y": "h"
},
{
"action": "close"
}
]
}
],
"id": (0, helper_1.uid)(13),
"attribute": {
"container": false,
"rotatable": true,
"visible": true,
"collapsable": false,
"collapsed": false,
"linkable": true,
"markerOffset": 5
},
});
}
function createCircle(node) {
return createNode(node, {
"textBlock": [
{
"position": {
"w": "w-20",
"x": 10,
"h": "h",
"y": 0
},
"text": ""
}
],
"anchors": [
{
"x": "w/2",
"y": "0"
},
{
"x": "w/2",
"y": "h"
},
{
"x": "0",
"y": "h/2"
},
{
"x": "w",
"y": "h/2"
}
],
"title": "圆形",
"fontStyle": {},
"dataAttributes": [],
"props": {
"zindex": 1,
"x": node.cx - node.radius,
"y": node.cy - node.radius,
"w": node.radius * 2,
"h": node.radius * 2,
"angle": 0
},
"path": [
{
"actions": [
{
"x": "0",
"action": "move",
"y": "h/2"
},
{
"y1": "-h/6",
"x": "w",
"action": "curve",
"x1": "0",
"y2": "-h/6",
"y": "h/2",
"x2": "w"
},
{
"y1": "h+h/6",
"x": "0",
"action": "curve",
"x1": "w",
"y2": "h+h/6",
"y": "h/2",
"x2": "0"
},
{
"action": "close"
}
]
}
],
"lineStyle": {},
"children": [],
"resizeDir": [
"tl",
"tr",
"br",
"bl"
],
"name": "round",
"theme": {},
"id": (0, helper_1.uid)(13),
"attribute": {
"container": false,
"rotatable": true,
"visible": true,
"collapsable": false,
"collapsed": false,
"linkable": true,
"markerOffset": 5
},
});
}
function createLine(node) {
return {
"linkerType": "normal",
"lineStyle": {
"endArrowStyle": "none"
},
"name": "linker",
"from": {
"x": node.x1,
"y": node.y1
},
"to": {
"x": node.x2,
"y": node.y2
},
"id": (0, helper_1.uid)(14),
"text": "",
"locked": false,
"props": {
"zindex": 1
},
"dataAttributes": [],
"group": "",
"points": []
};
}
function createText(node) {
let fontStyle = {
size: node.textSize || 14
};
const color = Color(node.color);
// console.log('color', )
if (node.color) {
fontStyle.color = color.rgb().array().join(',');
}
return createNode(node, {
"name": "text",
"parent": "",
"link": "",
"shapeStyle": {
"alpha": 1
},
"textBlock": [
{
"position": {
"w": "w",
"x": 0,
"h": "h",
"y": 0
},
"text": node.text
}
],
"anchors": [
{
"x": "w/2",
"y": "0"
},
{
"x": "w/2",
"y": "h"
},
{
"x": "0",
"y": "h/2"
},
{
"x": "w",
"y": "h/2"
}
],
"title": "文本",
fontStyle,
"props": {
"zindex": 1,
"x": node.x,
"w": (node.textSize || 14) * node.text.length,
"h": node.textSize || 14,
"y": node.y,
"angle": 0
},
"path": [
{
"lineStyle": {
"lineWidth": 0
},
"fillStyle": {
"type": "none"
},
"actions": [
{
"x": "0",
"action": "move",
"y": "0"
},
{
"x": "w",
"action": "line",
"y": "0"
},
{
"x": "w",
"action": "line",
"y": "h"
},
{
"x": "0",
"action": "line",
"y": "h"
},
{
"action": "close"
}
]
}
],
"lineStyle": {
"lineColor": "229,115,115"
},
"children": [],
"resizeDir": [
"tl",
"tr",
"br",
"bl"
],
"theme": {},
"attribute": {
"container": false,
"rotatable": true,
"visible": true,
"collapsable": false,
"collapsed": false,
"linkable": true,
"markerOffset": 5
},
"category": "basic",
"locked": false,
"group": ""
});
}
let elementMap = {};
helper_1.uiUtil.treeMap(this.root, {
childrenKey: '_children',
nodeHandler(node) {
if (node._type == 'rect') {
let rect = createRect(node);
elementMap[rect.id] = rect;
return rect;
}
if (node._type == 'circle') {
let rect = createCircle(node);
elementMap[rect.id] = rect;
return rect;
}
if (node._type == 'line') {
let rect = createLine(node);
elementMap[rect.id] = rect;
return rect;
}
if (node._type == 'text') {
let rect = createText(node);
elementMap[rect.id] = rect;
return rect;
}
// if (node._type == 'text') {
// let rect = createText(node)
// elementMap[rect.id] = rect
// }
return {};
// TODO 没有适配 root
// throw new Error(`unknow type ${node._type}`)
}
});
const obj = {
"diagram": {
"elements": {
"elements": elementMap,
"page": {
"padding": 0,
"backgroundColor": "transparent",
"orientation": "portrait",
"gridSize": 25,
"width": this.root.width,
"showGrid": true,
"lineJumps": false,
"height": this.root.height,
}
}
},
"meta": {
"diagramInfo": {
"title": "未命名文件",
"category": "flow"
},
"id": "6132cea2e0b34d35500338d3",
"type": "ProcessOn Schema File",
"version": "1.0"
}
};
return JSON.stringify(obj, null, 4);
}
toHtml() {
return helper_1.uiUtil.xmlObj2Xml(convertUiObj2HtmlObject(this.root));
}
}
exports.StdUI = StdUI;
//# sourceMappingURL=index.js.map