abstract-image 3.1.3 → 3.2.3

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.
Files changed (188) hide show
  1. package/CHANGELOG.md +27 -21
  2. package/LICENSE +21 -21
  3. package/README.md +73 -71
  4. package/lib/__stories__/react-svg-export/example-1.stories.d.ts.map +1 -1
  5. package/lib/__stories__/react-svg-export/example-1.stories.js +1 -1
  6. package/lib/__stories__/react-svg-export/example-1.stories.js.map +1 -1
  7. package/lib/exporters/__tests__/dxf2d-export-image/test-defs/dxf2d-ellipse.js +379 -379
  8. package/lib/exporters/__tests__/dxf2d-export-image/test-defs/dxf2d-group.d.ts.map +1 -1
  9. package/lib/exporters/__tests__/dxf2d-export-image/test-defs/dxf2d-group.js +124 -124
  10. package/lib/exporters/__tests__/dxf2d-export-image/test-defs/dxf2d-group.js.map +1 -1
  11. package/lib/exporters/__tests__/dxf2d-export-image/test-defs/dxf2d-line.js +55 -55
  12. package/lib/exporters/__tests__/dxf2d-export-image/test-defs/dxf2d-polygon.js +89 -89
  13. package/lib/exporters/__tests__/dxf2d-export-image/test-defs/dxf2d-polyline.js +79 -79
  14. package/lib/exporters/__tests__/dxf2d-export-image/test-defs/dxf2d-rectangle.js +99 -99
  15. package/lib/exporters/__tests__/dxf2d-export-image/test-defs/dxf2d-text-growth-directions.d.ts.map +1 -1
  16. package/lib/exporters/__tests__/dxf2d-export-image/test-defs/dxf2d-text-growth-directions.js +139 -139
  17. package/lib/exporters/__tests__/dxf2d-export-image/test-defs/dxf2d-text-growth-directions.js.map +1 -1
  18. package/lib/exporters/__tests__/dxf2d-export-image/test-defs/dxf2d-text.d.ts.map +1 -1
  19. package/lib/exporters/__tests__/dxf2d-export-image/test-defs/dxf2d-text.js +64 -64
  20. package/lib/exporters/__tests__/dxf2d-export-image/test-defs/dxf2d-text.js.map +1 -1
  21. package/lib/exporters/__tests__/eps-export-image/test-defs/eps-ellipse.js +24 -24
  22. package/lib/exporters/__tests__/eps-export-image/test-defs/eps-empty-text.d.ts.map +1 -1
  23. package/lib/exporters/__tests__/eps-export-image/test-defs/eps-empty-text.js +27 -27
  24. package/lib/exporters/__tests__/eps-export-image/test-defs/eps-empty-text.js.map +1 -1
  25. package/lib/exporters/__tests__/eps-export-image/test-defs/eps-group.d.ts.map +1 -1
  26. package/lib/exporters/__tests__/eps-export-image/test-defs/eps-group.js +32 -32
  27. package/lib/exporters/__tests__/eps-export-image/test-defs/eps-group.js.map +1 -1
  28. package/lib/exporters/__tests__/eps-export-image/test-defs/eps-line.js +20 -20
  29. package/lib/exporters/__tests__/eps-export-image/test-defs/eps-polygon.js +34 -34
  30. package/lib/exporters/__tests__/eps-export-image/test-defs/eps-polyline.js +26 -26
  31. package/lib/exporters/__tests__/eps-export-image/test-defs/eps-rectangle.js +20 -20
  32. package/lib/exporters/__tests__/eps-export-image/test-defs/eps-text-growth-directions.d.ts.map +1 -1
  33. package/lib/exporters/__tests__/eps-export-image/test-defs/eps-text-growth-directions.js +63 -63
  34. package/lib/exporters/__tests__/eps-export-image/test-defs/eps-text-growth-directions.js.map +1 -1
  35. package/lib/exporters/__tests__/eps-export-image/test-defs/eps-text.d.ts.map +1 -1
  36. package/lib/exporters/__tests__/eps-export-image/test-defs/eps-text.js +27 -27
  37. package/lib/exporters/__tests__/eps-export-image/test-defs/eps-text.js.map +1 -1
  38. package/lib/exporters/__tests__/exception/react-svg-direction-exception.test.js +2 -2
  39. package/lib/exporters/__tests__/exception/react-svg-direction-exception.test.js.map +1 -1
  40. package/lib/exporters/__tests__/exception/svg-direction-exception.test.js +2 -2
  41. package/lib/exporters/__tests__/exception/svg-direction-exception.test.js.map +1 -1
  42. package/lib/exporters/__tests__/react-svg-export-image/test-defs/react-svg-binary.js +1 -1
  43. package/lib/exporters/__tests__/react-svg-export-image/test-defs/react-svg-binary.js.map +1 -1
  44. package/lib/exporters/__tests__/react-svg-export-image/test-defs/react-svg-callback.d.ts.map +1 -1
  45. package/lib/exporters/__tests__/react-svg-export-image/test-defs/react-svg-callback.js +1 -1
  46. package/lib/exporters/__tests__/react-svg-export-image/test-defs/react-svg-callback.js.map +1 -1
  47. package/lib/exporters/__tests__/react-svg-export-image/test-defs/react-svg-empty-text.d.ts.map +1 -1
  48. package/lib/exporters/__tests__/react-svg-export-image/test-defs/react-svg-empty-text.js +1 -1
  49. package/lib/exporters/__tests__/react-svg-export-image/test-defs/react-svg-empty-text.js.map +1 -1
  50. package/lib/exporters/__tests__/react-svg-export-image/test-defs/react-svg-group.d.ts.map +1 -1
  51. package/lib/exporters/__tests__/react-svg-export-image/test-defs/react-svg-group.js +1 -1
  52. package/lib/exporters/__tests__/react-svg-export-image/test-defs/react-svg-group.js.map +1 -1
  53. package/lib/exporters/__tests__/react-svg-export-image/test-defs/react-svg-subimage.d.ts.map +1 -1
  54. package/lib/exporters/__tests__/react-svg-export-image/test-defs/react-svg-subimage.js +1 -1
  55. package/lib/exporters/__tests__/react-svg-export-image/test-defs/react-svg-subimage.js.map +1 -1
  56. package/lib/exporters/__tests__/react-svg-export-image/test-defs/react-svg-text-bold.d.ts +3 -0
  57. package/lib/exporters/__tests__/react-svg-export-image/test-defs/react-svg-text-bold.d.ts.map +1 -0
  58. package/lib/exporters/__tests__/react-svg-export-image/test-defs/react-svg-text-bold.js +35 -0
  59. package/lib/exporters/__tests__/react-svg-export-image/test-defs/react-svg-text-bold.js.map +1 -0
  60. package/lib/exporters/__tests__/react-svg-export-image/test-defs/react-svg-text-growth-directions.d.ts.map +1 -1
  61. package/lib/exporters/__tests__/react-svg-export-image/test-defs/react-svg-text-growth-directions.js +4 -4
  62. package/lib/exporters/__tests__/react-svg-export-image/test-defs/react-svg-text-growth-directions.js.map +1 -1
  63. package/lib/exporters/__tests__/react-svg-export-image/test-defs/react-svg-text-italic.d.ts +3 -0
  64. package/lib/exporters/__tests__/react-svg-export-image/test-defs/react-svg-text-italic.d.ts.map +1 -0
  65. package/lib/exporters/__tests__/react-svg-export-image/test-defs/react-svg-text-italic.js +36 -0
  66. package/lib/exporters/__tests__/react-svg-export-image/test-defs/react-svg-text-italic.js.map +1 -0
  67. package/lib/exporters/__tests__/react-svg-export-image/test-defs/react-svg-text-sub.d.ts.map +1 -1
  68. package/lib/exporters/__tests__/react-svg-export-image/test-defs/react-svg-text-sub.js +1 -1
  69. package/lib/exporters/__tests__/react-svg-export-image/test-defs/react-svg-text-sub.js.map +1 -1
  70. package/lib/exporters/__tests__/react-svg-export-image/test-defs/react-svg-text.d.ts.map +1 -1
  71. package/lib/exporters/__tests__/react-svg-export-image/test-defs/react-svg-text.js +2 -2
  72. package/lib/exporters/__tests__/react-svg-export-image/test-defs/react-svg-text.js.map +1 -1
  73. package/lib/exporters/__tests__/svg-export-image/test-defs/svg-binary.js +2 -1
  74. package/lib/exporters/__tests__/svg-export-image/test-defs/svg-binary.js.map +1 -1
  75. package/lib/exporters/__tests__/svg-export-image/test-defs/svg-empty-text.d.ts.map +1 -1
  76. package/lib/exporters/__tests__/svg-export-image/test-defs/svg-empty-text.js +1 -1
  77. package/lib/exporters/__tests__/svg-export-image/test-defs/svg-empty-text.js.map +1 -1
  78. package/lib/exporters/__tests__/svg-export-image/test-defs/svg-group.d.ts.map +1 -1
  79. package/lib/exporters/__tests__/svg-export-image/test-defs/svg-group.js +1 -1
  80. package/lib/exporters/__tests__/svg-export-image/test-defs/svg-group.js.map +1 -1
  81. package/lib/exporters/__tests__/svg-export-image/test-defs/svg-text-bold.d.ts +3 -0
  82. package/lib/exporters/__tests__/svg-export-image/test-defs/svg-text-bold.d.ts.map +1 -0
  83. package/lib/exporters/__tests__/svg-export-image/test-defs/svg-text-bold.js +35 -0
  84. package/lib/exporters/__tests__/svg-export-image/test-defs/svg-text-bold.js.map +1 -0
  85. package/lib/exporters/__tests__/svg-export-image/test-defs/svg-text-growth-directions.d.ts.map +1 -1
  86. package/lib/exporters/__tests__/svg-export-image/test-defs/svg-text-growth-directions.js +4 -4
  87. package/lib/exporters/__tests__/svg-export-image/test-defs/svg-text-growth-directions.js.map +1 -1
  88. package/lib/exporters/__tests__/svg-export-image/test-defs/svg-text-italic.d.ts +3 -0
  89. package/lib/exporters/__tests__/svg-export-image/test-defs/svg-text-italic.d.ts.map +1 -0
  90. package/lib/exporters/__tests__/svg-export-image/test-defs/svg-text-italic.js +36 -0
  91. package/lib/exporters/__tests__/svg-export-image/test-defs/svg-text-italic.js.map +1 -0
  92. package/lib/exporters/__tests__/svg-export-image/test-defs/svg-text.d.ts.map +1 -1
  93. package/lib/exporters/__tests__/svg-export-image/test-defs/svg-text.js +2 -2
  94. package/lib/exporters/__tests__/svg-export-image/test-defs/svg-text.js.map +1 -1
  95. package/lib/exporters/react-svg-export-image.js +4 -5
  96. package/lib/exporters/react-svg-export-image.js.map +1 -1
  97. package/lib/exporters/svg-export-image.d.ts.map +1 -1
  98. package/lib/exporters/svg-export-image.js +30 -35
  99. package/lib/exporters/svg-export-image.js.map +1 -1
  100. package/lib/model/component.d.ts +3 -2
  101. package/lib/model/component.d.ts.map +1 -1
  102. package/lib/model/component.js +12 -11
  103. package/lib/model/component.js.map +1 -1
  104. package/package.json +2 -2
  105. package/src/__stories__/react-svg-export/example-1.stories.tsx +54 -53
  106. package/src/__stories__/svg-export/example-1.stories.tsx +42 -42
  107. package/src/exporters/__tests__/dxf2d-export-image/export-test-def.ts +11 -11
  108. package/src/exporters/__tests__/dxf2d-export-image/export.test.tsx +13 -13
  109. package/src/exporters/__tests__/dxf2d-export-image/test-defs/dxf2d-ellipse.ts +405 -405
  110. package/src/exporters/__tests__/dxf2d-export-image/test-defs/dxf2d-group.ts +166 -165
  111. package/src/exporters/__tests__/dxf2d-export-image/test-defs/dxf2d-line.ts +80 -80
  112. package/src/exporters/__tests__/dxf2d-export-image/test-defs/dxf2d-polygon.ts +114 -114
  113. package/src/exporters/__tests__/dxf2d-export-image/test-defs/dxf2d-polyline.ts +103 -103
  114. package/src/exporters/__tests__/dxf2d-export-image/test-defs/dxf2d-rectangle.ts +125 -125
  115. package/src/exporters/__tests__/dxf2d-export-image/test-defs/dxf2d-text-growth-directions.ts +214 -210
  116. package/src/exporters/__tests__/dxf2d-export-image/test-defs/dxf2d-text.ts +97 -96
  117. package/src/exporters/__tests__/eps-export-image/export-test-def.ts +11 -11
  118. package/src/exporters/__tests__/eps-export-image/export.test.tsx +13 -13
  119. package/src/exporters/__tests__/eps-export-image/test-defs/eps-ellipse.ts +50 -50
  120. package/src/exporters/__tests__/eps-export-image/test-defs/eps-empty-text.ts +60 -59
  121. package/src/exporters/__tests__/eps-export-image/test-defs/eps-group.ts +74 -73
  122. package/src/exporters/__tests__/eps-export-image/test-defs/eps-line.ts +45 -45
  123. package/src/exporters/__tests__/eps-export-image/test-defs/eps-polygon.ts +65 -65
  124. package/src/exporters/__tests__/eps-export-image/test-defs/eps-polyline.ts +58 -58
  125. package/src/exporters/__tests__/eps-export-image/test-defs/eps-rectangle.ts +46 -46
  126. package/src/exporters/__tests__/eps-export-image/test-defs/eps-text-growth-directions.ts +138 -134
  127. package/src/exporters/__tests__/eps-export-image/test-defs/eps-text.ts +60 -59
  128. package/src/exporters/__tests__/exception/png-unsupported.test.tsx +25 -25
  129. package/src/exporters/__tests__/exception/react-svg-direction-exception.test.tsx +65 -63
  130. package/src/exporters/__tests__/exception/svg-direction-exception.test.tsx +65 -63
  131. package/src/exporters/__tests__/png-export-image/export-test-def.ts +11 -11
  132. package/src/exporters/__tests__/png-export-image/export.test.tsx +13 -13
  133. package/src/exporters/__tests__/png-export-image/test-defs/png-createPNG.tsx +26 -26
  134. package/src/exporters/__tests__/react-svg-export-image/export-test-def.tsx +13 -13
  135. package/src/exporters/__tests__/react-svg-export-image/export.test.tsx +13 -13
  136. package/src/exporters/__tests__/react-svg-export-image/test-defs/react-svg-binary-png.tsx +27 -27
  137. package/src/exporters/__tests__/react-svg-export-image/test-defs/react-svg-binary.tsx +26 -26
  138. package/src/exporters/__tests__/react-svg-export-image/test-defs/react-svg-callback.tsx +60 -59
  139. package/src/exporters/__tests__/react-svg-export-image/test-defs/react-svg-ellipse.tsx +28 -28
  140. package/src/exporters/__tests__/react-svg-export-image/test-defs/react-svg-empty-text.tsx +35 -34
  141. package/src/exporters/__tests__/react-svg-export-image/test-defs/react-svg-group.tsx +44 -43
  142. package/src/exporters/__tests__/react-svg-export-image/test-defs/react-svg-line.tsx +26 -26
  143. package/src/exporters/__tests__/react-svg-export-image/test-defs/react-svg-polygon.tsx +32 -32
  144. package/src/exporters/__tests__/react-svg-export-image/test-defs/react-svg-polyline.tsx +33 -33
  145. package/src/exporters/__tests__/react-svg-export-image/test-defs/react-svg-rectangle.tsx +27 -27
  146. package/src/exporters/__tests__/react-svg-export-image/test-defs/react-svg-subimage.tsx +36 -35
  147. package/src/exporters/__tests__/react-svg-export-image/test-defs/react-svg-text-bold.tsx +50 -0
  148. package/src/exporters/__tests__/react-svg-export-image/test-defs/react-svg-text-growth-directions.tsx +80 -76
  149. package/src/exporters/__tests__/react-svg-export-image/test-defs/react-svg-text-italic.tsx +65 -0
  150. package/src/exporters/__tests__/react-svg-export-image/test-defs/react-svg-text-sub.tsx +35 -34
  151. package/src/exporters/__tests__/react-svg-export-image/test-defs/react-svg-text.tsx +35 -34
  152. package/src/exporters/__tests__/svg-export-image/export-test-def.ts +11 -11
  153. package/src/exporters/__tests__/svg-export-image/export.test.tsx +13 -13
  154. package/src/exporters/__tests__/svg-export-image/test-defs/svg-binary.tsx +26 -26
  155. package/src/exporters/__tests__/svg-export-image/test-defs/svg-ellipse.ts +27 -27
  156. package/src/exporters/__tests__/svg-export-image/test-defs/svg-empty-text.ts +34 -33
  157. package/src/exporters/__tests__/svg-export-image/test-defs/svg-group.ts +44 -43
  158. package/src/exporters/__tests__/svg-export-image/test-defs/svg-line.ts +26 -26
  159. package/src/exporters/__tests__/svg-export-image/test-defs/svg-polygon.ts +32 -32
  160. package/src/exporters/__tests__/svg-export-image/test-defs/svg-polyline.ts +33 -33
  161. package/src/exporters/__tests__/svg-export-image/test-defs/svg-rectangle.ts +27 -27
  162. package/src/exporters/__tests__/svg-export-image/test-defs/svg-text-bold.ts +50 -0
  163. package/src/exporters/__tests__/svg-export-image/test-defs/svg-text-growth-directions.ts +80 -76
  164. package/src/exporters/__tests__/svg-export-image/test-defs/svg-text-italic.ts +65 -0
  165. package/src/exporters/__tests__/svg-export-image/test-defs/svg-text.ts +35 -34
  166. package/src/exporters/dxf2d-export-image.ts +218 -218
  167. package/src/exporters/eps-export-image.ts +154 -154
  168. package/src/exporters/index.ts +3 -3
  169. package/src/exporters/png-export-image.ts +12 -12
  170. package/src/exporters/react-svg-export-image.tsx +301 -298
  171. package/src/exporters/svg-export-image.ts +296 -334
  172. package/src/index.ts +11 -11
  173. package/src/model/__tests__/color/export-test-def.ts +13 -13
  174. package/src/model/__tests__/color/export.test.tsx +14 -14
  175. package/src/model/__tests__/color/test-defs/color-from-string.ts +46 -46
  176. package/src/model/__tests__/color/test-defs/color-to-string.ts +35 -35
  177. package/src/model/__tests__/color/test-defs/color-undefined-2.ts +8 -8
  178. package/src/model/__tests__/color/test-defs/color-undefined.ts +8 -8
  179. package/src/model/abstract-image.ts +25 -25
  180. package/src/model/color.ts +52 -52
  181. package/src/model/component.ts +266 -279
  182. package/src/model/index.ts +5 -5
  183. package/src/model/point.ts +11 -11
  184. package/src/model/size.ts +11 -11
  185. package/lib/exporters/__tests__/svg-export-image.test.d.ts +0 -2
  186. package/lib/exporters/__tests__/svg-export-image.test.d.ts.map +0 -1
  187. package/lib/exporters/__tests__/svg-export-image.test.js +0 -35
  188. package/lib/exporters/__tests__/svg-export-image.test.js.map +0 -1
