gospelo-iconcraft-react 0.3.1 → 0.3.5
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.
- package/README.md +3 -2
- package/dist/index.d.ts +12 -4
- package/dist/index.js +99 -77
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -161,7 +161,7 @@ import { IconCraftShape } from 'gospelo-iconcraft-react';
|
|
|
161
161
|
| Prop | Type | Default | Description |
|
|
162
162
|
|------|------|---------|-------------|
|
|
163
163
|
| `svg` | `string` | required | SVG content string |
|
|
164
|
-
| `mode` | `'jelly' \| '
|
|
164
|
+
| `mode` | `'sticker' \| 'jelly' \| 'bubble' \| 'wax'` | `'jelly'` | Shape mode |
|
|
165
165
|
| `shapeColor` | `string` | `'#6366f1'` | Shape base color (hex) |
|
|
166
166
|
| `iconColor` | `string` | `'#1d1d1f'` | Icon color (for stroke/fill styles) |
|
|
167
167
|
| `iconStyle` | `'original' \| 'emboss' \| 'stroke' \| 'fill'` | `'emboss'` | Icon rendering style |
|
|
@@ -208,8 +208,9 @@ icon1.config.update({ shapeColor: '#10b981', rotation: 45 });
|
|
|
208
208
|
|
|
209
209
|
| Mode | Description |
|
|
210
210
|
|------|-------------|
|
|
211
|
+
| `sticker` | Jelly-based shape with paper-like noise texture, no highlights |
|
|
211
212
|
| `jelly` | Smooth, organic blob shape following icon contours |
|
|
212
|
-
| `
|
|
213
|
+
| `bubble` | Perfect circle/sphere with glass-like highlights |
|
|
213
214
|
| `wax` | Irregular wax seal shape with pressed icon indent |
|
|
214
215
|
|
|
215
216
|
## Animations
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { CSSProperties, ReactNode } from 'react';
|
|
|
2
2
|
import * as gospelo_iconcraft_wasm from 'gospelo-iconcraft-wasm';
|
|
3
3
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
4
|
|
|
5
|
-
type ShapeMode = 'jelly' | '
|
|
5
|
+
type ShapeMode = 'jelly' | 'bubble' | 'wax' | 'sticker';
|
|
6
6
|
type IconStyle = 'original' | 'emboss' | 'stroke' | 'fill';
|
|
7
7
|
/** Built-in animation types */
|
|
8
8
|
type BuiltInAnimationType = 'none' | 'shake' | 'bounce' | 'pulse' | 'swing' | 'wobble' | 'jello' | 'heartbeat' | 'float' | 'spin' | 'rubberBand' | 'squish' | 'tada' | 'flip' | 'drop' | 'pop' | 'wiggle' | 'breathe';
|
|
@@ -93,7 +93,7 @@ interface IconCraftResult {
|
|
|
93
93
|
interface IconCraftShapeProps {
|
|
94
94
|
/** SVG content string or URL */
|
|
95
95
|
svg: string;
|
|
96
|
-
/** Shape mode: jelly,
|
|
96
|
+
/** Shape mode: jelly, bubble, or wax */
|
|
97
97
|
mode?: ShapeMode;
|
|
98
98
|
/** Base color for the shape (hex) */
|
|
99
99
|
shapeColor?: string;
|
|
@@ -208,6 +208,7 @@ declare class IconCraftConfig {
|
|
|
208
208
|
includeIcon: boolean;
|
|
209
209
|
shapeColor: string;
|
|
210
210
|
rotation: number;
|
|
211
|
+
iconColor: string;
|
|
211
212
|
};
|
|
212
213
|
/**
|
|
213
214
|
* スタイル用のサイズを取得
|
|
@@ -335,6 +336,7 @@ interface WasmGenerateParams {
|
|
|
335
336
|
includeIcon: boolean;
|
|
336
337
|
shapeColor: string;
|
|
337
338
|
rotation?: number;
|
|
339
|
+
iconColor?: string;
|
|
338
340
|
}
|
|
339
341
|
/**
|
|
340
342
|
* WASMマネージャー(Singleton)
|
|
@@ -563,6 +565,12 @@ interface IconCraftViewProps {
|
|
|
563
565
|
renderReticle?: (props: ReticleProps) => React.ReactNode;
|
|
564
566
|
/** Reticle preset object (overrides renderReticle) */
|
|
565
567
|
reticlePreset?: ReticlePreset;
|
|
568
|
+
/** Dial ring color (default: '#000') */
|
|
569
|
+
dialColor?: string;
|
|
570
|
+
/** Notch color (default: '#000') */
|
|
571
|
+
notchColor?: string;
|
|
572
|
+
/** Reticle color (default: '#000') */
|
|
573
|
+
reticleColor?: string;
|
|
566
574
|
}
|
|
567
575
|
/** Props passed to custom reticle renderer */
|
|
568
576
|
interface ReticleProps {
|
|
@@ -603,7 +611,7 @@ interface DialLabelProps {
|
|
|
603
611
|
* <IconCraftView instance={icon} zIndex={10} />
|
|
604
612
|
* ```
|
|
605
613
|
*/
|
|
606
|
-
declare function IconCraftView({ instance, animation, animationTarget, animateOnHover, zIndex, className, style, onClick, onLoad, onError, showRotationDial, onRotationChange, rotationSnap, renderRing: renderRingProp, renderNotch: renderNotchProp, renderLabel: renderLabelProp, dialPreset, showReticle, renderReticle: renderReticleProp, reticlePreset, }: IconCraftViewProps): react_jsx_runtime.JSX.Element | null;
|
|
614
|
+
declare function IconCraftView({ instance, animation, animationTarget, animateOnHover, zIndex, className, style, onClick, onLoad, onError, showRotationDial, onRotationChange, rotationSnap, renderRing: renderRingProp, renderNotch: renderNotchProp, renderLabel: renderLabelProp, dialPreset, showReticle, renderReticle: renderReticleProp, reticlePreset, dialColor: dialColorProp, notchColor: notchColorProp, reticleColor: reticleColorProp, }: IconCraftViewProps): react_jsx_runtime.JSX.Element | null;
|
|
607
615
|
|
|
608
616
|
/**
|
|
609
617
|
* IconCraftSimple Props
|
|
@@ -668,7 +676,7 @@ interface IconCraftSimpleProps {
|
|
|
668
676
|
* // SVG文字列を直接渡す
|
|
669
677
|
* <IconCraftSimple
|
|
670
678
|
* src={`<svg>...</svg>`}
|
|
671
|
-
* mode="
|
|
679
|
+
* mode="bubble"
|
|
672
680
|
* iconStyle="emboss"
|
|
673
681
|
* />
|
|
674
682
|
* ```
|
package/dist/index.js
CHANGED
|
@@ -60,7 +60,7 @@ var IconCraftConfig = class _IconCraftConfig {
|
|
|
60
60
|
* WASM呼び出し用のパラメータを取得
|
|
61
61
|
*/
|
|
62
62
|
getWasmParams() {
|
|
63
|
-
const needsEmbossSvg = this.mode === "wax" || this.iconStyle === "emboss";
|
|
63
|
+
const needsEmbossSvg = this.mode === "wax" || this.mode === "sticker" || this.iconStyle === "emboss";
|
|
64
64
|
return {
|
|
65
65
|
mode: this.mode,
|
|
66
66
|
offset: this.offset,
|
|
@@ -68,7 +68,8 @@ var IconCraftConfig = class _IconCraftConfig {
|
|
|
68
68
|
simplify: this.simplify,
|
|
69
69
|
includeIcon: needsEmbossSvg,
|
|
70
70
|
shapeColor: this.shapeColor,
|
|
71
|
-
rotation: this.rotation
|
|
71
|
+
rotation: this.rotation,
|
|
72
|
+
iconColor: this.iconColor
|
|
72
73
|
};
|
|
73
74
|
}
|
|
74
75
|
/**
|
|
@@ -96,13 +97,15 @@ function createCacheKey(params) {
|
|
|
96
97
|
simplify: params.simplify,
|
|
97
98
|
includeIcon: params.includeIcon,
|
|
98
99
|
shapeColor: params.shapeColor,
|
|
99
|
-
rotation: params.rotation ?? 0
|
|
100
|
+
rotation: params.rotation ?? 0,
|
|
101
|
+
iconColor: params.iconColor ?? ""
|
|
100
102
|
});
|
|
101
103
|
}
|
|
102
104
|
var shapeModeMap = {
|
|
103
105
|
jelly: 0,
|
|
104
|
-
|
|
105
|
-
wax: 2
|
|
106
|
+
bubble: 1,
|
|
107
|
+
wax: 2,
|
|
108
|
+
sticker: 3
|
|
106
109
|
};
|
|
107
110
|
var WasmManagerClass = class {
|
|
108
111
|
constructor() {
|
|
@@ -142,6 +145,7 @@ var WasmManagerClass = class {
|
|
|
142
145
|
}
|
|
143
146
|
const wasm = await this.init();
|
|
144
147
|
const rotation = params.rotation ?? 0;
|
|
148
|
+
const iconColor = params.iconColor ?? null;
|
|
145
149
|
const result = typeof wasm.generate_clippath_with_rotation === "function" ? wasm.generate_clippath_with_rotation(
|
|
146
150
|
params.svgContent,
|
|
147
151
|
shapeModeMap[params.mode],
|
|
@@ -150,7 +154,8 @@ var WasmManagerClass = class {
|
|
|
150
154
|
params.simplify,
|
|
151
155
|
params.includeIcon,
|
|
152
156
|
params.shapeColor,
|
|
153
|
-
rotation
|
|
157
|
+
rotation,
|
|
158
|
+
iconColor
|
|
154
159
|
) : wasm.generate_clippath_with_color(
|
|
155
160
|
params.svgContent,
|
|
156
161
|
shapeModeMap[params.mode],
|
|
@@ -542,7 +547,9 @@ import { useEffect, useState, useMemo, useCallback, useRef } from "react";
|
|
|
542
547
|
|
|
543
548
|
// src/components/dialPresets.tsx
|
|
544
549
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
545
|
-
var dialColor = "var(--iconcraft-dial-color, #
|
|
550
|
+
var dialColor = "var(--iconcraft-dial-color, #000)";
|
|
551
|
+
var notchColor = "var(--iconcraft-notch-color, #000)";
|
|
552
|
+
var reticleColor = "var(--iconcraft-reticle-color, #000)";
|
|
546
553
|
var dialPresetDashed = {
|
|
547
554
|
name: "dashed",
|
|
548
555
|
renderRing: ({ cx, cy, radius }) => /* @__PURE__ */ jsx(
|
|
@@ -564,7 +571,7 @@ var dialPresetDashed = {
|
|
|
564
571
|
cx: x,
|
|
565
572
|
cy: y,
|
|
566
573
|
r: "7",
|
|
567
|
-
fill:
|
|
574
|
+
fill: notchColor,
|
|
568
575
|
stroke: "#fff",
|
|
569
576
|
strokeWidth: "2",
|
|
570
577
|
style: { pointerEvents: "auto", cursor: "grab" },
|
|
@@ -599,7 +606,7 @@ var dialPresetSolid = {
|
|
|
599
606
|
y: "-5",
|
|
600
607
|
width: "10",
|
|
601
608
|
height: "10",
|
|
602
|
-
fill:
|
|
609
|
+
fill: notchColor,
|
|
603
610
|
stroke: "#fff",
|
|
604
611
|
strokeWidth: "1.5",
|
|
605
612
|
rx: "1"
|
|
@@ -646,7 +653,7 @@ var dialPresetTicks = {
|
|
|
646
653
|
cx: x,
|
|
647
654
|
cy: y,
|
|
648
655
|
r: "5",
|
|
649
|
-
fill:
|
|
656
|
+
fill: notchColor,
|
|
650
657
|
stroke: "#fff",
|
|
651
658
|
strokeWidth: "1.5",
|
|
652
659
|
style: { pointerEvents: "auto", cursor: "grab" },
|
|
@@ -689,8 +696,8 @@ var dialPresetDotted = {
|
|
|
689
696
|
children: /* @__PURE__ */ jsx(
|
|
690
697
|
"polygon",
|
|
691
698
|
{
|
|
692
|
-
points: "0
|
|
693
|
-
fill:
|
|
699
|
+
points: "0,-2 -5,10 5,10",
|
|
700
|
+
fill: notchColor,
|
|
694
701
|
stroke: "#fff",
|
|
695
702
|
strokeWidth: "1.5",
|
|
696
703
|
strokeLinejoin: "round"
|
|
@@ -746,7 +753,7 @@ var dialPresetDouble = {
|
|
|
746
753
|
width: "6",
|
|
747
754
|
height: "16",
|
|
748
755
|
rx: "3",
|
|
749
|
-
fill:
|
|
756
|
+
fill: notchColor,
|
|
750
757
|
stroke: "#fff",
|
|
751
758
|
strokeWidth: "1.5"
|
|
752
759
|
}
|
|
@@ -805,9 +812,9 @@ var dialPresetCrosshair = {
|
|
|
805
812
|
style: { pointerEvents: "auto", cursor: "grab" },
|
|
806
813
|
onMouseDown,
|
|
807
814
|
children: [
|
|
808
|
-
/* @__PURE__ */ jsx("line", { x1: -6, y1: 0, x2: 6, y2: 0, stroke:
|
|
809
|
-
/* @__PURE__ */ jsx("line", { x1: 0, y1: -6, x2: 0, y2: 6, stroke:
|
|
810
|
-
/* @__PURE__ */ jsx("circle", { cx: 0, cy: 0, r: "3", fill: "#fff", stroke:
|
|
815
|
+
/* @__PURE__ */ jsx("line", { x1: -6, y1: 0, x2: 6, y2: 0, stroke: notchColor, strokeWidth: "2" }),
|
|
816
|
+
/* @__PURE__ */ jsx("line", { x1: 0, y1: -6, x2: 0, y2: 6, stroke: notchColor, strokeWidth: "2" }),
|
|
817
|
+
/* @__PURE__ */ jsx("circle", { cx: 0, cy: 0, r: "3", fill: "#fff", stroke: notchColor, strokeWidth: "1.5" })
|
|
811
818
|
]
|
|
812
819
|
}
|
|
813
820
|
)
|
|
@@ -852,7 +859,7 @@ var dialPresetMinimal = {
|
|
|
852
859
|
"polygon",
|
|
853
860
|
{
|
|
854
861
|
points: "0,-8 -5,4 5,4",
|
|
855
|
-
fill:
|
|
862
|
+
fill: notchColor,
|
|
856
863
|
stroke: "#fff",
|
|
857
864
|
strokeWidth: "1.5",
|
|
858
865
|
strokeLinejoin: "round"
|
|
@@ -886,7 +893,7 @@ var dialPresetNeedle = {
|
|
|
886
893
|
"path",
|
|
887
894
|
{
|
|
888
895
|
d: "M 0,-12 L 2,-2 0,4 -2,-2 Z",
|
|
889
|
-
fill:
|
|
896
|
+
fill: notchColor,
|
|
890
897
|
stroke: "#fff",
|
|
891
898
|
strokeWidth: "1",
|
|
892
899
|
strokeLinejoin: "round"
|
|
@@ -923,7 +930,7 @@ var dialPresetBar = {
|
|
|
923
930
|
width: "4",
|
|
924
931
|
height: "20",
|
|
925
932
|
rx: "2",
|
|
926
|
-
fill:
|
|
933
|
+
fill: notchColor,
|
|
927
934
|
stroke: "#fff",
|
|
928
935
|
strokeWidth: "1.5"
|
|
929
936
|
}
|
|
@@ -971,7 +978,7 @@ var dialPresetArrow = {
|
|
|
971
978
|
"path",
|
|
972
979
|
{
|
|
973
980
|
d: "M 0,-11 L 4,-3 1,-3 1,5 -1,5 -1,-3 -4,-3 Z",
|
|
974
|
-
fill:
|
|
981
|
+
fill: notchColor,
|
|
975
982
|
stroke: "#fff",
|
|
976
983
|
strokeWidth: "1",
|
|
977
984
|
strokeLinejoin: "round"
|
|
@@ -1005,7 +1012,7 @@ var reticlePresetCross = {
|
|
|
1005
1012
|
y1: cy - half,
|
|
1006
1013
|
x2: cx,
|
|
1007
1014
|
y2: cy + half,
|
|
1008
|
-
stroke:
|
|
1015
|
+
stroke: reticleColor,
|
|
1009
1016
|
strokeWidth: "1"
|
|
1010
1017
|
}
|
|
1011
1018
|
),
|
|
@@ -1016,11 +1023,11 @@ var reticlePresetCross = {
|
|
|
1016
1023
|
y1: cy,
|
|
1017
1024
|
x2: cx + half,
|
|
1018
1025
|
y2: cy,
|
|
1019
|
-
stroke:
|
|
1026
|
+
stroke: reticleColor,
|
|
1020
1027
|
strokeWidth: "1"
|
|
1021
1028
|
}
|
|
1022
1029
|
),
|
|
1023
|
-
/* @__PURE__ */ jsx("circle", { cx, cy, r: "2", fill:
|
|
1030
|
+
/* @__PURE__ */ jsx("circle", { cx, cy, r: "2", fill: reticleColor })
|
|
1024
1031
|
] });
|
|
1025
1032
|
}
|
|
1026
1033
|
};
|
|
@@ -1037,11 +1044,11 @@ var reticlePresetBullseye = {
|
|
|
1037
1044
|
cy,
|
|
1038
1045
|
r,
|
|
1039
1046
|
fill: "none",
|
|
1040
|
-
stroke:
|
|
1047
|
+
stroke: reticleColor,
|
|
1041
1048
|
strokeWidth: "1"
|
|
1042
1049
|
}
|
|
1043
1050
|
),
|
|
1044
|
-
/* @__PURE__ */ jsx("circle", { cx, cy, r: "2.5", fill:
|
|
1051
|
+
/* @__PURE__ */ jsx("circle", { cx, cy, r: "2.5", fill: reticleColor })
|
|
1045
1052
|
] });
|
|
1046
1053
|
}
|
|
1047
1054
|
};
|
|
@@ -1064,7 +1071,7 @@ var reticlePresetGlobe = {
|
|
|
1064
1071
|
{
|
|
1065
1072
|
d: `M ${cx + lx} ${cy - ly} A ${rx} ${ly} 0 0 0 ${cx + lx} ${cy + ly}`,
|
|
1066
1073
|
fill: "none",
|
|
1067
|
-
stroke:
|
|
1074
|
+
stroke: reticleColor,
|
|
1068
1075
|
strokeWidth: sw
|
|
1069
1076
|
}
|
|
1070
1077
|
),
|
|
@@ -1073,7 +1080,7 @@ var reticlePresetGlobe = {
|
|
|
1073
1080
|
{
|
|
1074
1081
|
d: `M ${cx - lx} ${cy - ly} A ${rx} ${ly} 0 0 1 ${cx - lx} ${cy + ly}`,
|
|
1075
1082
|
fill: "none",
|
|
1076
|
-
stroke:
|
|
1083
|
+
stroke: reticleColor,
|
|
1077
1084
|
strokeWidth: sw
|
|
1078
1085
|
}
|
|
1079
1086
|
)
|
|
@@ -1086,7 +1093,7 @@ var reticlePresetGlobe = {
|
|
|
1086
1093
|
y1: cy,
|
|
1087
1094
|
x2: cx + r,
|
|
1088
1095
|
y2: cy,
|
|
1089
|
-
stroke:
|
|
1096
|
+
stroke: reticleColor,
|
|
1090
1097
|
strokeWidth: sw
|
|
1091
1098
|
}
|
|
1092
1099
|
),
|
|
@@ -1100,7 +1107,7 @@ var reticlePresetGlobe = {
|
|
|
1100
1107
|
{
|
|
1101
1108
|
d: `M ${cx - lx} ${cy - ly} A ${lx} ${ry} 0 0 0 ${cx + lx} ${cy - ly}`,
|
|
1102
1109
|
fill: "none",
|
|
1103
|
-
stroke:
|
|
1110
|
+
stroke: reticleColor,
|
|
1104
1111
|
strokeWidth: sw
|
|
1105
1112
|
}
|
|
1106
1113
|
),
|
|
@@ -1109,7 +1116,7 @@ var reticlePresetGlobe = {
|
|
|
1109
1116
|
{
|
|
1110
1117
|
d: `M ${cx - lx} ${cy + ly} A ${lx} ${ry} 0 0 1 ${cx + lx} ${cy + ly}`,
|
|
1111
1118
|
fill: "none",
|
|
1112
|
-
stroke:
|
|
1119
|
+
stroke: reticleColor,
|
|
1113
1120
|
strokeWidth: sw
|
|
1114
1121
|
}
|
|
1115
1122
|
)
|
|
@@ -1125,7 +1132,7 @@ var reticlePresetGlobe = {
|
|
|
1125
1132
|
cy,
|
|
1126
1133
|
r,
|
|
1127
1134
|
fill: "none",
|
|
1128
|
-
stroke:
|
|
1135
|
+
stroke: reticleColor,
|
|
1129
1136
|
strokeWidth: sw
|
|
1130
1137
|
}
|
|
1131
1138
|
),
|
|
@@ -1136,7 +1143,7 @@ var reticlePresetGlobe = {
|
|
|
1136
1143
|
y1: cy - r,
|
|
1137
1144
|
x2: cx,
|
|
1138
1145
|
y2: cy + r,
|
|
1139
|
-
stroke:
|
|
1146
|
+
stroke: reticleColor,
|
|
1140
1147
|
strokeWidth: sw
|
|
1141
1148
|
}
|
|
1142
1149
|
),
|
|
@@ -1150,7 +1157,7 @@ var reticlePresetGlobe = {
|
|
|
1150
1157
|
{
|
|
1151
1158
|
d: `M ${cx + lx} ${cy - ly} A ${rx} ${ly} 0 0 1 ${cx + lx} ${cy + ly}`,
|
|
1152
1159
|
fill: "none",
|
|
1153
|
-
stroke:
|
|
1160
|
+
stroke: reticleColor,
|
|
1154
1161
|
strokeWidth: sw
|
|
1155
1162
|
}
|
|
1156
1163
|
),
|
|
@@ -1159,7 +1166,7 @@ var reticlePresetGlobe = {
|
|
|
1159
1166
|
{
|
|
1160
1167
|
d: `M ${cx - lx} ${cy - ly} A ${rx} ${ly} 0 0 0 ${cx - lx} ${cy + ly}`,
|
|
1161
1168
|
fill: "none",
|
|
1162
|
-
stroke:
|
|
1169
|
+
stroke: reticleColor,
|
|
1163
1170
|
strokeWidth: sw
|
|
1164
1171
|
}
|
|
1165
1172
|
)
|
|
@@ -1172,7 +1179,7 @@ var reticlePresetGlobe = {
|
|
|
1172
1179
|
y1: cy,
|
|
1173
1180
|
x2: cx + r,
|
|
1174
1181
|
y2: cy,
|
|
1175
|
-
stroke:
|
|
1182
|
+
stroke: reticleColor,
|
|
1176
1183
|
strokeWidth: sw
|
|
1177
1184
|
}
|
|
1178
1185
|
),
|
|
@@ -1186,7 +1193,7 @@ var reticlePresetGlobe = {
|
|
|
1186
1193
|
{
|
|
1187
1194
|
d: `M ${cx - lx} ${cy - ly} A ${lx} ${ry} 0 0 1 ${cx + lx} ${cy - ly}`,
|
|
1188
1195
|
fill: "none",
|
|
1189
|
-
stroke:
|
|
1196
|
+
stroke: reticleColor,
|
|
1190
1197
|
strokeWidth: sw
|
|
1191
1198
|
}
|
|
1192
1199
|
),
|
|
@@ -1195,7 +1202,7 @@ var reticlePresetGlobe = {
|
|
|
1195
1202
|
{
|
|
1196
1203
|
d: `M ${cx - lx} ${cy + ly} A ${lx} ${ry} 0 0 0 ${cx + lx} ${cy + ly}`,
|
|
1197
1204
|
fill: "none",
|
|
1198
|
-
stroke:
|
|
1205
|
+
stroke: reticleColor,
|
|
1199
1206
|
strokeWidth: sw
|
|
1200
1207
|
}
|
|
1201
1208
|
)
|
|
@@ -1466,9 +1473,18 @@ function getParser() {
|
|
|
1466
1473
|
}
|
|
1467
1474
|
function sanitizeSvg(html) {
|
|
1468
1475
|
if (!html) return "";
|
|
1469
|
-
const
|
|
1476
|
+
const imagePlaceholders = [];
|
|
1477
|
+
const preserved = html.replace(/<image\b[^>]*\/?\s*>/gi, (match) => {
|
|
1478
|
+
imagePlaceholders.push(match);
|
|
1479
|
+
return `<!--__IMAGE_${imagePlaceholders.length - 1}__-->`;
|
|
1480
|
+
});
|
|
1481
|
+
const doc = getParser().parseFromString(preserved, "text/html");
|
|
1470
1482
|
sanitizeNode(doc.body);
|
|
1471
|
-
|
|
1483
|
+
let result = doc.body.innerHTML;
|
|
1484
|
+
result = result.replace(/<!--__IMAGE_(\d+)__-->/g, (_, idx) => {
|
|
1485
|
+
return imagePlaceholders[parseInt(idx, 10)] ?? "";
|
|
1486
|
+
});
|
|
1487
|
+
return result;
|
|
1472
1488
|
}
|
|
1473
1489
|
function sanitizeNode(node) {
|
|
1474
1490
|
const toRemove = [];
|
|
@@ -1537,6 +1553,8 @@ function resolveTransformOrigin(value) {
|
|
|
1537
1553
|
return "center center";
|
|
1538
1554
|
}
|
|
1539
1555
|
}
|
|
1556
|
+
var ROTATE_CURSOR_SVG = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12a9 9 0 1 1-3-6.7"/><polyline points="21 3 21 9 15 9"/></svg>`;
|
|
1557
|
+
var ROTATE_CURSOR = `url("data:image/svg+xml,${encodeURIComponent(ROTATE_CURSOR_SVG)}") 12 12, pointer`;
|
|
1540
1558
|
function IconCraftView({
|
|
1541
1559
|
instance,
|
|
1542
1560
|
animation,
|
|
@@ -1557,7 +1575,10 @@ function IconCraftView({
|
|
|
1557
1575
|
dialPreset,
|
|
1558
1576
|
showReticle = false,
|
|
1559
1577
|
renderReticle: renderReticleProp,
|
|
1560
|
-
reticlePreset
|
|
1578
|
+
reticlePreset,
|
|
1579
|
+
dialColor: dialColorProp,
|
|
1580
|
+
notchColor: notchColorProp,
|
|
1581
|
+
reticleColor: reticleColorProp
|
|
1561
1582
|
}) {
|
|
1562
1583
|
const resolvedDial = dialPreset ?? (renderRingProp || renderNotchProp || renderLabelProp ? void 0 : dialPresetDotted);
|
|
1563
1584
|
const renderRing = resolvedDial?.renderRing ?? renderRingProp;
|
|
@@ -1654,7 +1675,7 @@ function IconCraftView({
|
|
|
1654
1675
|
const isWax = mode === "wax";
|
|
1655
1676
|
if (isWax && instance.embossSvg) {
|
|
1656
1677
|
let svg2 = instance.embossSvg;
|
|
1657
|
-
const modes = ["wax", "jelly", "
|
|
1678
|
+
const modes = ["wax", "jelly", "bubble", "sticker"];
|
|
1658
1679
|
for (const m of modes) {
|
|
1659
1680
|
svg2 = svg2.replace(
|
|
1660
1681
|
new RegExp(`id="${m}-`, "g"),
|
|
@@ -1666,14 +1687,6 @@ function IconCraftView({
|
|
|
1666
1687
|
);
|
|
1667
1688
|
}
|
|
1668
1689
|
if (iconStyle === "emboss") {
|
|
1669
|
-
const rotation3 = instance.config.rotation;
|
|
1670
|
-
if (rotation3) {
|
|
1671
|
-
const layout2 = result?.icon_layout;
|
|
1672
|
-
const iconCx = (layout2?.left_percent ?? 28) + (layout2?.width_percent ?? 44) / 2;
|
|
1673
|
-
const iconCy = (layout2?.top_percent ?? 28) + (layout2?.height_percent ?? 44) / 2;
|
|
1674
|
-
const rotateTransform = `transform="rotate(${rotation3}, ${iconCx.toFixed(2)}, ${iconCy.toFixed(2)})"`;
|
|
1675
|
-
svg2 = svg2.replace(/<g filter="none">/, `<g filter="none" ${rotateTransform}>`);
|
|
1676
|
-
}
|
|
1677
1690
|
return svg2;
|
|
1678
1691
|
}
|
|
1679
1692
|
{
|
|
@@ -1709,7 +1722,7 @@ function IconCraftView({
|
|
|
1709
1722
|
${iconContent2}
|
|
1710
1723
|
</svg>
|
|
1711
1724
|
</g>`;
|
|
1712
|
-
svg2 = svg2.replace(/<g filter="none"
|
|
1725
|
+
svg2 = svg2.replace(/<g filter="none"[^>]*>[\s\S]*?<\/g>\s*<\/svg>$/, `${newIconSvg}
|
|
1713
1726
|
</svg>`);
|
|
1714
1727
|
}
|
|
1715
1728
|
}
|
|
@@ -1717,7 +1730,7 @@ function IconCraftView({
|
|
|
1717
1730
|
}
|
|
1718
1731
|
if (iconStyle === "emboss" && instance.embossSvg) {
|
|
1719
1732
|
let svg2 = instance.embossSvg;
|
|
1720
|
-
const modes = ["wax", "jelly", "
|
|
1733
|
+
const modes = ["wax", "jelly", "bubble", "sticker"];
|
|
1721
1734
|
for (const m of modes) {
|
|
1722
1735
|
svg2 = svg2.replace(
|
|
1723
1736
|
new RegExp(`id="${m}-`, "g"),
|
|
@@ -1728,14 +1741,6 @@ function IconCraftView({
|
|
|
1728
1741
|
`url(#${instanceId}-${m}-`
|
|
1729
1742
|
);
|
|
1730
1743
|
}
|
|
1731
|
-
const rotation3 = instance.config.rotation;
|
|
1732
|
-
if (rotation3) {
|
|
1733
|
-
const layout2 = result?.icon_layout;
|
|
1734
|
-
const iconCx = (layout2?.left_percent ?? 28) + (layout2?.width_percent ?? 44) / 2;
|
|
1735
|
-
const iconCy = (layout2?.top_percent ?? 28) + (layout2?.height_percent ?? 44) / 2;
|
|
1736
|
-
const rotateTransform = `transform="rotate(${rotation3}, ${iconCx.toFixed(2)}, ${iconCy.toFixed(2)})"`;
|
|
1737
|
-
svg2 = svg2.replace(/<g filter="none">/, `<g filter="none" ${rotateTransform}>`);
|
|
1738
|
-
}
|
|
1739
1744
|
return svg2;
|
|
1740
1745
|
}
|
|
1741
1746
|
if (!result || !result.svg_paths?.clip) return "";
|
|
@@ -1766,7 +1771,8 @@ function IconCraftView({
|
|
|
1766
1771
|
}
|
|
1767
1772
|
const clipPath = result.svg_paths.clip;
|
|
1768
1773
|
const highlightPath = result.svg_paths.highlight;
|
|
1769
|
-
const
|
|
1774
|
+
const isSticker = mode === "sticker";
|
|
1775
|
+
const isJellyOrBubble = mode === "jelly" || mode === "bubble" || isSticker;
|
|
1770
1776
|
const gradientId = `${instanceId}-bg-grad`;
|
|
1771
1777
|
const clipId = `${instanceId}-clip`;
|
|
1772
1778
|
const viewBoxMatch = svgContent.match(/viewBox="([^"]*)"/);
|
|
@@ -1779,28 +1785,28 @@ function IconCraftView({
|
|
|
1779
1785
|
innerSvg = innerSvg.replace(/stroke="[^"]*"/g, "");
|
|
1780
1786
|
innerSvg = innerSvg.replace(/stroke-width="[^"]*"/g, "");
|
|
1781
1787
|
}
|
|
1782
|
-
const bgGradient =
|
|
1788
|
+
const bgGradient = isJellyOrBubble ? `<linearGradient id="${gradientId}" gradientUnits="userSpaceOnUse" x1="0" y1="0" x2="100" y2="100">
|
|
1783
1789
|
<stop offset="0%" stop-color="${color}" stop-opacity="0.35"/>
|
|
1784
1790
|
<stop offset="50%" stop-color="${color}" stop-opacity="0.4"/>
|
|
1785
1791
|
<stop offset="100%" stop-color="${color}" stop-opacity="0.5"/>
|
|
1786
1792
|
</linearGradient>
|
|
1787
|
-
|
|
1793
|
+
${isSticker ? "" : `<linearGradient id="${instanceId}-top-highlight" gradientUnits="userSpaceOnUse" x1="50" y1="0" x2="50" y2="100">
|
|
1788
1794
|
<stop offset="0%" stop-color="#fff" stop-opacity="0.6"/>
|
|
1789
1795
|
<stop offset="30%" stop-color="#fff" stop-opacity="0.3"/>
|
|
1790
1796
|
<stop offset="60%" stop-color="#fff" stop-opacity="0.1"/>
|
|
1791
1797
|
<stop offset="100%" stop-color="#fff" stop-opacity="0"/>
|
|
1792
1798
|
</linearGradient>
|
|
1793
|
-
<linearGradient id="${instanceId}-bottom-shadow" x1="50
|
|
1799
|
+
<linearGradient id="${instanceId}-bottom-shadow" gradientUnits="userSpaceOnUse" x1="50" y1="0" x2="50" y2="100">
|
|
1794
1800
|
<stop offset="0%" stop-color="#000" stop-opacity="0"/>
|
|
1795
1801
|
<stop offset="40%" stop-color="#000" stop-opacity="0.05"/>
|
|
1796
1802
|
<stop offset="70%" stop-color="#000" stop-opacity="0.15"/>
|
|
1797
1803
|
<stop offset="100%" stop-color="#000" stop-opacity="0.3"/>
|
|
1798
1804
|
</linearGradient>
|
|
1799
|
-
<linearGradient id="${instanceId}-edge-highlight" x1="0
|
|
1805
|
+
<linearGradient id="${instanceId}-edge-highlight" gradientUnits="userSpaceOnUse" x1="0" y1="0" x2="100" y2="100">
|
|
1800
1806
|
<stop offset="0%" stop-color="#fff" stop-opacity="0.85"/>
|
|
1801
1807
|
<stop offset="50%" stop-color="#fff" stop-opacity="0.5"/>
|
|
1802
1808
|
<stop offset="100%" stop-color="#fff" stop-opacity="0"/>
|
|
1803
|
-
</linearGradient>` : `<linearGradient id="${gradientId}" x1="0%" y1="0%" x2="100%" y2="100%"${gradTransform}>
|
|
1809
|
+
</linearGradient>`}` : `<linearGradient id="${gradientId}" x1="0%" y1="0%" x2="100%" y2="100%"${gradTransform}>
|
|
1804
1810
|
<stop offset="0%" stop-color="${color}"/>
|
|
1805
1811
|
<stop offset="100%" stop-color="${color}"/>
|
|
1806
1812
|
</linearGradient>
|
|
@@ -1814,7 +1820,7 @@ function IconCraftView({
|
|
|
1814
1820
|
<stop offset="60%" stop-color="#000" stop-opacity="0.1"/>
|
|
1815
1821
|
<stop offset="100%" stop-color="#000" stop-opacity="0.25"/>
|
|
1816
1822
|
</linearGradient>`;
|
|
1817
|
-
const shapeContent =
|
|
1823
|
+
const shapeContent = isJellyOrBubble ? isSticker ? `<path d="${clipPath}" fill="url(#${gradientId})"/>` : `<path d="${clipPath}" fill="url(#${gradientId})"/>
|
|
1818
1824
|
<path d="${clipPath}" fill="url(#${instanceId}-top-highlight)"/>
|
|
1819
1825
|
<path d="${clipPath}" fill="url(#${instanceId}-bottom-shadow)"/>
|
|
1820
1826
|
${highlightPath ? `<path d="${highlightPath}" fill="url(#${instanceId}-edge-highlight)"/>` : ""}` : `<path d="${clipPath}" fill="url(#${gradientId})"/>
|
|
@@ -1871,6 +1877,9 @@ function IconCraftView({
|
|
|
1871
1877
|
...style
|
|
1872
1878
|
};
|
|
1873
1879
|
const cssVars = {};
|
|
1880
|
+
if (dialColorProp) cssVars["--iconcraft-dial-color"] = dialColorProp;
|
|
1881
|
+
if (notchColorProp) cssVars["--iconcraft-notch-color"] = notchColorProp;
|
|
1882
|
+
if (reticleColorProp) cssVars["--iconcraft-reticle-color"] = reticleColorProp;
|
|
1874
1883
|
if (target === "shape") {
|
|
1875
1884
|
cssVars["--iconcraft-shape-animation"] = animStyle;
|
|
1876
1885
|
cssVars["--iconcraft-icon-animation"] = "none";
|
|
@@ -2000,7 +2009,7 @@ function IconCraftView({
|
|
|
2000
2009
|
rx: reticleSize * 0.5,
|
|
2001
2010
|
ry: reticleSize * 0.15,
|
|
2002
2011
|
fill: "none",
|
|
2003
|
-
stroke: "var(--iconcraft-
|
|
2012
|
+
stroke: "var(--iconcraft-reticle-color, #000)",
|
|
2004
2013
|
strokeWidth: "1",
|
|
2005
2014
|
strokeDasharray: "3 2"
|
|
2006
2015
|
}
|
|
@@ -2013,7 +2022,7 @@ function IconCraftView({
|
|
|
2013
2022
|
rx: reticleSize * 0.15,
|
|
2014
2023
|
ry: reticleSize * 0.5,
|
|
2015
2024
|
fill: "none",
|
|
2016
|
-
stroke: "var(--iconcraft-
|
|
2025
|
+
stroke: "var(--iconcraft-reticle-color, #000)",
|
|
2017
2026
|
strokeWidth: "1",
|
|
2018
2027
|
strokeDasharray: "3 2"
|
|
2019
2028
|
}
|
|
@@ -2059,7 +2068,7 @@ function IconCraftView({
|
|
|
2059
2068
|
rx: reticleSize * 0.5,
|
|
2060
2069
|
ry: reticleSize * 0.3,
|
|
2061
2070
|
fill: "none",
|
|
2062
|
-
stroke: "var(--iconcraft-
|
|
2071
|
+
stroke: "var(--iconcraft-reticle-color, #000)",
|
|
2063
2072
|
strokeWidth: "1.2",
|
|
2064
2073
|
transform: `rotate(45, ${dialCenter}, ${dialCenter})`
|
|
2065
2074
|
}
|
|
@@ -2070,7 +2079,7 @@ function IconCraftView({
|
|
|
2070
2079
|
cx: dialCenter,
|
|
2071
2080
|
cy: dialCenter,
|
|
2072
2081
|
r: "2",
|
|
2073
|
-
fill: "var(--iconcraft-
|
|
2082
|
+
fill: "var(--iconcraft-reticle-color, #000)"
|
|
2074
2083
|
}
|
|
2075
2084
|
)
|
|
2076
2085
|
] })
|
|
@@ -2098,22 +2107,33 @@ function IconCraftView({
|
|
|
2098
2107
|
cy: dialCenter,
|
|
2099
2108
|
r: ringRadius,
|
|
2100
2109
|
fill: "none",
|
|
2101
|
-
stroke: "var(--iconcraft-dial-color, #
|
|
2110
|
+
stroke: "var(--iconcraft-dial-color, #000)",
|
|
2102
2111
|
strokeWidth: "2",
|
|
2103
2112
|
strokeDasharray: "6 4",
|
|
2104
2113
|
opacity: 0.7
|
|
2105
2114
|
}
|
|
2106
2115
|
),
|
|
2116
|
+
/* @__PURE__ */ jsx2("style", { children: `
|
|
2117
|
+
.iconcraft-notch {
|
|
2118
|
+
transition: r 0.15s ease, filter 0.15s ease;
|
|
2119
|
+
filter: none;
|
|
2120
|
+
}
|
|
2121
|
+
.iconcraft-notch:hover {
|
|
2122
|
+
r: 9;
|
|
2123
|
+
filter: drop-shadow(0 0 3px rgba(0,0,0,0.4));
|
|
2124
|
+
}
|
|
2125
|
+
` }),
|
|
2107
2126
|
renderNotch ? renderNotch({ x: notchX, y: notchY, degrees: dialDegValue, onMouseDown: handleNotchMouseDown }) : /* @__PURE__ */ jsx2(
|
|
2108
2127
|
"circle",
|
|
2109
2128
|
{
|
|
2129
|
+
className: "iconcraft-notch",
|
|
2110
2130
|
cx: notchX,
|
|
2111
2131
|
cy: notchY,
|
|
2112
|
-
r:
|
|
2113
|
-
fill: "var(--iconcraft-
|
|
2132
|
+
r: 7,
|
|
2133
|
+
fill: "var(--iconcraft-notch-color, #000)",
|
|
2114
2134
|
stroke: "#fff",
|
|
2115
2135
|
strokeWidth: "2",
|
|
2116
|
-
style: { pointerEvents: "auto", cursor:
|
|
2136
|
+
style: { pointerEvents: "auto", cursor: ROTATE_CURSOR },
|
|
2117
2137
|
onMouseDown: handleNotchMouseDown
|
|
2118
2138
|
}
|
|
2119
2139
|
),
|
|
@@ -2129,7 +2149,7 @@ function IconCraftView({
|
|
|
2129
2149
|
y: labelY,
|
|
2130
2150
|
textAnchor: "middle",
|
|
2131
2151
|
dominantBaseline: "central",
|
|
2132
|
-
fill: "var(--iconcraft-dial-color, #
|
|
2152
|
+
fill: "var(--iconcraft-dial-color, #000)",
|
|
2133
2153
|
fontSize: "11",
|
|
2134
2154
|
fontWeight: "600",
|
|
2135
2155
|
fontFamily: "system-ui, sans-serif",
|
|
@@ -2250,7 +2270,8 @@ async function initWasm() {
|
|
|
2250
2270
|
}
|
|
2251
2271
|
var shapeModeMap2 = {
|
|
2252
2272
|
jelly: 0,
|
|
2253
|
-
|
|
2273
|
+
bubble: 1,
|
|
2274
|
+
sticker: 3,
|
|
2254
2275
|
wax: 2
|
|
2255
2276
|
};
|
|
2256
2277
|
function isUrl(str) {
|
|
@@ -2466,7 +2487,8 @@ async function initWasm2() {
|
|
|
2466
2487
|
}
|
|
2467
2488
|
var shapeModeMap3 = {
|
|
2468
2489
|
jelly: 0,
|
|
2469
|
-
|
|
2490
|
+
bubble: 1,
|
|
2491
|
+
sticker: 3,
|
|
2470
2492
|
wax: 2
|
|
2471
2493
|
};
|
|
2472
2494
|
function isUrl2(str) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gospelo-iconcraft-react",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.5",
|
|
4
4
|
"description": "IconCraft React components - 3D decorative icon shapes from SVG",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "gorosun <goro-hayakawa@no-studio.net>",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"react-dom": ">=18.0.0"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"gospelo-iconcraft-wasm": "
|
|
35
|
+
"gospelo-iconcraft-wasm": "workspace:*",
|
|
36
36
|
"ulid": "^3.0.2"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|