132 lines
3.7 KiB
JavaScript
132 lines
3.7 KiB
JavaScript
import SvgNode from "./SvgNode.js";
|
|
|
|
export default {
|
|
// 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 `<path d="M0 0 L${c0} ${s0} A ${r} ${r} 0 ${aa} 0 ${c1} ${s1} z" stroke-width="3" stroke="#f00" fill="#0f0"/>`;
|
|
// },
|
|
|
|
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"
|
|
})
|
|
},
|
|
|
|
container(items){
|
|
return new SvgNode(null, null, items)
|
|
},
|
|
|
|
group(items){
|
|
return new SvgNode("g", null, items)
|
|
},
|
|
|
|
circle(r) {
|
|
return new SvgNode("circle", {r})
|
|
},
|
|
|
|
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]}`)})
|
|
},
|
|
|
|
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})
|
|
},
|
|
|
|
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` });
|
|
},
|
|
|
|
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
|
|
*/
|
|
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 => this.ring_sector(r0, r1, x.a0 * 360 / sum, x.a1 * 360 / sum).add_style(x.style))
|
|
|
|
return this.group(items)
|
|
},
|
|
|
|
text(text) {
|
|
let node = new SvgNode("text");
|
|
node.items = [text];
|
|
node.set_attrs({x: 0, y: 0})
|
|
return node;
|
|
},
|
|
|
|
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})
|
|
},
|
|
|
|
|
|
}
|
|
|
|
};
|