@@ -1,334 +1,296 @@
1
- import * as AbstractImage from "../model/index";
2
-
3
- export function createSVG(
4
- image: AbstractImage.AbstractImage,
5
- pixelWidth?: number,
6
- pixelHeight?: number
7
- ): string {
8
- const imageElements = image.components.map((c: AbstractImage.Component) =>
9
- abstractComponentToSVG(c)
10
- );
11
-
12
- return createElement(
13
- "svg",
14
- {
15
- xmlns: "http://www.w3.org/2000/svg",
16
- width: `${pixelWidth || image.size.width}px`,
17
- height: `${pixelHeight || image.size.height}px`,
18
- viewBox: [0, 0, image.size.width, image.size.height].join(" ")
19
- },
20
- imageElements
21
- );
22
- }
23
-
24
- function abstractComponentToSVG(component: AbstractImage.Component): string {
25
- switch (component.type) {
26
- case "group":
27
- return createElement(
28
- "g",
29
- {
30
- name: component.name
31
- },
32
- component.children.map(c => abstractComponentToSVG(c))
33
- );
34
- case "binaryimage":
35
- switch (component.format) {
36
- case "svg":
37
- return createElement("g", {}, [
38
- component.data.reduce((a, b) => a + String.fromCharCode(b), "")
39
- ]);
40
- default:
41
- return "";
42
- }
43
- case "subimage":
44
- return "";
45
- case "line":
46
- return createElement(
47
- "line",
48
- {
49
- x1: component.start.x.toString(),
50
- y1: component.start.y.toString(),
51
- x2: component.end.x.toString(),
52
- y2: component.end.y.toString(),
53
- stroke: colorToRgb(component.strokeColor),
54
- strokeOpacity: colorToOpacity(component.strokeColor),
55
- strokeWidth: component.strokeThickness.toString()
56
- },
57
- []
58
- );
59
- case "polyline":
60
- return createElement(
61
- "polyline",
62
- {
63
- fill: "none",
64
- points: component.points
65
- .map(p => p.x.toString() + "," + p.y.toString())
66
- .join(" "),
67
- stroke: colorToRgb(component.strokeColor),
68
- strokeOpacity: colorToOpacity(component.strokeColor),
69
- strokeWidth: component.strokeThickness.toString()
70
- },
71
- []
72
- );
73
- case "text":
74
- if (!component.text) {
75
- return "";
76
- }
77
- const lineHeight = component.fontSize;
78
-
79
- const shadowStyle = {
80
- textAnchor: getTextAnchor(component.horizontalGrowthDirection),
81
- fontSize: component.fontSize.toString() + "px",
82
- fontWeight: component.fontWeight,
83
- fontFamily: component.fontFamily,
84
- stroke: colorToRgb(component.strokeColor),
85
- strokeOpacity: colorToOpacity(component.strokeColor),
86
- strokeWidth: component.strokeThickness.toString() + "px"
87
- };
88
-
89
- const style = {
90
- textAnchor: getTextAnchor(component.horizontalGrowthDirection),
91
- fontSize: component.fontSize.toString() + "px",
92
- fontWeight: component.fontWeight,
93
- fontFamily: component.fontFamily,
94
- fill: colorToRgb(component.textColor),
95
- fillOpacity: colorToOpacity(component.textColor)
96
- };
97
-
98
- const dy = getBaselineAdjustment(component.verticalGrowthDirection);
99
-
100
- const transform =
101
- "rotate(" +
102
- component.clockwiseRotationDegrees.toString() +
103
- " " +
104
- component.position.x.toString() +
105
- " " +
106
- component.position.y.toString() +
107
- ")";
108
-
109
- const lines: Array<string> =
110
- component.text !== null ? component.text.split("\n") : [];
111
-
112
- const tSpans = lines.map(t =>
113
- createElement(
114
- "tspan",
115
- {
116
- x: component.position.x.toString(),
117
- y: (
118
- component.position.y +
119
- (lines.indexOf(t) + dy) * lineHeight
120
- ).toString(),
121
- height: lineHeight.toString() + "px"
122
- },
123
- [
124
- t
125
- .replace(
126
- "<sub>",
127
- `<tspan style="font-size: ${component.fontSize *
128
- 0.8}px" baseline-shift="sub">`
129
- )
130
- .replace("</sub>", "</tspan>")
131
- ]
132
- )
133
- );
134
-
135
- const cs: Array<string> = [];
136
-
137
- if (component.strokeThickness > 0 && component.strokeColor !== null) {
138
- cs.push(
139
- createElement(
140
- "text",
141
- {
142
- style: objectToAttributeValue(shadowStyle),
143
- transform: transform
144
- },
145
- tSpans
146
- )
147
- );
148
- }
149
- cs.push(
150
- createElement(
151
- "text",
152
- {
153
- style: objectToAttributeValue(style),
154
- transform: transform
155
- },
156
- tSpans
157
- )
158
- );
159
- return cs.join();
160
- case "ellipse":
161
- const rx = Math.abs(component.bottomRight.x - component.topLeft.x) * 0.5;
162
- const ry = Math.abs(component.bottomRight.y - component.topLeft.y) * 0.5;
163
- const cx = (component.bottomRight.x + component.topLeft.x) * 0.5;
164
- const cy = (component.bottomRight.y + component.topLeft.y) * 0.5;
165
- return createElement(
166
- "ellipse",
167
- {
168
- cx: cx.toString(),
169
- cy: cy.toString(),
170
- rx: rx.toString(),
171
- ry: ry.toString(),
172
- stroke: colorToRgb(component.strokeColor),
173
- strokeOpacity: colorToOpacity(component.strokeColor),
174
- strokeWidth: component.strokeThickness.toString(),
175
- fill: colorToRgb(component.fillColor),
176
- fillOpacity: colorToOpacity(component.fillColor)
177
- },
178
- []
179
- );
180
- case "polygon":
181
- return createElement(
182
- "polygon",
183
- {
184
- points: component.points
185
- .map(p => p.x.toString() + "," + p.y.toString())
186
- .join(" "),
187
- stroke: colorToRgb(component.strokeColor),
188
- strokeOpacity: colorToOpacity(component.strokeColor),
189
- strokeWidth: component.strokeThickness.toString(),
190
- fill: colorToRgb(component.fillColor),
191
- fillOpacity: colorToOpacity(component.fillColor)
192
- },
193
- []
194
- );
195
- case "rectangle":
196
- return createElement(
197
- "rect",
198
- {
199
- x: component.topLeft.x.toString(),
200
- y: component.topLeft.y.toString(),
201
- width: Math.abs(
202
- component.bottomRight.x - component.topLeft.x
203
- ).toString(),
204
- height: Math.abs(
205
- component.bottomRight.y - component.topLeft.y
206
- ).toString(),
207
- stroke: colorToRgb(component.strokeColor),
208
- strokeOpacity: colorToOpacity(component.strokeColor),
209
- strokeWidth: component.strokeThickness.toString(),
210
- fill: colorToRgb(component.fillColor),
211
- fillOpacity: colorToOpacity(component.fillColor)
212
- },
213
- []
214
- );
215
- default:
216
- return "";
217
- }
218
- }
219
-
220
- interface Attributes {
221
- readonly [key: string]: string;
222
- }
223
-
224
- function createElement(
225
- elementName: string,
226
- attributes: Attributes,
227
- innerElements: string[]
228
- ): string {
229
- const formattedName = convertUpperToHyphenLower(elementName);
230
- let element = `<${formattedName}`;
231
-
232
- if (Object.keys(attributes).length > 0) {
233
- element = Object.keys(attributes).reduce(
234
- (previousValue: string, currentValue: string) => {
235
- if (attributes[currentValue]) {
236
- return (
237
- previousValue +
238
- ` ${convertUpperToHyphenLower(currentValue)}="${
239
- attributes[currentValue]
240
- }"`
241
- );
242
- } else {
243
- return previousValue;
244
- }
245
- },
246
- element
247
- );
248
- }
249
-
250
- element += ">";
251
-
252
- if (innerElements.length > 0) {
253
- element = innerElements.reduce(
254
- (previousValue: string, currentValue: string) => {
255
- if (!currentValue || currentValue.length < 1) {
256
- return previousValue;
257
- } else {
258
- return previousValue + `${currentValue}`;
259
- }
260
- },
261
- element
262
- );
263
- }
264
-
265
- element += `</${formattedName}>`;
266
-
267
- return element;
268
- }
269
-
270
- function objectToAttributeValue(attributes: Attributes): string {
271
- if (attributes && Object.keys(attributes).length > 0) {
272
- return Object.keys(attributes).reduce(
273
- (previousValue: string, currentValue: string) => {
274
- if (attributes[currentValue]) {
275
- return (
276
- previousValue +
277
- `${convertUpperToHyphenLower(currentValue)}:${
278
- attributes[currentValue]
279
- };`
280
- );
281
- } else {
282
- return previousValue;
283
- }
284
- },
285
- ""
286
- );
287
- }
288
-
289
- return "";
290
- }
291
-
292
- function convertUpperToHyphenLower(elementName: string): string {
293
- function upperToHyphenLower(match: string): string {
294
- return "-" + match.toLowerCase();
295
- }
296
-
297
- return elementName !== "viewBox"
298
- ? elementName.replace(/[A-Z]/g, upperToHyphenLower)
299
- : elementName;
300
- }
301
-
302
- function getBaselineAdjustment(d: AbstractImage.GrowthDirection): number {
303
- if (d === "up") {
304
- return 0.0;
305
- }
306
- if (d === "uniform") {
307
- return 0.5;
308
- }
309
- if (d === "down") {
310
- return 1.0;
311
- }
312
- throw "Unknown text alignment " + d;
313
- }
314
-
315
- function getTextAnchor(d: AbstractImage.GrowthDirection): string {
316
- if (d === "left") {
317
- return "end";
318
- }
319
- if (d === "uniform") {
320
- return "middle";
321
- }
322
- if (d === "right") {
323
- return "start";
324
- }
325
- throw "Unknown text alignment " + d;
326
- }
327
-
328
- function colorToRgb(color: AbstractImage.Color): string {
329
- return `rgb(${color.r.toString()}, ${color.g.toString()}, ${color.b.toString()})`;
330
- }
331
-
332
- function colorToOpacity(color: AbstractImage.Color): string {
333
- return (color.a / 255).toString();
334
- }
1
+ import * as AbstractImage from "../model/index";
2
+
3
+ export function createSVG(image: AbstractImage.AbstractImage, pixelWidth?: number, pixelHeight?: number): string {
4
+ const imageElements = image.components.map((c: AbstractImage.Component) => abstractComponentToSVG(c));
5
+
6
+ return createElement(
7
+ "svg",
8
+ {
9
+ xmlns: "http://www.w3.org/2000/svg",
10
+ width: `${pixelWidth || image.size.width}px`,
11
+ height: `${pixelHeight || image.size.height}px`,
12
+ viewBox: [0, 0, image.size.width, image.size.height].join(" "),
13
+ },
14
+ imageElements
15
+ );
16
+ }
17
+
18
+ function abstractComponentToSVG(component: AbstractImage.Component): string {
19
+ switch (component.type) {
20
+ case "group":
21
+ return createElement(
22
+ "g",
23
+ {
24
+ name: component.name,
25
+ },
26
+ component.children.map((c) => abstractComponentToSVG(c))
27
+ );
28
+ case "binaryimage":
29
+ switch (component.format) {
30
+ case "svg":
31
+ const svg = component.data.reduce((a, b) => a + String.fromCharCode(b), "");
32
+ return createElement(
33
+ "image",
34
+ {
35
+ x: component.topLeft.x.toString(),
36
+ y: component.topLeft.y.toString(),
37
+ width: (component.bottomRight.x - component.topLeft.x).toString(),
38
+ height: (component.bottomRight.y - component.topLeft.y).toString(),
39
+ href: `data:image/svg+xml;utf8,${svg}`,
40
+ },
41
+ []
42
+ );
43
+ default:
44
+ return "";
45
+ }
46
+ case "subimage":
47
+ return "";
48
+ case "line":
49
+ return createElement(
50
+ "line",
51
+ {
52
+ x1: component.start.x.toString(),
53
+ y1: component.start.y.toString(),
54
+ x2: component.end.x.toString(),
55
+ y2: component.end.y.toString(),
56
+ stroke: colorToRgb(component.strokeColor),
57
+ strokeOpacity: colorToOpacity(component.strokeColor),
58
+ strokeWidth: component.strokeThickness.toString(),
59
+ },
60
+ []
61
+ );
62
+ case "polyline":
63
+ return createElement(
64
+ "polyline",
65
+ {
66
+ fill: "none",
67
+ points: component.points.map((p) => p.x.toString() + "," + p.y.toString()).join(" "),
68
+ stroke: colorToRgb(component.strokeColor),
69
+ strokeOpacity: colorToOpacity(component.strokeColor),
70
+ strokeWidth: component.strokeThickness.toString(),
71
+ },
72
+ []
73
+ );
74
+ case "text":
75
+ if (!component.text) {
76
+ return "";
77
+ }
78
+ const lineHeight = component.fontSize;
79
+
80
+ const shadowStyle = {
81
+ textAnchor: getTextAnchor(component.horizontalGrowthDirection),
82
+ fontSize: component.fontSize.toString() + "px",
83
+ fontWeight: component.fontWeight,
84
+ fontFamily: component.fontFamily,
85
+ stroke: colorToRgb(component.strokeColor),
86
+ strokeOpacity: colorToOpacity(component.strokeColor),
87
+ strokeWidth: component.strokeThickness.toString() + "px",
88
+ };
89
+
90
+ const style = {
91
+ textAnchor: getTextAnchor(component.horizontalGrowthDirection),
92
+ fontSize: component.fontSize.toString() + "px",
93
+ fontWeight: component.fontWeight,
94
+ fontFamily: component.fontFamily,
95
+ fill: colorToRgb(component.textColor),
96
+ fillOpacity: colorToOpacity(component.textColor),
97
+ };
98
+
99
+ const dy = getBaselineAdjustment(component.verticalGrowthDirection);
100
+
101
+ const transform =
102
+ "rotate(" +
103
+ component.clockwiseRotationDegrees.toString() +
104
+ " " +
105
+ component.position.x.toString() +
106
+ " " +
107
+ component.position.y.toString() +
108
+ ")";
109
+
110
+ const lines: Array<string> = component.text !== null ? component.text.split("\n") : [];
111
+
112
+ const tSpans = lines.map((t) =>
113
+ createElement(
114
+ "tspan",
115
+ {
116
+ x: component.position.x.toString(),
117
+ y: (component.position.y + (lines.indexOf(t) + dy) * lineHeight).toString(),
118
+ height: lineHeight.toString() + "px",
119
+ },
120
+ [
121
+ t
122
+ .replace("<sub>", `<tspan style="font-size: ${component.fontSize * 0.8}px" baseline-shift="sub">`)
123
+ .replace("</sub>", "</tspan>"),
124
+ ]
125
+ )
126
+ );
127
+
128
+ const cs: Array<string> = [];
129
+
130
+ if (component.strokeThickness > 0 && component.strokeColor !== null) {
131
+ cs.push(
132
+ createElement(
133
+ "text",
134
+ {
135
+ style: objectToAttributeValue(shadowStyle),
136
+ transform: transform,
137
+ },
138
+ tSpans
139
+ )
140
+ );
141
+ }
142
+ cs.push(
143
+ createElement(
144
+ "text",
145
+ {
146
+ style: objectToAttributeValue(style),
147
+ transform: transform,
148
+ },
149
+ tSpans
150
+ )
151
+ );
152
+ return cs.join();
153
+ case "ellipse":
154
+ const rx = Math.abs(component.bottomRight.x - component.topLeft.x) * 0.5;
155
+ const ry = Math.abs(component.bottomRight.y - component.topLeft.y) * 0.5;
156
+ const cx = (component.bottomRight.x + component.topLeft.x) * 0.5;
157
+ const cy = (component.bottomRight.y + component.topLeft.y) * 0.5;
158
+ return createElement(
159
+ "ellipse",
160
+ {
161
+ cx: cx.toString(),
162
+ cy: cy.toString(),
163
+ rx: rx.toString(),
164
+ ry: ry.toString(),
165
+ stroke: colorToRgb(component.strokeColor),
166
+ strokeOpacity: colorToOpacity(component.strokeColor),
167
+ strokeWidth: component.strokeThickness.toString(),
168
+ fill: colorToRgb(component.fillColor),
169
+ fillOpacity: colorToOpacity(component.fillColor),
170
+ },
171
+ []
172
+ );
173
+ case "polygon":
174
+ return createElement(
175
+ "polygon",
176
+ {
177
+ points: component.points.map((p) => p.x.toString() + "," + p.y.toString()).join(" "),
178
+ stroke: colorToRgb(component.strokeColor),
179
+ strokeOpacity: colorToOpacity(component.strokeColor),
180
+ strokeWidth: component.strokeThickness.toString(),
181
+ fill: colorToRgb(component.fillColor),
182
+ fillOpacity: colorToOpacity(component.fillColor),
183
+ },
184
+ []
185
+ );
186
+ case "rectangle":
187
+ return createElement(
188
+ "rect",
189
+ {
190
+ x: component.topLeft.x.toString(),
191
+ y: component.topLeft.y.toString(),
192
+ width: Math.abs(component.bottomRight.x - component.topLeft.x).toString(),
193
+ height: Math.abs(component.bottomRight.y - component.topLeft.y).toString(),
194
+ stroke: colorToRgb(component.strokeColor),
195
+ strokeOpacity: colorToOpacity(component.strokeColor),
196
+ strokeWidth: component.strokeThickness.toString(),
197
+ fill: colorToRgb(component.fillColor),
198
+ fillOpacity: colorToOpacity(component.fillColor),
199
+ },
200
+ []
201
+ );
202
+ default:
203
+ return "";
204
+ }
205
+ }
206
+
207
+ interface Attributes {
208
+ readonly [key: string]: string;
209
+ }
210
+
211
+ function createElement(elementName: string, attributes: Attributes, innerElements: string[]): string {
212
+ const formattedName = convertUpperToHyphenLower(elementName);
213
+ let element = `<${formattedName}`;
214
+
215
+ if (Object.keys(attributes).length > 0) {
216
+ element = Object.keys(attributes).reduce((previousValue: string, currentValue: string) => {
217
+ if (attributes[currentValue]) {
218
+ return previousValue + ` ${convertUpperToHyphenLower(currentValue)}="${attributes[currentValue]}"`;
219
+ } else {
220
+ return previousValue;
221
+ }
222
+ }, element);
223
+ }
224
+
225
+ element += ">";
226
+
227
+ if (innerElements.length > 0) {
228
+ element = innerElements.reduce((previousValue: string, currentValue: string) => {
229
+ if (!currentValue || currentValue.length < 1) {
230
+ return previousValue;
231
+ } else {
232
+ return previousValue + `${currentValue}`;
233
+ }
234
+ }, element);
235
+ }
236
+
237
+ element += `</${formattedName}>`;
238
+
239
+ return element;
240
+ }
241
+
242
+ function objectToAttributeValue(attributes: Attributes): string {
243
+ if (attributes && Object.keys(attributes).length > 0) {
244
+ return Object.keys(attributes).reduce((previousValue: string, currentValue: string) => {
245
+ if (attributes[currentValue]) {
246
+ return previousValue + `${convertUpperToHyphenLower(currentValue)}:${attributes[currentValue]};`;
247
+ } else {
248
+ return previousValue;
249
+ }
250
+ }, "");
251
+ }
252
+
253
+ return "";
254
+ }
255
+
256
+ function convertUpperToHyphenLower(elementName: string): string {
257
+ function upperToHyphenLower(match: string): string {
258
+ return "-" + match.toLowerCase();
259
+ }
260
+
261
+ return elementName !== "viewBox" ? elementName.replace(/[A-Z]/g, upperToHyphenLower) : elementName;
262
+ }
263
+
264
+ function getBaselineAdjustment(d: AbstractImage.GrowthDirection): number {
265
+ if (d === "up") {
266
+ return 0.0;
267
+ }
268
+ if (d === "uniform") {
269
+ return 0.5;
270
+ }
271
+ if (d === "down") {
272
+ return 1.0;
273
+ }
274
+ throw "Unknown text alignment " + d;
275
+ }
276
+
277
+ function getTextAnchor(d: AbstractImage.GrowthDirection): string {
278
+ if (d === "left") {
279
+ return "end";
280
+ }
281
+ if (d === "uniform") {
282
+ return "middle";
283
+ }
284
+ if (d === "right") {
285
+ return "start";
286
+ }
287
+ throw "Unknown text alignment " + d;
288
+ }
289
+
290
+ function colorToRgb(color: AbstractImage.Color): string {
291
+ return `rgb(${color.r.toString()}, ${color.g.toString()}, ${color.b.toString()})`;
292
+ }
293
+
294
+ function colorToOpacity(color: AbstractImage.Color): string {
295
+ return (color.a / 255).toString();
296
+ }
package/src/index.ts CHANGED
@@ -1,11 +1,11 @@
1
- export * from "./model/abstract-image";
2
- export * from "./model/color";
3
- export * from "./model/component";
4
- export * from "./model/point";
5
- export * from "./model/size";
6
-
7
- export * from "./exporters/svg-export-image";
8
- export * from "./exporters/png-export-image";
9
- export * from "./exporters/dxf2d-export-image";
10
- export * from "./exporters/react-svg-export-image";
11
- export * from "./exporters/eps-export-image";
1
+ export * from "./model/abstract-image";
2
+ export * from "./model/color";
3
+ export * from "./model/component";
4
+ export * from "./model/point";
5
+ export * from "./model/size";
6
+
7
+ export * from "./exporters/svg-export-image";
8
+ export * from "./exporters/png-export-image";
9
+ export * from "./exporters/dxf2d-export-image";
10
+ export * from "./exporters/react-svg-export-image";
11
+ export * from "./exporters/eps-export-image";