@chocbite/ts-lib-svg 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,157 @@
1
+ declare class SVGAttributes<T extends SVGElement> {
2
+ readonly elem: T;
3
+ constructor(elem: T);
4
+ /** Sets the stroke color of the SVG element */
5
+ stroke(stroke: string): this;
6
+ /** Sets the stroke color of the SVG element */
7
+ s(stroke: string): this;
8
+ /** Sets the fill color of the SVG element */
9
+ fill(fill: string): this;
10
+ /** Sets the fill color of the SVG element */
11
+ f(fill: string): this;
12
+ /** Sets the stroke width of the SVG element */
13
+ stroke_width(width: number): this;
14
+ /** Sets the stroke width of the SVG element */
15
+ sw(width: number): this;
16
+ /** Adds one or more class names to the SVG element */
17
+ class_list(...class_name: string[]): this;
18
+ /** Adds one or more class names to the SVG element */
19
+ cl(...class_name: string[]): this;
20
+ /** Sets an arbitrary attribute on the SVG element */
21
+ attribute(name: string, value: string): this;
22
+ /** Sets an arbitrary attribute on the SVG element */
23
+ a(name: string, value: string): this;
24
+ }
25
+
26
+ /**This creates a svg circle
27
+ * @param center_x x coordinate of center
28
+ * @param center_y y coordinate of center
29
+ * @param radius radius of circle*/
30
+ declare function circle(center_x: number, center_y: number, radius: number): SVGAttributes<SVGCircleElement>;
31
+ /**This draws parts of a circle/ellipse, the circle direction is reversed
32
+ * @param center_x the center point on the x axis
33
+ * @param center_y the center point on the y axis
34
+ * @param radius radius in x axis
35
+ * @param start_angle start angle in radians
36
+ * @param end_angle end anglein radians*/
37
+ declare function circle_arc(center_x: number, center_y: number, radius: number, start_angle: number, end_angle: number): SVGAttributes<SVGPathElement>;
38
+
39
+ /**This creates a svg ellipse
40
+ * @param center_x x coordinate of center
41
+ * @param center_y y coordinate of center
42
+ * @param radius_x x radius of circle
43
+ * @param radius_y y radius of circle*/
44
+ declare function ellipse(center_x: number, center_y: number, radius_x: number, radius_y: number): SVGAttributes<SVGEllipseElement>;
45
+ /**This draws parts of a circle/ellipse, the circle direction is reversed
46
+ * @param center_x the center point on the x axis
47
+ * @param center_y the center point on the y axis
48
+ * @param radius_x radius in x axis
49
+ * @param radius_y radius in y axis
50
+ * @param start_angle start angle in radians
51
+ * @param end_angle end anglein radians*/
52
+ declare function ellipse_arc(center_x: number, center_y: number, radius_x: number, radius_y: number, start_angle: number, end_angle: number): SVGAttributes<SVGPathElement>;
53
+
54
+ /**This draws a triangle*/
55
+ declare function group(): SVGAttributes<SVGGElement>;
56
+
57
+ /**This creates a line element
58
+ * @param start_x start point on x axis
59
+ * @param start_y start point on y axis
60
+ * @param end_x end point on x axis
61
+ * @param end_y end point on y axis*/
62
+ declare function line(start_x: number, start_y: number, end_x: number, end_y: number): SVGAttributes<SVGLineElement>;
63
+
64
+ /**This creates a path element*/
65
+ declare function path(path: string): SVGAttributes<SVGPathElement>;
66
+
67
+ /**This creates a rectangle with teh center as origin
68
+ * @param center_x x coordinate of center
69
+ * @param center_y y coordinate of center
70
+ * @param width width
71
+ * @param height height
72
+ * @param corner_radius radius of corner*/
73
+ declare function rectangle_from_center(center_x: number, center_y: number, width: number, height: number, corner_radius: number): SVGAttributes<SVGRectElement>;
74
+ /**This creates a rectangle with teh center as origin
75
+ * @param start_x x coordinate of center
76
+ * @param start_y y coordinate of center
77
+ * @param width width
78
+ * @param height height
79
+ * @param corner_radius radius of corner*/
80
+ declare function rectangle_from_corner(start_x: number, start_y: number, width: number, height: number, corner_radius: number): SVGAttributes<SVGRectElement>;
81
+
82
+ type SVGElements = {
83
+ ellipse: SVGEllipseElement;
84
+ circle: SVGCircleElement;
85
+ path: SVGPathElement;
86
+ line: SVGLineElement;
87
+ rect: SVGRectElement;
88
+ text: SVGTextElement;
89
+ g: SVGGElement;
90
+ svg: SVGSVGElement;
91
+ foreignObject: SVGForeignObjectElement;
92
+ };
93
+ declare function create_svg_element<K extends keyof SVGElements>(name: K): SVGAttributes<SVGElements[K]>;
94
+
95
+ /** This returns an empty svg element
96
+ * @param width width of svg
97
+ * @param height height of svg
98
+ * @param viewbox viewbox of svg*/
99
+ declare function svg$1(width: number, height: number, viewbox?: string): SVGAttributes<SVGSVGElement>;
100
+
101
+ declare const SVGAnchorPoint: {
102
+ readonly bottomLeft: 0;
103
+ readonly middleLeft: 1;
104
+ readonly topLeft: 2;
105
+ readonly topCenter: 3;
106
+ readonly topRight: 4;
107
+ readonly middleRight: 5;
108
+ readonly bottomRight: 6;
109
+ readonly bottomCenter: 7;
110
+ readonly middleCenter: 8;
111
+ };
112
+ type SVGAnchorPoint = (typeof SVGAnchorPoint)[keyof typeof SVGAnchorPoint];
113
+
114
+ /**Creates a text nodes for an svg
115
+ * @param x x coordinate of text
116
+ * @param y y coordinate of text
117
+ * @param text text
118
+ * @param size size of text in px
119
+ * @param anchor anchor point of text*/
120
+ declare function text(x: number, y: number, text: string, size: number, anchor: SVGAnchorPoint): SVGAttributes<SVGTextElement>;
121
+ /**Creates a text nodes for an svg
122
+ * @param x x coordinate of text
123
+ * @param y y coordinate of text
124
+ * @param width width of text
125
+ * @param height height of text
126
+ * @param text text
127
+ * @param size size of text in px
128
+ * @param anchor anchor point of */
129
+ declare function multi_line_text(x: number, y: number, width: number, height: number, text: string, size: number, anchor: SVGAnchorPoint): SVGAttributes<SVGForeignObjectElement>;
130
+
131
+ /**This draws a triangle
132
+ * @param center_x x coordinate of center
133
+ * @param center_y y coordinate of center
134
+ * @param width width
135
+ * @param height height*/
136
+ declare function isosceles_triangle(center_x: number, center_y: number, width: number, height: number): SVGAttributes<SVGPathElement>;
137
+
138
+ declare const svg: {
139
+ create: typeof create_svg_element;
140
+ circle: typeof circle;
141
+ circle_arc: typeof circle_arc;
142
+ ellipse: typeof ellipse;
143
+ ellipse_arc: typeof ellipse_arc;
144
+ group: typeof group;
145
+ line: typeof line;
146
+ path: typeof path;
147
+ rectangle_from_center: typeof rectangle_from_center;
148
+ rectangle_from_corner: typeof rectangle_from_corner;
149
+ svg: typeof svg$1;
150
+ text: typeof text;
151
+ multi_line_text: typeof multi_line_text;
152
+ isosceles_triangle: typeof isosceles_triangle;
153
+ angle_to_anchor_point: (angle: number) => 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;
154
+ };
155
+ type SVGFunc = () => SVGSVGElement;
156
+
157
+ export { SVGAnchorPoint, type SVGFunc, svg };
package/dist/index.js ADDED
@@ -0,0 +1,312 @@
1
+ // src/primitives/ellipse.ts
2
+ import { degrees_to_radians } from "@chocbite/ts-lib-math";
3
+
4
+ // src/attributes.ts
5
+ var SVGAttributes = class {
6
+ elem;
7
+ constructor(elem) {
8
+ this.elem = elem;
9
+ }
10
+ /** Sets the stroke color of the SVG element */
11
+ stroke(stroke) {
12
+ this.elem.setAttribute("stroke", stroke);
13
+ return this;
14
+ }
15
+ /** Sets the stroke color of the SVG element */
16
+ s(stroke) {
17
+ this.elem.setAttribute("stroke", stroke);
18
+ return this;
19
+ }
20
+ /** Sets the fill color of the SVG element */
21
+ fill(fill) {
22
+ this.elem.setAttribute("fill", fill);
23
+ return this;
24
+ }
25
+ /** Sets the fill color of the SVG element */
26
+ f(fill) {
27
+ this.elem.setAttribute("fill", fill);
28
+ return this;
29
+ }
30
+ /** Sets the stroke width of the SVG element */
31
+ stroke_width(width) {
32
+ this.elem.setAttribute("stroke-width", String(width));
33
+ return this;
34
+ }
35
+ /** Sets the stroke width of the SVG element */
36
+ sw(width) {
37
+ this.elem.setAttribute("stroke-width", String(width));
38
+ return this;
39
+ }
40
+ /** Adds one or more class names to the SVG element */
41
+ class_list(...class_name) {
42
+ this.elem.classList.add(...class_name);
43
+ return this;
44
+ }
45
+ /** Adds one or more class names to the SVG element */
46
+ cl(...class_name) {
47
+ this.elem.classList.add(...class_name);
48
+ return this;
49
+ }
50
+ /** Sets an arbitrary attribute on the SVG element */
51
+ attribute(name, value) {
52
+ this.elem.setAttribute(name, value);
53
+ return this;
54
+ }
55
+ /** Sets an arbitrary attribute on the SVG element */
56
+ a(name, value) {
57
+ this.elem.setAttribute(name, value);
58
+ return this;
59
+ }
60
+ };
61
+
62
+ // src/shared.ts
63
+ var NAME_SPACE = "http://www.w3.org/2000/svg";
64
+
65
+ // src/primitives/shared.ts
66
+ function create_svg_element(name) {
67
+ return new SVGAttributes(
68
+ document.createElementNS(NAME_SPACE, name)
69
+ );
70
+ }
71
+
72
+ // src/primitives/ellipse.ts
73
+ function ellipse(center_x, center_y, radius_x, radius_y) {
74
+ return create_svg_element("ellipse").a("cx", String(center_x)).a("cy", String(center_y)).a("rx", String(radius_x)).a("ry", String(radius_y));
75
+ }
76
+ function ellipse_arc(center_x, center_y, radius_x, radius_y, start_angle, end_angle) {
77
+ const start_radian = degrees_to_radians(start_angle);
78
+ end_angle = degrees_to_radians(end_angle - start_angle);
79
+ const s_x = radius_x * Math.cos(start_radian) + center_x;
80
+ const s_y = radius_y * Math.sin(start_radian) + center_y;
81
+ const e_x = radius_x * Math.cos(start_radian + end_angle) + center_x;
82
+ const e_y = radius_y * Math.sin(start_radian + end_angle) + center_y;
83
+ const f_a = end_angle > Math.PI ? 1 : 0;
84
+ const f_s = end_angle > 0 ? 1 : 0;
85
+ return create_svg_element("path").a(
86
+ "d",
87
+ `M ${s_x} ${s_y} A ${radius_x} ${radius_y} 0 ${f_a} ${f_s} ${e_x} ${e_y}`
88
+ );
89
+ }
90
+
91
+ // src/primitives/circle.ts
92
+ function circle(center_x, center_y, radius) {
93
+ const circle2 = create_svg_element("circle");
94
+ circle2.a("cx", String(center_x));
95
+ circle2.a("cy", String(center_y));
96
+ circle2.a("r", String(radius));
97
+ return circle2;
98
+ }
99
+ function circle_arc(center_x, center_y, radius, start_angle, end_angle) {
100
+ return ellipse_arc(
101
+ center_x,
102
+ center_y,
103
+ radius,
104
+ radius,
105
+ start_angle,
106
+ end_angle
107
+ );
108
+ }
109
+
110
+ // src/primitives/group.ts
111
+ function group() {
112
+ return create_svg_element("g");
113
+ }
114
+
115
+ // src/primitives/line.ts
116
+ function line(start_x, start_y, end_x, end_y) {
117
+ return create_svg_element("line").a("x1", String(start_x)).a("y1", String(start_y)).a("x2", String(end_x)).a("y2", String(end_y));
118
+ }
119
+
120
+ // src/primitives/path.ts
121
+ function path(path2) {
122
+ return create_svg_element("path").a("d", path2);
123
+ }
124
+
125
+ // src/primitives/rectangle.ts
126
+ function rectangle_from_center(center_x, center_y, width, height, corner_radius) {
127
+ return create_svg_element("rect").a("x", String(center_x - width / 2)).a("y", String(center_y - height / 2)).a("width", String(width)).a("height", String(height)).a("rx", String(corner_radius));
128
+ }
129
+ function rectangle_from_corner(start_x, start_y, width, height, corner_radius) {
130
+ return create_svg_element("rect").a("x", String(start_x)).a("y", String(start_y)).a("width", String(width)).a("height", String(height)).a("rx", String(corner_radius));
131
+ }
132
+
133
+ // src/primitives/svg.ts
134
+ function svg(width, height, viewbox = `0 0 ${width} ${height}`) {
135
+ return create_svg_element("svg").a("width", String(width)).a("height", String(height)).a("viewBox", String(viewbox));
136
+ }
137
+
138
+ // src/util/anchorPoint.ts
139
+ var SVGAnchorPoint = {
140
+ bottomLeft: 0,
141
+ middleLeft: 1,
142
+ topLeft: 2,
143
+ topCenter: 3,
144
+ topRight: 4,
145
+ middleRight: 5,
146
+ bottomRight: 6,
147
+ bottomCenter: 7,
148
+ middleCenter: 8
149
+ };
150
+
151
+ // src/primitives/text.ts
152
+ function text(x, y, text2, size, anchor) {
153
+ const text_elem = create_svg_element("text").a("x", String(x)).a("y", String(y)).a("font-size", String(size));
154
+ text_elem.elem.innerHTML = text2;
155
+ switch (anchor) {
156
+ case SVGAnchorPoint.bottomLeft:
157
+ case SVGAnchorPoint.middleLeft:
158
+ case SVGAnchorPoint.topLeft: {
159
+ text_elem.a("text-anchor", "start");
160
+ break;
161
+ }
162
+ case SVGAnchorPoint.topCenter:
163
+ case SVGAnchorPoint.bottomCenter:
164
+ case SVGAnchorPoint.middleCenter: {
165
+ text_elem.a("text-anchor", "middle");
166
+ break;
167
+ }
168
+ case SVGAnchorPoint.topRight:
169
+ case SVGAnchorPoint.middleRight:
170
+ case SVGAnchorPoint.bottomRight: {
171
+ text_elem.a("text-anchor", "end");
172
+ break;
173
+ }
174
+ }
175
+ switch (anchor) {
176
+ case SVGAnchorPoint.bottomLeft:
177
+ case SVGAnchorPoint.bottomRight:
178
+ case SVGAnchorPoint.bottomCenter: {
179
+ text_elem.a("dominant-baseline", "auto");
180
+ break;
181
+ }
182
+ case SVGAnchorPoint.middleLeft:
183
+ case SVGAnchorPoint.middleRight:
184
+ case SVGAnchorPoint.middleCenter: {
185
+ text_elem.a("dominant-baseline", "central");
186
+ break;
187
+ }
188
+ case SVGAnchorPoint.topLeft:
189
+ case SVGAnchorPoint.topCenter:
190
+ case SVGAnchorPoint.topRight: {
191
+ text_elem.a("dominant-baseline", "hanging");
192
+ break;
193
+ }
194
+ }
195
+ return text_elem;
196
+ }
197
+ function multi_line_text(x, y, width, height, text2, size, anchor) {
198
+ const text_element = create_svg_element("foreignObject");
199
+ const text_div = text_element.elem.appendChild(document.createElement("div"));
200
+ text_element.a("width", String(width));
201
+ text_element.a("height", String(height));
202
+ text_element.a("x", String(x));
203
+ text_element.a("y", String(y));
204
+ text_div.style.fontSize = size + "px";
205
+ text_div.style.width = "100%";
206
+ text_div.style.height = "100%";
207
+ text_div.style.display = "flex";
208
+ text_div.innerHTML = text2;
209
+ switch (anchor) {
210
+ case SVGAnchorPoint.bottomLeft:
211
+ case SVGAnchorPoint.middleLeft:
212
+ case SVGAnchorPoint.topLeft: {
213
+ text_div.style.textAlign = "start";
214
+ text_div.style.justifyContent = "flex-start";
215
+ break;
216
+ }
217
+ case SVGAnchorPoint.topCenter:
218
+ case SVGAnchorPoint.bottomCenter:
219
+ case SVGAnchorPoint.middleCenter: {
220
+ text_div.style.textAlign = "center";
221
+ text_div.style.justifyContent = "center";
222
+ break;
223
+ }
224
+ case SVGAnchorPoint.topRight:
225
+ case SVGAnchorPoint.middleRight:
226
+ case SVGAnchorPoint.bottomRight: {
227
+ text_div.style.textAlign = "end";
228
+ text_div.style.justifyContent = "flex-end";
229
+ break;
230
+ }
231
+ }
232
+ switch (anchor) {
233
+ case SVGAnchorPoint.bottomLeft:
234
+ case SVGAnchorPoint.bottomRight:
235
+ case SVGAnchorPoint.bottomCenter: {
236
+ text_div.style.alignItems = "flex-end";
237
+ break;
238
+ }
239
+ case SVGAnchorPoint.middleLeft:
240
+ case SVGAnchorPoint.middleRight:
241
+ case SVGAnchorPoint.middleCenter: {
242
+ text_div.style.alignItems = "center";
243
+ break;
244
+ }
245
+ case SVGAnchorPoint.topLeft:
246
+ case SVGAnchorPoint.topCenter:
247
+ case SVGAnchorPoint.topRight: {
248
+ text_div.style.alignItems = "flex-start";
249
+ break;
250
+ }
251
+ }
252
+ return text_element;
253
+ }
254
+
255
+ // src/primitives/triangle.ts
256
+ function isosceles_triangle(center_x, center_y, width, height) {
257
+ const half_w = width / 2;
258
+ const half_h = height / 2;
259
+ return create_svg_element("path").a(
260
+ "d",
261
+ "M" + (center_x - half_w) + "," + (center_y + half_h) + " " + (center_x + half_w) + "," + (center_y + half_h) + " " + center_x + "," + (center_y - half_h) + "Z"
262
+ );
263
+ }
264
+
265
+ // src/util/angleToAnchorPoint.ts
266
+ var angle_to_anchor_point = (angle) => {
267
+ const sec = angle >= 0 ? angle % 6.283185307179586 : -(angle % 6.283185307179586);
268
+ if (sec > 5.93411945678072) {
269
+ return SVGAnchorPoint.middleRight;
270
+ } else if (sec > 4.974188368183839) {
271
+ return SVGAnchorPoint.topRight;
272
+ } else if (sec > 4.45058959258554) {
273
+ return SVGAnchorPoint.topCenter;
274
+ } else if (sec > 3.490658503988659) {
275
+ return SVGAnchorPoint.topLeft;
276
+ } else if (sec > 2.792526803190927) {
277
+ return SVGAnchorPoint.middleLeft;
278
+ } else if (sec > 1.832595714594046) {
279
+ return SVGAnchorPoint.bottomLeft;
280
+ } else if (sec > 1.308996938995747) {
281
+ return SVGAnchorPoint.bottomCenter;
282
+ } else if (sec > 0.3490658503988659) {
283
+ return SVGAnchorPoint.bottomRight;
284
+ } else {
285
+ return SVGAnchorPoint.middleRight;
286
+ }
287
+ };
288
+
289
+ // src/index.ts
290
+ var svg2 = {
291
+ create: create_svg_element,
292
+ //Primitives
293
+ circle,
294
+ circle_arc,
295
+ ellipse,
296
+ ellipse_arc,
297
+ group,
298
+ line,
299
+ path,
300
+ rectangle_from_center,
301
+ rectangle_from_corner,
302
+ svg,
303
+ text,
304
+ multi_line_text,
305
+ isosceles_triangle,
306
+ //Utilities
307
+ angle_to_anchor_point
308
+ };
309
+ export {
310
+ SVGAnchorPoint,
311
+ svg2 as svg
312
+ };
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@chocbite/ts-lib-svg",
3
+ "version": "1.0.1",
4
+ "description": "Library to help with svg generation in typescript",
5
+ "author": "chocolateandmilkwin",
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "private": false,
9
+ "module": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "publishConfig": {
12
+ "access": "public"
13
+ },
14
+ "exports": {
15
+ ".": {
16
+ "import": "./dist/index.js",
17
+ "types": "./dist/index.d.ts"
18
+ }
19
+ },
20
+ "files": [
21
+ "dist"
22
+ ],
23
+ "scripts": {
24
+ "dev": "vite --port 9952",
25
+ "build": "tsup src/index.ts --format esm --dts",
26
+ "lint": "eslint src/**/*.ts",
27
+ "test": "vitest run",
28
+ "prepublishOnly": "npm run build"
29
+ },
30
+ "dependencies": {
31
+ "@chocbite/ts-lib-math": "1.0.0"
32
+ },
33
+ "devDependencies": {
34
+ "typescript": "^5.0.0",
35
+ "tsup": "^8.0.0",
36
+ "vite": "^7.0.0",
37
+ "vitest": "^4.0.0",
38
+ "eslint": "^9.0.0",
39
+ "typescript-eslint": "^8.0.0",
40
+ "@vitest/browser-playwright": "^4.0.0"
41
+ }
42
+ }