app_mapbuilder/svgmap/drawers/svg-nodes.js
2022-05-23 14:30:34 +05:00

140 lines
3.6 KiB
JavaScript

const SvgNode = require("./../svg-node.js");
function svg() {
return new SvgNode("svg", {
version: "1.1",
xmlns: "http://www.w3.org/2000/svg",
"xml:space": "preserve",
"xmlns:xlink": "http://www.w3.org/1999/xlink",
style: "shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd",
// viewBox: "0 0 2000 2000"
});
}
function node(name, attrs, items) {
return new SvgNode(name, attrs, items);
}
function container(items) {
return new SvgNode(null, null, items);
}
function group(items) {
return new SvgNode("g", null, items);
}
function circle(r) {
return new SvgNode("circle", { r });
}
function ngon(r, n, ang = 0) {
const da = (2 * Math.PI) / n;
ang = (ang * Math.PI) / 180;
const pts = Array(n)
.fill(0)
.map((x, i) => [Math.sin(i * da + ang) * r, Math.cos(i * da + ang) * r]);
return new SvgNode("polygon", { points: pts.map((x) => `${x[0]},${x[1]}`) });
}
function spike1(w, h, ang) {
const da = (ang * Math.PI) / 180;
const sa = Math.sin(da);
const ca = Math.cos(da);
h = h / 2;
const pts = `${-sa * h},${-ca * h} ${ca * w},${-sa * w}, ${sa * h},${ca * h}`;
return new SvgNode("polygon", { points: pts });
}
function sector(r, a0, a1) {
const k = Math.PI / 180;
let s0 = -Math.sin(a0 * k) * r;
let c0 = Math.cos(a0 * k) * r;
let s1 = -Math.sin(a1 * k) * r;
let c1 = Math.cos(a1 * k) * r;
var aa = a1 - a0 > 180 ? 1 : 0;
// var p = new TimalSvg.Data.SvgPath(string.Format("M0 0 L{0} 0 A {0} {0} 0 {3} 0 {1} {2} z", FN(r), ca, sa, aa));
// p.Transform = string.Format("rotate({0})", FN(ang / 2));
return new SvgNode("path", { d: `M0 0 L${c0} ${s0} A ${r} ${r} 0 ${aa} 0 ${c1} ${s1} z` });
}
function ring_sector(r0, r1, a0, a1) {
const k = Math.PI / 180;
let s0 = -Math.sin(a0 * k);
let c0 = Math.cos(a0 * k);
let s1 = -Math.sin(a1 * k);
let c1 = Math.cos(a1 * k);
var aa = a1 - a0 > 180 ? 1 : 0;
return new SvgNode("path", {
d: `M${c0 * r0} ${s0 * r0}
A ${r0} ${r0} 0 ${aa} 0 ${c1 * r0} ${s1 * r0}
L${c1 * r1} ${s1 * r1}
A ${r1} ${r1} 0 ${aa} 1 ${c0 * r1} ${s0 * r1} z`,
});
}
/**
*
* @param r0
* @param r1
* @param a0
* @param a1
* @param { [{v, style}] } rings
*/
function ring_sectors(r0, r1, sectors) {
let sum = sectors.reduce((s, c) => s + c.v, 0);
let angs = sectors.reduce((s, c, i) => [...s, { ...c, a0: i && s[i - 1].a1, a1: c.v + (i && s[i - 1].a1) }], []);
let items = angs.map((x) => ring_sector(r0, r1, (x.a0 * 360) / sum, (x.a1 * 360) / sum).add_style(x.style));
return group(items);
}
function text(text) {
let node = new SvgNode("text");
node.items = text ? [text] : [];
node.set_attrs({ x: 0, y: 0 });
return node;
}
const defs = {
simple: {
radialGradient(id, color0, color1) {
let s0 = new SvgNode("stop", { offset: "0%", "stop-color": color0 });
let s1 = new SvgNode("stop", { offset: "100%", "stop-color": color1 });
return new SvgNode("radialGradient", { id }).append(s0, s1);
},
},
radialGradient(id, cx, cy, r) {
return new SvgNode("radialGradient", { id, cx, cy, r });
},
stop(offset, color) {
return new SvgNode("stop", { offset, "stop-color": color });
},
};
function corel_layer(name) {
return new SvgNode('g', null, [`<metadata id="CorelCorpID_${name}Corel-Layer"/>`]).set_attr("id", name)
}
module.exports = {
node,
svg,
container,
group,
circle,
ngon,
spike1,
sector,
ring_sector,
ring_sectors,
text,
corel_layer
};
module.exports.default = module.exports;