@alekstar79/context-menu 2.0.0
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/LICENSE +21 -0
- package/README.md +284 -0
- package/lib/components/ContextMenu.vue.d.ts +31 -0
- package/lib/context-menu-vue.d.ts +2 -0
- package/lib/context-menu-vue.js +74 -0
- package/lib/context-menu-vue.js.map +1 -0
- package/lib/context-menu.d.ts +2 -0
- package/lib/context-menu.js +709 -0
- package/lib/context-menu.js.map +1 -0
- package/lib/core/animate.d.ts +4 -0
- package/lib/core/easing.d.ts +5 -0
- package/lib/core/index.d.ts +6 -0
- package/lib/core/matrix.d.ts +62 -0
- package/lib/core/parse.d.ts +2 -0
- package/lib/core/svg.d.ts +54 -0
- package/lib/core/transform.d.ts +5 -0
- package/lib/index.d.ts +2 -0
- package/lib/menu/builder.d.ts +37 -0
- package/lib/menu/config.d.ts +39 -0
- package/lib/menu/manager.d.ts +9 -0
- package/lib/styles.css +1 -0
- package/lib/styles.d.ts +1 -0
- package/lib/utils/text-metrics.d.ts +17 -0
- package/lib/vue.d.ts +3 -0
- package/package.json +72 -0
|
@@ -0,0 +1,709 @@
|
|
|
1
|
+
const I = {
|
|
2
|
+
sectors: [],
|
|
3
|
+
sprite: "../icons.svg",
|
|
4
|
+
innerRadius: 50,
|
|
5
|
+
outerRadius: 150,
|
|
6
|
+
opacity: 0.7
|
|
7
|
+
};
|
|
8
|
+
function J(o) {
|
|
9
|
+
return { ...I, ...o };
|
|
10
|
+
}
|
|
11
|
+
const A = /* @__PURE__ */ new Map();
|
|
12
|
+
function H(o) {
|
|
13
|
+
if (A.has(o))
|
|
14
|
+
return A.get(o);
|
|
15
|
+
const e = document.createElement("canvas").getContext("2d");
|
|
16
|
+
if (!e) {
|
|
17
|
+
const c = { ascent: 9, descent: 3, height: 12 };
|
|
18
|
+
return A.set(o, c), c;
|
|
19
|
+
}
|
|
20
|
+
e.font = o;
|
|
21
|
+
const s = e.measureText("A"), i = s.actualBoundingBoxAscent ?? 9, n = s.actualBoundingBoxDescent ?? 3, r = i + n, a = { ascent: i, descent: n, height: r };
|
|
22
|
+
return A.set(o, a), a;
|
|
23
|
+
}
|
|
24
|
+
let R = null;
|
|
25
|
+
function N() {
|
|
26
|
+
if (R) return R;
|
|
27
|
+
const o = document.createElement("div");
|
|
28
|
+
o.className = "radial-hint", o.style.position = "absolute", o.style.visibility = "hidden", o.style.pointerEvents = "none", o.textContent = "A", document.body.appendChild(o);
|
|
29
|
+
const t = window.getComputedStyle(o), e = `${t.fontWeight} ${t.fontSize} ${t.fontFamily}`;
|
|
30
|
+
document.body.removeChild(o);
|
|
31
|
+
const s = H(e);
|
|
32
|
+
return R = s, s;
|
|
33
|
+
}
|
|
34
|
+
function q(o) {
|
|
35
|
+
const t = "http://www.w3.org/2000/svg", e = document.createElementNS(t, "svg");
|
|
36
|
+
e.style.position = "absolute", e.style.visibility = "hidden", document.body.appendChild(e);
|
|
37
|
+
const s = document.createElementNS(t, "text");
|
|
38
|
+
s.textContent = o, e.appendChild(s);
|
|
39
|
+
const i = s.getComputedTextLength();
|
|
40
|
+
return document.body.removeChild(e), i;
|
|
41
|
+
}
|
|
42
|
+
const D = (o) => o % 360 * Math.PI / 180, T = /,?([a-z]),?/gi;
|
|
43
|
+
function O() {
|
|
44
|
+
return this.join(",").replace(T, "$1");
|
|
45
|
+
}
|
|
46
|
+
const z = (o) => {
|
|
47
|
+
if (!o) return null;
|
|
48
|
+
let t = [];
|
|
49
|
+
return Array.isArray(o) && Array.isArray(o[0]) && (t = o.map((e) => [...e])), t.length || String(o).replace(/([rstm])\s*,?\s*((-?\d*\.?\d*(?:e[\-+]?\d+)?\s*,?\s*)+)/ig, (e, s, i) => {
|
|
50
|
+
const n = [];
|
|
51
|
+
return i.replace(/(-?\d*\.?\d*(?:e[\-+]?\d+)?)\s*,?\s*/ig, (r, a) => (a && n.push(+a), "")), t.push([s, ...n]), "";
|
|
52
|
+
}), t.toString = O, t;
|
|
53
|
+
}, _ = (o) => {
|
|
54
|
+
const t = z(o), e = new C();
|
|
55
|
+
if (t)
|
|
56
|
+
for (let s = 0, i = t.length; s < i; s++) {
|
|
57
|
+
const n = t[s];
|
|
58
|
+
switch (n[0].toLowerCase()) {
|
|
59
|
+
case "t":
|
|
60
|
+
e.translate(n[1], n[2] || 0);
|
|
61
|
+
break;
|
|
62
|
+
case "r":
|
|
63
|
+
e.rotate(n[1], n[2] || 0, n[3] || 0);
|
|
64
|
+
break;
|
|
65
|
+
case "s":
|
|
66
|
+
e.scale(n[1] || 1, n[2] || n[1] || 1, n[3] || 0, n[4] || 0);
|
|
67
|
+
break;
|
|
68
|
+
case "m":
|
|
69
|
+
e.add(n[1] || 1, n[2] || 0, n[3] || 0, n[4] || 1, n[5] || 0, n[6] || 0);
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return e;
|
|
74
|
+
}, G = { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 };
|
|
75
|
+
class C {
|
|
76
|
+
a;
|
|
77
|
+
b;
|
|
78
|
+
c;
|
|
79
|
+
d;
|
|
80
|
+
e;
|
|
81
|
+
f;
|
|
82
|
+
/**
|
|
83
|
+
* Creates a new matrix.
|
|
84
|
+
* If no arguments are given, creates an identity matrix.
|
|
85
|
+
* If an object with a,b,c,d,e,f properties is provided (e.g., SVGMatrix), copies its values.
|
|
86
|
+
*/
|
|
87
|
+
constructor(t, e, s, i, n, r) {
|
|
88
|
+
if (t instanceof SVGMatrix) {
|
|
89
|
+
Object.assign(this, t);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
t != null ? Object.assign(this, { a: +t, b: +e, c: +s, d: +i, e: +n, f: +r }) : Object.assign(this, G);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Multiplies current matrix by another matrix.
|
|
96
|
+
*/
|
|
97
|
+
add(t, e, s, i, n, r) {
|
|
98
|
+
if (t instanceof C)
|
|
99
|
+
return this.add(t.a, t.b, t.c, t.d, t.e, t.f);
|
|
100
|
+
const a = t * this.a + e * this.c, c = t * this.b + e * this.d;
|
|
101
|
+
return this.e += n * this.a + r * this.c, this.f += n * this.b + r * this.d, this.c = s * this.a + i * this.c, this.d = s * this.b + i * this.d, this.a = a, this.b = c, this;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Returns inverse matrix.
|
|
105
|
+
*/
|
|
106
|
+
invert() {
|
|
107
|
+
const t = this.a * this.d - this.b * this.c;
|
|
108
|
+
return new C(
|
|
109
|
+
this.d / t,
|
|
110
|
+
-this.b / t,
|
|
111
|
+
-this.c / t,
|
|
112
|
+
this.a / t,
|
|
113
|
+
(this.c * this.f - this.d * this.e) / t,
|
|
114
|
+
(this.b * this.e - this.a * this.f) / t
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Returns a copy of the matrix.
|
|
119
|
+
*/
|
|
120
|
+
clone() {
|
|
121
|
+
return new C(this.a, this.b, this.c, this.d, this.e, this.f);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Translates the matrix by x and y.
|
|
125
|
+
*/
|
|
126
|
+
translate(t, e = 0) {
|
|
127
|
+
return this.add(1, 0, 0, 1, t, e);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Scales the matrix by x and y, optionally about point (cx, cy).
|
|
131
|
+
*/
|
|
132
|
+
scale(t, e = t, s, i) {
|
|
133
|
+
return (s != null || i != null) && this.translate(s, i), this.a *= t, this.b *= t, this.c *= e, this.d *= e, (s != null || i != null) && this.translate(-s, -i), this;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Rotates the matrix by angle (degrees) about point (x, y).
|
|
137
|
+
*/
|
|
138
|
+
rotate(t, e = 0, s = 0) {
|
|
139
|
+
t = D(t);
|
|
140
|
+
const i = +Math.cos(t).toFixed(9), n = +Math.sin(t).toFixed(9);
|
|
141
|
+
return this.add(i, n, -n, i, e, s), this.add(1, 0, 0, 1, -e, -s);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Applies matrix to point (x, y) and returns resulting x.
|
|
145
|
+
*/
|
|
146
|
+
x(t, e) {
|
|
147
|
+
return t * this.a + e * this.c + this.e;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Applies matrix to point (x, y) and returns resulting y.
|
|
151
|
+
*/
|
|
152
|
+
y(t, e) {
|
|
153
|
+
return t * this.b + e * this.d + this.f;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Returns matrix as an SVG matrix string.
|
|
157
|
+
*/
|
|
158
|
+
toString() {
|
|
159
|
+
return `matrix(${this.a},${this.b},${this.c},${this.d},${this.e},${this.f})`;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
const b = {
|
|
163
|
+
linear: (o) => o,
|
|
164
|
+
easeinout: (o) => {
|
|
165
|
+
if (o === 1) return 1;
|
|
166
|
+
if (o === 0) return 0;
|
|
167
|
+
const t = 0.48 - o / 1.04, e = Math.sqrt(0.1734 + t * t), s = e - t, i = Math.pow(Math.abs(s), 1 / 3) * (s < 0 ? -1 : 1), n = -e - t, r = Math.pow(Math.abs(n), 1 / 3) * (n < 0 ? -1 : 1), a = i + r + 0.5;
|
|
168
|
+
return (1 - a) * 3 * a * a + a * a * a;
|
|
169
|
+
},
|
|
170
|
+
elastic: (o) => o === 0 || o === 1 ? o : Math.pow(2, -10 * o) * Math.sin((o - 0.075) * (2 * Math.PI) / 0.3) + 1
|
|
171
|
+
};
|
|
172
|
+
function P(o, t, e, s, i = b.linear, n) {
|
|
173
|
+
const r = performance.now();
|
|
174
|
+
let a = !1, c = 0;
|
|
175
|
+
const l = (h) => {
|
|
176
|
+
if (a) return;
|
|
177
|
+
const p = h - r, u = Math.min(p / s, 1), d = i(u);
|
|
178
|
+
if (Array.isArray(o) && Array.isArray(t)) {
|
|
179
|
+
const m = o.map((y, w) => y + (t[w] - y) * d);
|
|
180
|
+
e(m);
|
|
181
|
+
} else {
|
|
182
|
+
const m = o + (t - o) * d;
|
|
183
|
+
e(m);
|
|
184
|
+
}
|
|
185
|
+
u < 1 ? c = requestAnimationFrame(l) : n?.();
|
|
186
|
+
};
|
|
187
|
+
return c = requestAnimationFrame(l), {
|
|
188
|
+
stop: () => {
|
|
189
|
+
a = !0, cancelAnimationFrame(c);
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
let W = 0;
|
|
194
|
+
const $ = /* @__PURE__ */ new WeakMap();
|
|
195
|
+
function x(o, t) {
|
|
196
|
+
if ($.has(o)) {
|
|
197
|
+
const s = $.get(o);
|
|
198
|
+
return t && !s.paper && (s.paper = t), s;
|
|
199
|
+
}
|
|
200
|
+
const e = new B(o, t);
|
|
201
|
+
return $.set(o, e), e;
|
|
202
|
+
}
|
|
203
|
+
class B {
|
|
204
|
+
node;
|
|
205
|
+
paper;
|
|
206
|
+
_id;
|
|
207
|
+
constructor(t, e) {
|
|
208
|
+
this.node = t, this.paper = e, this._id = "e" + (W++).toString(36);
|
|
209
|
+
}
|
|
210
|
+
get type() {
|
|
211
|
+
return this.node.tagName;
|
|
212
|
+
}
|
|
213
|
+
get id() {
|
|
214
|
+
return this.node.id || this._id;
|
|
215
|
+
}
|
|
216
|
+
parent() {
|
|
217
|
+
return this.node.parentNode ? x(this.node.parentNode, this.paper) : null;
|
|
218
|
+
}
|
|
219
|
+
children() {
|
|
220
|
+
return Array.from(this.node.children).map((t) => x(t, this.paper));
|
|
221
|
+
}
|
|
222
|
+
clear() {
|
|
223
|
+
for (; this.node.firstChild; )
|
|
224
|
+
this.node.removeChild(this.node.firstChild);
|
|
225
|
+
return this;
|
|
226
|
+
}
|
|
227
|
+
attr(t, e) {
|
|
228
|
+
if (typeof t == "string")
|
|
229
|
+
return e === void 0 ? this.node.getAttribute(t) : (this._setAttr(t, e), this);
|
|
230
|
+
if (typeof t == "object") {
|
|
231
|
+
for (const s in t)
|
|
232
|
+
this._setAttr(s, t[s]);
|
|
233
|
+
return this;
|
|
234
|
+
}
|
|
235
|
+
return this;
|
|
236
|
+
}
|
|
237
|
+
_setAttr(t, e) {
|
|
238
|
+
t === "textpath" ? this._setTextPath(e) : t === "text" ? this._setText(e) : this.node.setAttribute(t, String(e));
|
|
239
|
+
}
|
|
240
|
+
_setText(t) {
|
|
241
|
+
const e = this.node.querySelector("textPath");
|
|
242
|
+
e ? e.textContent = t : this.node.textContent = t;
|
|
243
|
+
}
|
|
244
|
+
_setTextPath(t) {
|
|
245
|
+
if (this.node.tagName !== "text") return;
|
|
246
|
+
const e = this.node;
|
|
247
|
+
let s = e.querySelector("textPath"), i = "";
|
|
248
|
+
if (s)
|
|
249
|
+
i = s.textContent || "";
|
|
250
|
+
else {
|
|
251
|
+
for (let r = 0; r < e.childNodes.length; r++) {
|
|
252
|
+
const a = e.childNodes[r];
|
|
253
|
+
a.nodeType === 3 && (i += a.textContent);
|
|
254
|
+
}
|
|
255
|
+
for (; e.firstChild; )
|
|
256
|
+
e.removeChild(e.firstChild);
|
|
257
|
+
s = document.createElementNS("http://www.w3.org/2000/svg", "textPath"), e.appendChild(s), e.removeAttribute("x"), e.removeAttribute("y");
|
|
258
|
+
}
|
|
259
|
+
let n;
|
|
260
|
+
if (t.startsWith("#"))
|
|
261
|
+
n = t;
|
|
262
|
+
else {
|
|
263
|
+
if (!this.paper)
|
|
264
|
+
throw new Error("No paper reference for creating defs");
|
|
265
|
+
const r = this.paper.defs, a = "p" + Date.now() + Math.random().toString(36).slice(2), c = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
|
266
|
+
c.setAttribute("d", t), c.id = a, r.node.appendChild(c), n = "#" + a;
|
|
267
|
+
}
|
|
268
|
+
s.setAttributeNS("http://www.w3.org/1999/xlink", "href", n), i && (s.textContent = i);
|
|
269
|
+
}
|
|
270
|
+
addClass(t) {
|
|
271
|
+
const e = t.trim().split(/\s+/);
|
|
272
|
+
for (const s of e)
|
|
273
|
+
s && this.node.classList.add(s);
|
|
274
|
+
return this;
|
|
275
|
+
}
|
|
276
|
+
removeClass(t) {
|
|
277
|
+
const e = t.trim().split(/\s+/);
|
|
278
|
+
for (const s of e)
|
|
279
|
+
s && this.node.classList.remove(s);
|
|
280
|
+
return this;
|
|
281
|
+
}
|
|
282
|
+
transform(t) {
|
|
283
|
+
if (t === void 0) return this;
|
|
284
|
+
if (t instanceof C)
|
|
285
|
+
this.node.setAttribute("transform", t.toString());
|
|
286
|
+
else {
|
|
287
|
+
const e = _(t);
|
|
288
|
+
this.node.setAttribute("transform", e.toString());
|
|
289
|
+
}
|
|
290
|
+
return this;
|
|
291
|
+
}
|
|
292
|
+
getBBox() {
|
|
293
|
+
if (this.node.isConnected) {
|
|
294
|
+
const i = this.node.getBBox();
|
|
295
|
+
return {
|
|
296
|
+
x: i.x,
|
|
297
|
+
y: i.y,
|
|
298
|
+
width: i.width,
|
|
299
|
+
height: i.height,
|
|
300
|
+
cx: i.x + i.width / 2,
|
|
301
|
+
cy: i.y + i.height / 2,
|
|
302
|
+
x2: i.x + i.width,
|
|
303
|
+
y2: i.y + i.height
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
const e = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
307
|
+
e.style.position = "absolute", e.style.visibility = "hidden", e.style.pointerEvents = "none", document.body.appendChild(e), e.appendChild(this.node);
|
|
308
|
+
const s = this.node.getBBox();
|
|
309
|
+
return e.removeChild(this.node), document.body.removeChild(e), {
|
|
310
|
+
x: s.x,
|
|
311
|
+
y: s.y,
|
|
312
|
+
width: s.width,
|
|
313
|
+
height: s.height,
|
|
314
|
+
cx: s.x + s.width / 2,
|
|
315
|
+
cy: s.y + s.height / 2,
|
|
316
|
+
x2: s.x + s.width,
|
|
317
|
+
y2: s.y + s.height
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
select(t) {
|
|
321
|
+
const e = this.node.querySelector(t);
|
|
322
|
+
return e ? x(e, this.paper) : null;
|
|
323
|
+
}
|
|
324
|
+
selectAll(t) {
|
|
325
|
+
const e = this.node.querySelectorAll(t);
|
|
326
|
+
return Array.from(e).map((s) => x(s, this.paper));
|
|
327
|
+
}
|
|
328
|
+
clone() {
|
|
329
|
+
return x(this.node.cloneNode(!0), this.paper);
|
|
330
|
+
}
|
|
331
|
+
add(t) {
|
|
332
|
+
return this.node.appendChild(t.node), this;
|
|
333
|
+
}
|
|
334
|
+
hover(t, e) {
|
|
335
|
+
return this.node.addEventListener("mouseover", t), this.node.addEventListener("mouseout", e), this;
|
|
336
|
+
}
|
|
337
|
+
mouseup(t) {
|
|
338
|
+
return this.node.addEventListener("mouseup", t), this;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
class k extends B {
|
|
342
|
+
defs;
|
|
343
|
+
constructor(t) {
|
|
344
|
+
super(t, null), this.paper = this, $.set(t, this);
|
|
345
|
+
let e = t.querySelector("defs");
|
|
346
|
+
e || (e = document.createElementNS("http://www.w3.org/2000/svg", "defs"), t.appendChild(e)), this.defs = x(e, this);
|
|
347
|
+
}
|
|
348
|
+
g(...t) {
|
|
349
|
+
const e = document.createElementNS("http://www.w3.org/2000/svg", "g");
|
|
350
|
+
this.node.appendChild(e);
|
|
351
|
+
const s = x(e, this);
|
|
352
|
+
return t.length === 1 && t[0] && !t[0].node ? s.attr(t[0]) : t.length && t.forEach((i) => {
|
|
353
|
+
i instanceof B && s.add(i);
|
|
354
|
+
}), s;
|
|
355
|
+
}
|
|
356
|
+
path(t) {
|
|
357
|
+
const e = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
|
358
|
+
this.node.appendChild(e);
|
|
359
|
+
const s = x(e, this);
|
|
360
|
+
return t && (typeof t == "string" ? s.attr("d", t) : s.attr(t)), s;
|
|
361
|
+
}
|
|
362
|
+
circle(t, e, s) {
|
|
363
|
+
const i = document.createElementNS("http://www.w3.org/2000/svg", "circle");
|
|
364
|
+
this.node.appendChild(i);
|
|
365
|
+
const n = x(i, this);
|
|
366
|
+
return typeof t == "object" ? n.attr(t) : t != null && n.attr({ cx: t, cy: e ?? t, r: s ?? 0 }), n;
|
|
367
|
+
}
|
|
368
|
+
text(t, e, s) {
|
|
369
|
+
const i = document.createElementNS("http://www.w3.org/2000/svg", "text");
|
|
370
|
+
this.node.appendChild(i);
|
|
371
|
+
const n = x(i, this);
|
|
372
|
+
return typeof t == "object" ? n.attr(t) : t != null && n.attr({ x: t, y: e ?? t, text: s ?? "" }), n;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
class Y {
|
|
376
|
+
frag;
|
|
377
|
+
constructor(t) {
|
|
378
|
+
this.frag = t;
|
|
379
|
+
}
|
|
380
|
+
select(t) {
|
|
381
|
+
const e = this.frag.querySelector(t);
|
|
382
|
+
return e ? x(e) : null;
|
|
383
|
+
}
|
|
384
|
+
selectAll(t) {
|
|
385
|
+
const e = this.frag.querySelectorAll(t);
|
|
386
|
+
return Array.from(e).map((s) => x(s));
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
function j(o) {
|
|
390
|
+
if (typeof o == "string") {
|
|
391
|
+
const t = document.querySelector(o);
|
|
392
|
+
return t ? new k(t) : null;
|
|
393
|
+
}
|
|
394
|
+
return o instanceof SVGSVGElement ? new k(o) : null;
|
|
395
|
+
}
|
|
396
|
+
function V(o) {
|
|
397
|
+
const t = document.createElement("div");
|
|
398
|
+
let e = o.trim();
|
|
399
|
+
e.match(/^\s*<\s*svg/i) || (e = "<svg>" + e + "</svg>"), t.innerHTML = e;
|
|
400
|
+
const s = t.querySelector("svg"), i = document.createDocumentFragment();
|
|
401
|
+
if (s)
|
|
402
|
+
for (; s.firstChild; )
|
|
403
|
+
i.appendChild(s.firstChild);
|
|
404
|
+
return new Y(i);
|
|
405
|
+
}
|
|
406
|
+
const X = (o, t, e) => o > e ? e : o < t ? t : o, L = /* @__PURE__ */ new WeakMap(), E = /* @__PURE__ */ new WeakMap();
|
|
407
|
+
function M(o, t, e, s) {
|
|
408
|
+
return s = (s - 90) * Math.PI / 180, {
|
|
409
|
+
x: o + e * Math.cos(s),
|
|
410
|
+
y: t + e * Math.sin(s)
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
function S(o, t, e, s, i, n, r) {
|
|
414
|
+
const a = M(o, t, e, s %= 360), c = M(o, t, e, i %= 360);
|
|
415
|
+
return `${n ? "L" : "M"}${a.x} ${a.y} A${e} ${e}, 0, ${i - s >= 180 ? 1 : 0}, ${r ? 0 : 1}, ${c.x} ${c.y}`;
|
|
416
|
+
}
|
|
417
|
+
function F(o, t, e, s, i, n) {
|
|
418
|
+
return `${S(o, t, e, i, n, !1, !1)} ${S(o, t, s, n, i, !0, !0)}Z`;
|
|
419
|
+
}
|
|
420
|
+
class Q {
|
|
421
|
+
config;
|
|
422
|
+
events = {};
|
|
423
|
+
container;
|
|
424
|
+
snap;
|
|
425
|
+
angle;
|
|
426
|
+
size = 500;
|
|
427
|
+
c = this.size / 2;
|
|
428
|
+
element;
|
|
429
|
+
area;
|
|
430
|
+
duration = 300;
|
|
431
|
+
icons = null;
|
|
432
|
+
theme = "light";
|
|
433
|
+
constructor(t) {
|
|
434
|
+
this.config = t, this.size = 2 * t.outerRadius, this.c = this.size / 2, this.angle = 360 / (this.config.sectors.length || 6), this.element = this.createMenuElement(), this.snap = j(this.element.querySelector("svg")), this.area = this.snap, this.container = this.area.g().transform("s0"), this.init().catch(console.error);
|
|
435
|
+
}
|
|
436
|
+
createMenuElement() {
|
|
437
|
+
const t = document.createElement("div");
|
|
438
|
+
t.className = "context theme--light hidden", t.style.position = "fixed", t.style.top = "0", t.style.left = "0", t.style.width = "100vw", t.style.height = "100vh", t.style.overflow = "visible", t.style.pointerEvents = "auto";
|
|
439
|
+
const e = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
440
|
+
return e.setAttribute("width", this.size.toString()), e.setAttribute("height", this.size.toString()), e.setAttribute("viewBox", `0 0 ${this.size} ${this.size}`), e.style.position = "absolute", e.style.display = "block", e.style.overflow = "visible", e.style.pointerEvents = "auto", e.classList.add("radial-menu-svg"), e.addEventListener("wheel", (s) => {
|
|
441
|
+
s.preventDefault(), this.transformOpacity(s);
|
|
442
|
+
}), e.addEventListener("contextmenu", (s) => {
|
|
443
|
+
s.stopPropagation(), s.preventDefault(), this.hide();
|
|
444
|
+
}), e.addEventListener("click", (s) => {
|
|
445
|
+
s.stopPropagation(), this.hide();
|
|
446
|
+
}), t.addEventListener("click", (s) => {
|
|
447
|
+
s.target === t && this.hide();
|
|
448
|
+
}), t.appendChild(e), t;
|
|
449
|
+
}
|
|
450
|
+
async init() {
|
|
451
|
+
await this.loadIcons(), this.updateButtons();
|
|
452
|
+
}
|
|
453
|
+
async loadIcons() {
|
|
454
|
+
if (!this.icons)
|
|
455
|
+
try {
|
|
456
|
+
const t = await fetch(this.config.sprite);
|
|
457
|
+
t.ok && (this.icons = V(await t.text()));
|
|
458
|
+
} catch (t) {
|
|
459
|
+
console.error("Failed to load icons:", t);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
updateButtons() {
|
|
463
|
+
if (!(!this.icons || !this.container) && (this.container.clear(), this.config.sectors.forEach((t) => {
|
|
464
|
+
const e = this.createIcon(t);
|
|
465
|
+
if (e) {
|
|
466
|
+
const s = this.createButton(t, this.createSector(), e, this.createHint(t));
|
|
467
|
+
this.container.add(s);
|
|
468
|
+
}
|
|
469
|
+
}), this.config.centralButton)) {
|
|
470
|
+
const t = this.createCentralButton(this.config.centralButton);
|
|
471
|
+
t && this.container.add(t);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
createSector() {
|
|
475
|
+
const t = this.config.color ?? "#1976D2";
|
|
476
|
+
return this.area.path(F(this.c, this.c, this.config.outerRadius, this.config.innerRadius, 0, this.angle)).attr({ fill: t, stroke: t, opacity: this.config.opacity }).addClass("radial-sector");
|
|
477
|
+
}
|
|
478
|
+
createButton(t, e, s, i) {
|
|
479
|
+
const n = this.area.g(e, s, i);
|
|
480
|
+
return n.hover(
|
|
481
|
+
() => {
|
|
482
|
+
n.select(".radial-hint")?.addClass("active");
|
|
483
|
+
const r = n.select(".radial-hint-bg");
|
|
484
|
+
r && (r.addClass("active"), r.node.style.opacity = String(this.config.opacity)), this.animateButtonHover(n, 0, 1, 200, b.easeinout);
|
|
485
|
+
},
|
|
486
|
+
() => {
|
|
487
|
+
n.select(".radial-hint")?.removeClass("active");
|
|
488
|
+
const r = n.select(".radial-hint-bg");
|
|
489
|
+
r && (r.removeClass("active"), r.node.style.opacity = "0"), this.animateButtonHover(n, 1, 0, 2e3, b.elastic);
|
|
490
|
+
}
|
|
491
|
+
), n.mouseup((r) => {
|
|
492
|
+
r.button === 0 && (this.emit("click", { icon: t.icon, hint: t.hint }), t.onclick?.());
|
|
493
|
+
}), n;
|
|
494
|
+
}
|
|
495
|
+
createIcon(t) {
|
|
496
|
+
if (!this.icons) return null;
|
|
497
|
+
const e = this.icons.select(`#${t.icon}`);
|
|
498
|
+
if (!e)
|
|
499
|
+
return console.error(`Icon #${t.icon} not found in SVG`), null;
|
|
500
|
+
const s = e.clone(), i = s.getBBox(), n = (this.config.innerRadius + this.config.outerRadius) / 2, a = (this.config.outerRadius - this.config.innerRadius) * 0.5 / i.height, c = t.iconRadius ?? this.config.iconRadius ?? n, l = t.iconScale ?? this.config.iconScale ?? a, h = this.angle / 2, p = h + (t.rotate || 0);
|
|
501
|
+
E.set(s, { midRadius: c, scale: l, rotation: p, bbox: i });
|
|
502
|
+
const u = M(this.c, this.c, c, h), d = new C();
|
|
503
|
+
return d.translate(u.x, u.y), d.scale(l), d.rotate(p, 0, 0), d.translate(-i.cx, -i.cy), s.transform(d), s.addClass("radial-icon");
|
|
504
|
+
}
|
|
505
|
+
createHint(t) {
|
|
506
|
+
const e = this.area.g();
|
|
507
|
+
e.addClass("hint-group");
|
|
508
|
+
const s = t.hintPadding ?? this.config.hintPadding, i = N(), n = t.hint || t.icon, r = q(n), a = 2;
|
|
509
|
+
let c, l = 0;
|
|
510
|
+
if (s !== void 0)
|
|
511
|
+
l = i.height + 2 * s, c = this.config.outerRadius + l / 2 + a;
|
|
512
|
+
else {
|
|
513
|
+
const v = i.height * 0.75;
|
|
514
|
+
c = this.config.outerRadius + v;
|
|
515
|
+
}
|
|
516
|
+
const p = r / c * 180 / Math.PI, u = this.angle / 2, d = u - p / 2, m = u + p / 2, y = S(this.c, this.c, c, d, m, !1, !1);
|
|
517
|
+
if (s !== void 0) {
|
|
518
|
+
const v = this.config.color ?? "#1976D2", g = this.area.path(y).attr({
|
|
519
|
+
stroke: v,
|
|
520
|
+
"stroke-width": `${l}`,
|
|
521
|
+
"stroke-linecap": "round",
|
|
522
|
+
fill: "none",
|
|
523
|
+
"vector-effect": "non-scaling-stroke"
|
|
524
|
+
}).addClass("radial-hint-bg");
|
|
525
|
+
g.node.style.opacity = "0", e.add(g);
|
|
526
|
+
}
|
|
527
|
+
const w = this.area.text(0, 0, n).addClass("radial-hint").attr({
|
|
528
|
+
fill: this.theme === "light" ? "#333333" : "#7a7a7a",
|
|
529
|
+
textpath: y
|
|
530
|
+
}), f = w.select("textPath");
|
|
531
|
+
return f && (f.attr("dominant-baseline", "central"), f.attr("startOffset", "50%")), e.add(w), L.set(e, {
|
|
532
|
+
sectorMidAngle: u,
|
|
533
|
+
baseRadius: c,
|
|
534
|
+
textLength: r
|
|
535
|
+
}), e;
|
|
536
|
+
}
|
|
537
|
+
createCentralButton(t) {
|
|
538
|
+
const e = this.config.innerRadius * 0.6, s = t.iconRadius ?? this.config.iconRadius ?? e, i = this.config.color ?? "#1976D2", n = this.area.circle({
|
|
539
|
+
cx: this.c,
|
|
540
|
+
cy: this.c,
|
|
541
|
+
r: s,
|
|
542
|
+
fill: i,
|
|
543
|
+
stroke: i,
|
|
544
|
+
opacity: this.config.opacity
|
|
545
|
+
}).addClass("radial-sector central-sector");
|
|
546
|
+
n.node.dataset.initialRadius = `${s}`;
|
|
547
|
+
let r = null, a = null;
|
|
548
|
+
t.icon && (r = this.createCentralIcon(t, s)), t.hint && (a = this.createCentralHint(t, s));
|
|
549
|
+
const c = [n, r, a].filter((h) => h !== null), l = this.area.g(...c).addClass("central-button");
|
|
550
|
+
return l.hover(
|
|
551
|
+
() => {
|
|
552
|
+
l.select(".central-hint")?.addClass("active");
|
|
553
|
+
const h = l.select(".radial-hint-bg");
|
|
554
|
+
h && (h.addClass("active"), h.node.style.opacity = String(this.config.opacity)), this.animateCentralHover(l, !0);
|
|
555
|
+
},
|
|
556
|
+
() => {
|
|
557
|
+
l.select(".central-hint")?.removeClass("active");
|
|
558
|
+
const h = l.select(".radial-hint-bg");
|
|
559
|
+
h && (h.removeClass("active"), h.node.style.opacity = "0"), this.animateCentralHover(l, !1);
|
|
560
|
+
}
|
|
561
|
+
), l.mouseup((h) => {
|
|
562
|
+
h.button === 0 && (this.emit("click", { icon: t.icon, hint: t.hint || "" }), t.onclick?.());
|
|
563
|
+
}), l;
|
|
564
|
+
}
|
|
565
|
+
createCentralIcon(t, e) {
|
|
566
|
+
if (!this.icons) return null;
|
|
567
|
+
const s = this.icons.select(`#${t.icon}`);
|
|
568
|
+
if (!s)
|
|
569
|
+
return console.error(`Icon #${t.icon} not found in SVG`), null;
|
|
570
|
+
const i = s.clone(), n = i.getBBox(), r = e * 0.8 / Math.max(n.width, n.height), a = t.iconScale ?? this.config.iconScale ?? r, c = new C();
|
|
571
|
+
return c.translate(this.c, this.c), c.scale(a), c.translate(-n.cx, -n.cy), i.transform(c).addClass("radial-icon central-icon"), E.set(i, {
|
|
572
|
+
midRadius: 0,
|
|
573
|
+
rotation: 0,
|
|
574
|
+
scale: a,
|
|
575
|
+
bbox: n
|
|
576
|
+
}), i;
|
|
577
|
+
}
|
|
578
|
+
createCentralHint(t, e) {
|
|
579
|
+
const s = this.area.g(), i = t.hintPadding ?? this.config.hintPadding, n = N(), r = t.hint ?? "";
|
|
580
|
+
let a, c = 0;
|
|
581
|
+
i !== void 0 ? (c = n.height + 2 * i, a = t.hintOffset ?? c / 2 + 2) : t.hintOffset != null ? a = t.hintOffset : a = t.hintDistance ?? 8;
|
|
582
|
+
const h = e + a;
|
|
583
|
+
let p, u, d;
|
|
584
|
+
if (t.hintStartAngle != null && t.hintEndAngle != null)
|
|
585
|
+
p = t.hintStartAngle, u = t.hintEndAngle, d = p > u;
|
|
586
|
+
else {
|
|
587
|
+
const g = (t.hintSpan ?? 120) / 2;
|
|
588
|
+
(t.hintPosition ?? "top") === "bottom" ? (p = 180 + g, u = 180 - g, d = !0) : (p = 360 - g, u = g, d = !1);
|
|
589
|
+
}
|
|
590
|
+
const m = S(this.c, this.c, h, p, u, !1, d);
|
|
591
|
+
if (i !== void 0) {
|
|
592
|
+
const v = this.config.color ?? "#1976D2", g = this.area.path(m).attr({
|
|
593
|
+
stroke: v,
|
|
594
|
+
"stroke-width": `${c}`,
|
|
595
|
+
"stroke-linecap": "round",
|
|
596
|
+
fill: "none",
|
|
597
|
+
"vector-effect": "non-scaling-stroke"
|
|
598
|
+
}).addClass("radial-hint-bg");
|
|
599
|
+
g.node.style.opacity = "0", s.add(g);
|
|
600
|
+
}
|
|
601
|
+
const y = this.area.text(0, 0, r).addClass("radial-hint central-hint").attr({
|
|
602
|
+
fill: this.theme === "light" ? "#333333" : "#7a7a7a",
|
|
603
|
+
textpath: m
|
|
604
|
+
}), w = y.select("textPath");
|
|
605
|
+
w && (w.attr("dominant-baseline", "central"), w.attr("startOffset", "50%"));
|
|
606
|
+
const f = y.node;
|
|
607
|
+
return f.dataset.hintOffset = a.toString(), f.dataset.startAngle = p.toString(), f.dataset.endAngle = u.toString(), f.dataset.alter = d ? "true" : "false", f.dataset.centerX = this.c.toString(), f.dataset.centerY = this.c.toString(), s.add(y), s;
|
|
608
|
+
}
|
|
609
|
+
show(t) {
|
|
610
|
+
this.element.classList.remove("hidden");
|
|
611
|
+
const e = this.element.querySelector("svg");
|
|
612
|
+
e.style.left = t.clientX - this.c + "px", e.style.top = t.clientY - this.c + "px", this.animateContainer(0, 1, this.duration * 8, b.elastic), this.animateButtons(0, 1, this.duration, this.duration * 8, b.elastic);
|
|
613
|
+
}
|
|
614
|
+
hide() {
|
|
615
|
+
this.animateContainer(1, 0, this.duration, b.easeinout, () => {
|
|
616
|
+
this.element.classList.add("hidden");
|
|
617
|
+
}), this.animateButtons(1, 0, this.duration, this.duration, b.easeinout);
|
|
618
|
+
}
|
|
619
|
+
animate(t, e, s, i, n, r, a, c) {
|
|
620
|
+
t.animation ||= [], t.animation[e]?.stop(), t.animation[e] = P(s, i, a, n, r, c);
|
|
621
|
+
}
|
|
622
|
+
animateContainer(t, e, s, i, n) {
|
|
623
|
+
this.animate(this, 0, t, e, s, i, (r) => {
|
|
624
|
+
this.container.transform(`r${90 - 90 * r},${this.c},${this.c}s${r},${r},${this.c},${this.c}`);
|
|
625
|
+
}, n);
|
|
626
|
+
}
|
|
627
|
+
animateButtons(t, e, s, i, n) {
|
|
628
|
+
const r = (a, c) => Math.random() * (c - a) + a;
|
|
629
|
+
this.container.children().forEach((a, c) => {
|
|
630
|
+
const l = a.node.classList.contains("central-button");
|
|
631
|
+
this.animate(a, 0, t, e, r(s, i), n, (h) => {
|
|
632
|
+
l ? a.transform(`s${h},${h},${this.c},${this.c}`) : a.transform(`r${this.angle * c},${this.c},${this.c}s${h},${h},${this.c},${this.c}`);
|
|
633
|
+
});
|
|
634
|
+
});
|
|
635
|
+
}
|
|
636
|
+
animateButtonHover(t, e, s, i, n, r) {
|
|
637
|
+
const a = t.select(".radial-icon"), c = a ? E.get(a) : void 0, l = t.select(".hint-group"), h = l ? L.get(l) : void 0;
|
|
638
|
+
this.animate(t, 1, e, s, i, n, (p) => {
|
|
639
|
+
const u = p * 10;
|
|
640
|
+
if (t.select(".radial-sector")?.attr({
|
|
641
|
+
d: F(this.c, this.c, this.config.outerRadius - u, this.config.innerRadius, 0, this.angle)
|
|
642
|
+
}), a && c) {
|
|
643
|
+
const d = c.midRadius - u, m = c.scale * (1 - p * 0.1), y = this.angle / 2, w = M(this.c, this.c, d, y), f = new C();
|
|
644
|
+
f.translate(w.x, w.y), f.scale(m), f.rotate(c.rotation, 0, 0), f.translate(-c.bbox.cx, -c.bbox.cy), a.transform(f);
|
|
645
|
+
}
|
|
646
|
+
if (h && l) {
|
|
647
|
+
const d = h.baseRadius - u, m = h.textLength / d * 180 / Math.PI, y = h.sectorMidAngle - m / 2, w = h.sectorMidAngle + m / 2, f = S(this.c, this.c, d, y, w, !1, !1), v = l.select(".radial-hint");
|
|
648
|
+
v && v.attr("textpath", f);
|
|
649
|
+
const g = l.select(".radial-hint-bg");
|
|
650
|
+
g && g.attr("d", f);
|
|
651
|
+
}
|
|
652
|
+
}, r);
|
|
653
|
+
}
|
|
654
|
+
animateCentralHover(t, e) {
|
|
655
|
+
const s = t.select(".central-sector"), i = t.select(".central-icon"), n = t.select(".central-hint"), r = t.select(".radial-hint-bg");
|
|
656
|
+
if (!s || !i) return;
|
|
657
|
+
const a = parseFloat(s.node.dataset.initialRadius || "30"), c = parseFloat(s.attr("r")), l = e ? a - 8 : a, h = i ? E.get(i) : void 0;
|
|
658
|
+
let p = 12, u = 0, d = 0, m = this.c, y = this.c, w = !1;
|
|
659
|
+
n && (p = parseFloat(n.node.dataset.hintOffset || "12"), u = parseFloat(n.node.dataset.startAngle || "0"), d = parseFloat(n.node.dataset.endAngle || "0"), m = parseFloat(n.node.dataset.centerX || this.c.toString()), y = parseFloat(n.node.dataset.centerY || this.c.toString()), w = n.node.dataset.alter === "true"), P(c, l, (f) => {
|
|
660
|
+
if (s.attr("r", f), i && h) {
|
|
661
|
+
const v = h.scale * (f / a), g = new C();
|
|
662
|
+
g.translate(this.c, this.c), g.scale(v), g.translate(-h.bbox.cx, -h.bbox.cy), i.transform(g);
|
|
663
|
+
}
|
|
664
|
+
if (n) {
|
|
665
|
+
const v = f + p, g = S(m, y, v, u, d, !1, w);
|
|
666
|
+
n.attr({ textpath: g }), r && r.attr({ d: g });
|
|
667
|
+
}
|
|
668
|
+
}, 200, b.easeinout);
|
|
669
|
+
}
|
|
670
|
+
transformOpacity(t) {
|
|
671
|
+
const e = t.deltaY > 0 ? 0.03 : -0.03;
|
|
672
|
+
this.config.opacity = X(this.config.opacity + e, 0.4, 1), this.area.selectAll(".radial-sector").forEach((s) => {
|
|
673
|
+
s.attr({ opacity: this.config.opacity });
|
|
674
|
+
}), this.area.selectAll(".radial-hint-bg.active").forEach((s) => {
|
|
675
|
+
s.node.style.opacity = String(this.config.opacity);
|
|
676
|
+
});
|
|
677
|
+
}
|
|
678
|
+
on(t, e) {
|
|
679
|
+
(this.events[t] ??= []).push(e);
|
|
680
|
+
}
|
|
681
|
+
emit(t, e) {
|
|
682
|
+
this.events[t] && this.events[t].forEach((s) => s(e));
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
class K {
|
|
686
|
+
menu;
|
|
687
|
+
constructor(t, e) {
|
|
688
|
+
this.menu = new Q(e), t.appendChild(this.menu.element), e.autoBindContextMenu !== !1 && this.bindEvents();
|
|
689
|
+
}
|
|
690
|
+
bindEvents() {
|
|
691
|
+
window.addEventListener("contextmenu", (t) => {
|
|
692
|
+
t.preventDefault(), this.menu.show(t);
|
|
693
|
+
});
|
|
694
|
+
}
|
|
695
|
+
on(t, e) {
|
|
696
|
+
this.menu.on(t, e);
|
|
697
|
+
}
|
|
698
|
+
show(t) {
|
|
699
|
+
this.menu.show(t);
|
|
700
|
+
}
|
|
701
|
+
hide() {
|
|
702
|
+
this.menu.hide();
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
export {
|
|
706
|
+
K as Manager,
|
|
707
|
+
J as defineConfig
|
|
708
|
+
};
|
|
709
|
+
//# sourceMappingURL=context-menu.js.map
|