@rogieking/figui3 1.2.8 → 1.3.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/example.html +56 -23
- package/fig.css +89 -2
- package/fig.js +200 -1
- package/package.json +1 -1
package/example.html
CHANGED
|
@@ -23,14 +23,18 @@
|
|
|
23
23
|
<h2>UI3 Components</h2>
|
|
24
24
|
</fig-header>
|
|
25
25
|
<fig-content>
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
<fig-input-joystick text="true"
|
|
27
|
+
onInput="console.log(event.target.value)"></fig-input-joystick>
|
|
28
|
+
<fig-header>
|
|
29
|
+
<h2>Details</h2>
|
|
30
|
+
</fig-header>
|
|
28
31
|
<details>
|
|
29
32
|
<summary>Advanced settings</summary>
|
|
30
33
|
<p>Some more content here</p>
|
|
31
34
|
</details>
|
|
32
|
-
|
|
33
|
-
|
|
35
|
+
<fig-header>
|
|
36
|
+
<h2>Avatar</h2>
|
|
37
|
+
</fig-header>
|
|
34
38
|
<fig-field>
|
|
35
39
|
<label>Default</label>
|
|
36
40
|
<fig-avatar src="https://avatars.githubusercontent.com/u/12345678?v=4"
|
|
@@ -53,15 +57,18 @@
|
|
|
53
57
|
name="Rogie King"></fig-avatar>
|
|
54
58
|
</fig-field>
|
|
55
59
|
|
|
56
|
-
<
|
|
60
|
+
<fig-header>
|
|
61
|
+
<h2>Tabs</h2>
|
|
62
|
+
</fig-header>
|
|
57
63
|
<fig-field>
|
|
58
64
|
<fig-tabs>
|
|
59
65
|
<fig-tab selected>Tab #1</fig-tab>
|
|
60
66
|
<fig-tab>Tab #2</fig-tab>
|
|
61
67
|
</fig-tabs>
|
|
62
68
|
</fig-field>
|
|
63
|
-
<
|
|
64
|
-
|
|
69
|
+
<fig-header>
|
|
70
|
+
<h2>Segmented control</h2>
|
|
71
|
+
</fig-header>
|
|
65
72
|
<fig-field>
|
|
66
73
|
<fig-segmented-control>
|
|
67
74
|
<fig-segment selected>One</fig-segment>
|
|
@@ -69,7 +76,9 @@
|
|
|
69
76
|
<fig-segment>Three</fig-segment>
|
|
70
77
|
</fig-segmented-control>
|
|
71
78
|
</fig-field>
|
|
72
|
-
<
|
|
79
|
+
<fig-header>
|
|
80
|
+
<h2>Image</h2>
|
|
81
|
+
</fig-header>
|
|
73
82
|
<fig-field>
|
|
74
83
|
<label>Default</label>
|
|
75
84
|
<fig-image src="https://avatars.githubusercontent.com/u/12345678?v=4"></fig-image>
|
|
@@ -86,7 +95,9 @@
|
|
|
86
95
|
size="large"></fig-image>
|
|
87
96
|
</fig-field>
|
|
88
97
|
<br /><br />
|
|
89
|
-
<
|
|
98
|
+
<fig-header>
|
|
99
|
+
<h2>Button</h2>
|
|
100
|
+
</fig-header>
|
|
90
101
|
<fig-field>
|
|
91
102
|
<label>Primary Button</label>
|
|
92
103
|
<fig-button>Primary</fig-button>
|
|
@@ -127,8 +138,9 @@
|
|
|
127
138
|
fill="currentColor"></path>
|
|
128
139
|
</svg></fig-button>
|
|
129
140
|
</fig-field>
|
|
130
|
-
|
|
131
|
-
|
|
141
|
+
<fig-header>
|
|
142
|
+
<h2>Combo button</h2>
|
|
143
|
+
</fig-header>
|
|
132
144
|
<fig-field>
|
|
133
145
|
<label>Primary (compact dropdown</label>
|
|
134
146
|
<fig-button-combo>
|
|
@@ -315,8 +327,9 @@
|
|
|
315
327
|
<fig-button>Save</fig-button>
|
|
316
328
|
</footer>
|
|
317
329
|
</fig-dialog>
|
|
318
|
-
|
|
319
|
-
|
|
330
|
+
<fig-header>
|
|
331
|
+
<h2>Dropdown</h2>
|
|
332
|
+
</fig-header>
|
|
320
333
|
<fig-field>
|
|
321
334
|
<label>Dropdown</label>
|
|
322
335
|
<fig-dropdown>
|
|
@@ -392,7 +405,9 @@
|
|
|
392
405
|
<span slot="prepend">X</span>
|
|
393
406
|
</fig-input-text>
|
|
394
407
|
</fig-field>
|
|
395
|
-
<
|
|
408
|
+
<fig-header>
|
|
409
|
+
<h2>Color input</h2>
|
|
410
|
+
</fig-header>
|
|
396
411
|
<fig-field>
|
|
397
412
|
<label>Color swatch</label>
|
|
398
413
|
<fig-input-color value="#FF000066"></fig-input-color>
|
|
@@ -408,11 +423,15 @@
|
|
|
408
423
|
alpha="true"
|
|
409
424
|
text="true"></fig-input-color>
|
|
410
425
|
</fig-field>
|
|
411
|
-
<
|
|
426
|
+
<fig-header>
|
|
427
|
+
<h2>Checkbox</h2>
|
|
428
|
+
</fig-header>
|
|
412
429
|
<fig-field>
|
|
413
430
|
<fig-checkbox label="Checkbox"></fig-checkbox>
|
|
414
431
|
</fig-field>
|
|
415
|
-
<
|
|
432
|
+
<fig-header>
|
|
433
|
+
<h2>Radio</h2>
|
|
434
|
+
</fig-header>
|
|
416
435
|
<fig-field>
|
|
417
436
|
<label>Radio buttons</label>
|
|
418
437
|
<fig-radio label="Radio #1"
|
|
@@ -420,7 +439,9 @@
|
|
|
420
439
|
<fig-radio label="Radio #2"
|
|
421
440
|
name="r1"></fig-radio>
|
|
422
441
|
</fig-field>
|
|
423
|
-
<
|
|
442
|
+
<fig-header>
|
|
443
|
+
<h2>Switch</h2>
|
|
444
|
+
</fig-header>
|
|
424
445
|
<fig-field>
|
|
425
446
|
<label>Switches</label>
|
|
426
447
|
<fig-switch on="true"
|
|
@@ -430,7 +451,9 @@
|
|
|
430
451
|
<fig-switch disabled
|
|
431
452
|
label="Disabled"></fig-switch>
|
|
432
453
|
</fig-field>
|
|
433
|
-
<
|
|
454
|
+
<fig-header>
|
|
455
|
+
<h2>Chit</h2>
|
|
456
|
+
</fig-header>
|
|
434
457
|
<fig-field>
|
|
435
458
|
<label>Chit</label>
|
|
436
459
|
<hstack>
|
|
@@ -473,13 +496,17 @@
|
|
|
473
496
|
</hstack>
|
|
474
497
|
</fig-field>
|
|
475
498
|
|
|
476
|
-
<
|
|
499
|
+
<fig-header>
|
|
500
|
+
<h2>Tooltip</h2>
|
|
501
|
+
</fig-header>
|
|
477
502
|
<p>Some paragraph text here with a
|
|
478
503
|
<fig-tooltip text="Tooltip text">
|
|
479
504
|
<em>Tooltip</em>
|
|
480
505
|
</fig-tooltip> for more information.
|
|
481
506
|
</p>
|
|
482
|
-
<
|
|
507
|
+
<fig-header>
|
|
508
|
+
<h2>Field</h2>
|
|
509
|
+
</fig-header>
|
|
483
510
|
<fig-field direction="horizontal">
|
|
484
511
|
<label>Horizontal</label>
|
|
485
512
|
<fig-input-text value=""
|
|
@@ -490,7 +517,9 @@
|
|
|
490
517
|
<fig-input-text value=""
|
|
491
518
|
placeholder="Field placeholder"></fig-input-text>
|
|
492
519
|
</fig-field>
|
|
493
|
-
<
|
|
520
|
+
<fig-header>
|
|
521
|
+
<h2>Slider</h2>
|
|
522
|
+
</fig-header>
|
|
494
523
|
<fig-field>
|
|
495
524
|
<label>Default slider</label>
|
|
496
525
|
<fig-slider default="25"
|
|
@@ -559,10 +588,14 @@
|
|
|
559
588
|
</datalist>
|
|
560
589
|
</fig-slider>
|
|
561
590
|
</fig-field>
|
|
562
|
-
<
|
|
591
|
+
<fig-header>
|
|
592
|
+
<h2>Spinner</h2>
|
|
593
|
+
</fig-header>
|
|
563
594
|
<fig-spinner></fig-spinner>
|
|
564
595
|
|
|
565
|
-
<
|
|
596
|
+
<fig-header>
|
|
597
|
+
<h2>Misc.</h2>
|
|
598
|
+
</fig-header>
|
|
566
599
|
<hstack>
|
|
567
600
|
<fig-tooltip text="Tooltip"
|
|
568
601
|
delay="0">
|
package/fig.css
CHANGED
|
@@ -444,7 +444,7 @@
|
|
|
444
444
|
@media (prefers-color-scheme: dark) {
|
|
445
445
|
:root {
|
|
446
446
|
--icon-chevron: url("data:image/svg+xml,%3Csvg width='16' height='16' viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M5.87868 7.12132L8 9.24264L10.1213 7.12132' stroke='rgb(255 255 255 / 100%)' stroke-linecap='round'/%3E%3C/svg%3E%0A");
|
|
447
|
-
--handle-shadow: 0px 0 0 0.75px rgba(
|
|
447
|
+
--handle-shadow: 0px 0 0 0.75px 0px 0 0 0.75px rgba(0, 0, 0, 0.1),
|
|
448
448
|
0px 0px 0.5px 0px rgba(255, 255, 255, 0.1);
|
|
449
449
|
--figma-color-bg-ghost-hover: rgba(255, 255, 255, 0.05);
|
|
450
450
|
--figma-color-bordertranslucent: rgba(255, 255, 255, 0.1);
|
|
@@ -1224,7 +1224,7 @@ input[type="checkbox"].switch:after {
|
|
|
1224
1224
|
height: calc(1rem - 2px);
|
|
1225
1225
|
border-radius: 0.5rem;
|
|
1226
1226
|
margin: 1px;
|
|
1227
|
-
transform: translate(calc(-0.5rem
|
|
1227
|
+
transform: translate(calc(-0.5rem));
|
|
1228
1228
|
transition: var(--input-transition);
|
|
1229
1229
|
box-shadow: var(--handle-shadow);
|
|
1230
1230
|
}
|
|
@@ -1247,6 +1247,9 @@ input[type="checkbox"].switch:checked:after {
|
|
|
1247
1247
|
input[type="checkbox"].switch:disabled {
|
|
1248
1248
|
background-color: var(--figma-color-bg-tertiary);
|
|
1249
1249
|
cursor: not-allowed;
|
|
1250
|
+
&:after {
|
|
1251
|
+
background-color: var(--figma-color-bg);
|
|
1252
|
+
}
|
|
1250
1253
|
}
|
|
1251
1254
|
|
|
1252
1255
|
input[type="checkbox"].switch:focus {
|
|
@@ -2271,3 +2274,87 @@ fig-segmented-control {
|
|
|
2271
2274
|
transform: rotate(360deg);
|
|
2272
2275
|
}
|
|
2273
2276
|
}
|
|
2277
|
+
|
|
2278
|
+
fig-input-joystick {
|
|
2279
|
+
--size: 1.5rem;
|
|
2280
|
+
display: inline-flex;
|
|
2281
|
+
gap: var(--spacer-2);
|
|
2282
|
+
.fig-input-joystick-plane-container {
|
|
2283
|
+
display: flex;
|
|
2284
|
+
width: 1.5rem;
|
|
2285
|
+
height: 1.5rem;
|
|
2286
|
+
place-items: center;
|
|
2287
|
+
}
|
|
2288
|
+
.fig-input-joystick-plane {
|
|
2289
|
+
display: inline-grid;
|
|
2290
|
+
place-items: center;
|
|
2291
|
+
position: relative;
|
|
2292
|
+
width: var(--size);
|
|
2293
|
+
height: var(--size);
|
|
2294
|
+
flex-shrink: 0;
|
|
2295
|
+
&:hover {
|
|
2296
|
+
cursor: grab;
|
|
2297
|
+
--size: 3rem;
|
|
2298
|
+
}
|
|
2299
|
+
}
|
|
2300
|
+
.fig-input-joystick-plane > * {
|
|
2301
|
+
grid-area: 1/1;
|
|
2302
|
+
}
|
|
2303
|
+
.fig-input-joystick-guides {
|
|
2304
|
+
position: absolute;
|
|
2305
|
+
width: var(--size);
|
|
2306
|
+
height: var(--size);
|
|
2307
|
+
border: 1px solid var(--figma-color-border);
|
|
2308
|
+
border-radius: var(--radius-medium);
|
|
2309
|
+
overflow: hidden;
|
|
2310
|
+
background: var(--figma-color-bg-secondary);
|
|
2311
|
+
|
|
2312
|
+
&:before {
|
|
2313
|
+
content: "";
|
|
2314
|
+
position: absolute;
|
|
2315
|
+
height: 0;
|
|
2316
|
+
border-left: 1px solid var(--figma-color-border);
|
|
2317
|
+
height: 100%;
|
|
2318
|
+
top: 0;
|
|
2319
|
+
left: calc(50% - 0.5px);
|
|
2320
|
+
pointer-events: none;
|
|
2321
|
+
}
|
|
2322
|
+
&:after {
|
|
2323
|
+
content: "";
|
|
2324
|
+
position: absolute;
|
|
2325
|
+
height: 0;
|
|
2326
|
+
border-top: 1px solid var(--figma-color-border);
|
|
2327
|
+
width: 100%;
|
|
2328
|
+
top: calc(50% - 0.5px);
|
|
2329
|
+
left: 0;
|
|
2330
|
+
pointer-events: none;
|
|
2331
|
+
}
|
|
2332
|
+
}
|
|
2333
|
+
.fig-input-joystick-plane:hover .fig-input-joystick-guides {
|
|
2334
|
+
background: linear-gradient(
|
|
2335
|
+
45deg,
|
|
2336
|
+
transparent calc(50% - 0.5px),
|
|
2337
|
+
var(--figma-color-border) calc(50% - 0.5px),
|
|
2338
|
+
var(--figma-color-border) calc(50% + 0.5px),
|
|
2339
|
+
transparent calc(50% + 0.5px)
|
|
2340
|
+
),
|
|
2341
|
+
linear-gradient(
|
|
2342
|
+
-45deg,
|
|
2343
|
+
transparent calc(50% - 0.5px),
|
|
2344
|
+
var(--figma-color-border) calc(50% - 0.5px),
|
|
2345
|
+
var(--figma-color-border) calc(50% + 0.5px),
|
|
2346
|
+
transparent calc(50% + 0.5px)
|
|
2347
|
+
),
|
|
2348
|
+
var(--figma-color-bg-secondary);
|
|
2349
|
+
}
|
|
2350
|
+
.fig-input-joystick-handle {
|
|
2351
|
+
position: absolute;
|
|
2352
|
+
z-index: 1;
|
|
2353
|
+
width: 0.5rem;
|
|
2354
|
+
height: 0.5rem;
|
|
2355
|
+
background: var(--figma-color-icon-onbrand);
|
|
2356
|
+
box-shadow: var(--handle-shadow);
|
|
2357
|
+
border-radius: 50%;
|
|
2358
|
+
transform: translate(-50%, -50%);
|
|
2359
|
+
}
|
|
2360
|
+
}
|
package/fig.js
CHANGED
|
@@ -892,6 +892,8 @@ class FigInputText extends HTMLElement {
|
|
|
892
892
|
this.value = this.getAttribute("value") || "";
|
|
893
893
|
this.type = this.getAttribute("type") || "text";
|
|
894
894
|
this.placeholder = this.getAttribute("placeholder") || "";
|
|
895
|
+
this.name = this.getAttribute("name") || null;
|
|
896
|
+
|
|
895
897
|
if (this.type === "number") {
|
|
896
898
|
if (this.getAttribute("step")) {
|
|
897
899
|
this.step = Number(this.getAttribute("step"));
|
|
@@ -910,6 +912,7 @@ class FigInputText extends HTMLElement {
|
|
|
910
912
|
|
|
911
913
|
let html = `<input
|
|
912
914
|
type="${this.type}"
|
|
915
|
+
${this.name ? `name="${this.name}"` : ""}
|
|
913
916
|
placeholder="${this.placeholder}"
|
|
914
917
|
value="${
|
|
915
918
|
this.type === "number" ? this.#transformNumber(this.value) : this.value
|
|
@@ -1038,6 +1041,7 @@ class FigInputText extends HTMLElement {
|
|
|
1038
1041
|
"min",
|
|
1039
1042
|
"max",
|
|
1040
1043
|
"transform",
|
|
1044
|
+
"name",
|
|
1041
1045
|
];
|
|
1042
1046
|
}
|
|
1043
1047
|
|
|
@@ -1078,8 +1082,12 @@ class FigInputText extends HTMLElement {
|
|
|
1078
1082
|
this.input.setAttribute(name, newValue);
|
|
1079
1083
|
}
|
|
1080
1084
|
break;
|
|
1085
|
+
case "name":
|
|
1086
|
+
this[name] = this.input[name] = newValue;
|
|
1087
|
+
this.input.setAttribute("name", newValue);
|
|
1088
|
+
break;
|
|
1081
1089
|
default:
|
|
1082
|
-
this[name] = this.input[name] =
|
|
1090
|
+
this[name] = this.input[name] = newValue;
|
|
1083
1091
|
break;
|
|
1084
1092
|
}
|
|
1085
1093
|
}
|
|
@@ -1703,3 +1711,194 @@ class FigImage extends HTMLElement {
|
|
|
1703
1711
|
}
|
|
1704
1712
|
}
|
|
1705
1713
|
window.customElements.define("fig-image", FigImage);
|
|
1714
|
+
|
|
1715
|
+
class FigInputJoystick extends HTMLElement {
|
|
1716
|
+
constructor() {
|
|
1717
|
+
super();
|
|
1718
|
+
|
|
1719
|
+
this.position = { x: 0.5, y: 0.5 };
|
|
1720
|
+
this.value = [0.5, 0.5];
|
|
1721
|
+
this.isDragging = false;
|
|
1722
|
+
this.isShiftHeld = false;
|
|
1723
|
+
|
|
1724
|
+
// Initialize position
|
|
1725
|
+
requestAnimationFrame(() => {
|
|
1726
|
+
this.precision = this.getAttribute("precision") || 3;
|
|
1727
|
+
this.precision = parseInt(this.precision);
|
|
1728
|
+
this.transform = this.getAttribute("transform") || 1;
|
|
1729
|
+
this.transform = Number(this.transform);
|
|
1730
|
+
this.text = this.getAttribute("text") === "true";
|
|
1731
|
+
|
|
1732
|
+
this.render();
|
|
1733
|
+
|
|
1734
|
+
this.setupListeners();
|
|
1735
|
+
|
|
1736
|
+
this.cursor.style.left = `${this.position.x * 100}%`;
|
|
1737
|
+
this.cursor.style.top = `${this.position.y * 100}%`;
|
|
1738
|
+
if (this.text) {
|
|
1739
|
+
this.xInput.value = this.position.x.toFixed(this.precision);
|
|
1740
|
+
this.yInput.value = this.position.y.toFixed(this.precision);
|
|
1741
|
+
}
|
|
1742
|
+
});
|
|
1743
|
+
}
|
|
1744
|
+
|
|
1745
|
+
render() {
|
|
1746
|
+
this.innerHTML = `
|
|
1747
|
+
<div class="fig-input-joystick-plane-container">
|
|
1748
|
+
<div class="fig-input-joystick-plane">
|
|
1749
|
+
<div class="fig-input-joystick-guides"></div>
|
|
1750
|
+
<div class="fig-input-joystick-handle"></div>
|
|
1751
|
+
</div>
|
|
1752
|
+
</div>
|
|
1753
|
+
${
|
|
1754
|
+
this.text
|
|
1755
|
+
? `<fig-input-text
|
|
1756
|
+
type="number"
|
|
1757
|
+
name="x"
|
|
1758
|
+
step="0.01"
|
|
1759
|
+
value="${this.position.x}"
|
|
1760
|
+
min="0"
|
|
1761
|
+
max="1">
|
|
1762
|
+
<span slot="prepend">X</span>
|
|
1763
|
+
</fig-input-text>
|
|
1764
|
+
<fig-input-text
|
|
1765
|
+
type="number"
|
|
1766
|
+
name="y"
|
|
1767
|
+
step="0.01"
|
|
1768
|
+
min="0"
|
|
1769
|
+
max="1"
|
|
1770
|
+
value="${this.position.y}">
|
|
1771
|
+
<span slot="prepend">Y</span>
|
|
1772
|
+
</fig-input-text>`
|
|
1773
|
+
: ""
|
|
1774
|
+
}
|
|
1775
|
+
`;
|
|
1776
|
+
}
|
|
1777
|
+
|
|
1778
|
+
setupListeners() {
|
|
1779
|
+
this.plane = this.querySelector(".fig-input-joystick-plane");
|
|
1780
|
+
this.cursor = this.querySelector(".fig-input-joystick-handle");
|
|
1781
|
+
if (this.text) {
|
|
1782
|
+
this.xInput = this.querySelector("fig-input-text[name='x']");
|
|
1783
|
+
this.yInput = this.querySelector("fig-input-text[name='y']");
|
|
1784
|
+
}
|
|
1785
|
+
|
|
1786
|
+
this.plane.addEventListener("mousedown", this.handleMouseDown.bind(this));
|
|
1787
|
+
window.addEventListener("keydown", this.handleKeyDown.bind(this));
|
|
1788
|
+
window.addEventListener("keyup", this.handleKeyUp.bind(this));
|
|
1789
|
+
|
|
1790
|
+
this.xInput.addEventListener("input", this.handleXInput.bind(this));
|
|
1791
|
+
this.yInput.addEventListener("input", this.handleYInput.bind(this));
|
|
1792
|
+
}
|
|
1793
|
+
|
|
1794
|
+
handleXInput(e) {
|
|
1795
|
+
e.stopPropagation();
|
|
1796
|
+
this.position.x = e.target.value;
|
|
1797
|
+
this.#syncHandlePosition();
|
|
1798
|
+
this.#emitInputEvent();
|
|
1799
|
+
this.#emitChangeEvent();
|
|
1800
|
+
}
|
|
1801
|
+
|
|
1802
|
+
handleYInput(e) {
|
|
1803
|
+
e.stopPropagation();
|
|
1804
|
+
this.position.y = e.target.value;
|
|
1805
|
+
this.#syncHandlePosition();
|
|
1806
|
+
this.#emitInputEvent();
|
|
1807
|
+
this.#emitChangeEvent();
|
|
1808
|
+
}
|
|
1809
|
+
|
|
1810
|
+
snapToGuide(value) {
|
|
1811
|
+
if (!this.isShiftHeld) return value;
|
|
1812
|
+
if (value < 0.1) return 0;
|
|
1813
|
+
if (value > 0.9) return 1;
|
|
1814
|
+
if (value > 0.4 && value < 0.6) return 0.5;
|
|
1815
|
+
return value;
|
|
1816
|
+
}
|
|
1817
|
+
|
|
1818
|
+
snapToDiagonal(x, y) {
|
|
1819
|
+
if (!this.isShiftHeld) return { x, y };
|
|
1820
|
+
const diff = Math.abs(x - y);
|
|
1821
|
+
if (diff < 0.1) return { x: (x + y) / 2, y: (x + y) / 2 };
|
|
1822
|
+
if (Math.abs(1 - x - y) < 0.1) return { x, y: 1 - x };
|
|
1823
|
+
return { x, y };
|
|
1824
|
+
}
|
|
1825
|
+
|
|
1826
|
+
#updatePosition(e) {
|
|
1827
|
+
const rect = this.plane.getBoundingClientRect();
|
|
1828
|
+
let x = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
|
|
1829
|
+
let y = Math.max(0, Math.min(1, (e.clientY - rect.top) / rect.height));
|
|
1830
|
+
|
|
1831
|
+
// Invert Y coordinate to match typical coordinate system
|
|
1832
|
+
y = 1 - y;
|
|
1833
|
+
|
|
1834
|
+
x = this.snapToGuide(x);
|
|
1835
|
+
y = this.snapToGuide(y);
|
|
1836
|
+
|
|
1837
|
+
const snapped = this.snapToDiagonal(x, y);
|
|
1838
|
+
this.position = snapped;
|
|
1839
|
+
this.value = [snapped.x, snapped.y];
|
|
1840
|
+
|
|
1841
|
+
this.cursor.style.left = `${snapped.x * 100}%`;
|
|
1842
|
+
this.cursor.style.top = `${(1 - snapped.y) * 100}%`; // Invert Y for display
|
|
1843
|
+
if (this.text) {
|
|
1844
|
+
this.xInput.setAttribute("value", snapped.x.toFixed(3));
|
|
1845
|
+
this.yInput.setAttribute("value", snapped.y.toFixed(3));
|
|
1846
|
+
}
|
|
1847
|
+
|
|
1848
|
+
this.#emitInputEvent();
|
|
1849
|
+
}
|
|
1850
|
+
#emitInputEvent() {
|
|
1851
|
+
this.dispatchEvent(
|
|
1852
|
+
new CustomEvent("input", {
|
|
1853
|
+
bubbles: true,
|
|
1854
|
+
cancelable: true,
|
|
1855
|
+
})
|
|
1856
|
+
);
|
|
1857
|
+
}
|
|
1858
|
+
|
|
1859
|
+
#emitChangeEvent() {
|
|
1860
|
+
this.dispatchEvent(
|
|
1861
|
+
new CustomEvent("change", {
|
|
1862
|
+
bubbles: true,
|
|
1863
|
+
cancelable: true,
|
|
1864
|
+
})
|
|
1865
|
+
);
|
|
1866
|
+
}
|
|
1867
|
+
|
|
1868
|
+
#syncHandlePosition() {
|
|
1869
|
+
this.cursor.style.left = `${this.position.x * 100}%`;
|
|
1870
|
+
this.cursor.style.top = `${(1 - this.position.y) * 100}%`;
|
|
1871
|
+
}
|
|
1872
|
+
|
|
1873
|
+
handleMouseDown(e) {
|
|
1874
|
+
this.isDragging = true;
|
|
1875
|
+
this.#updatePosition(e);
|
|
1876
|
+
|
|
1877
|
+
this.plane.style.cursor = "grabbing";
|
|
1878
|
+
|
|
1879
|
+
const handleMouseMove = (e) => {
|
|
1880
|
+
if (this.isDragging) this.#updatePosition(e);
|
|
1881
|
+
};
|
|
1882
|
+
|
|
1883
|
+
const handleMouseUp = () => {
|
|
1884
|
+
this.isDragging = false;
|
|
1885
|
+
this.plane.style.cursor = "";
|
|
1886
|
+
window.removeEventListener("mousemove", handleMouseMove);
|
|
1887
|
+
window.removeEventListener("mouseup", handleMouseUp);
|
|
1888
|
+
this.#emitChangeEvent();
|
|
1889
|
+
};
|
|
1890
|
+
|
|
1891
|
+
window.addEventListener("mousemove", handleMouseMove);
|
|
1892
|
+
window.addEventListener("mouseup", handleMouseUp);
|
|
1893
|
+
}
|
|
1894
|
+
|
|
1895
|
+
handleKeyDown(e) {
|
|
1896
|
+
if (e.key === "Shift") this.isShiftHeld = true;
|
|
1897
|
+
}
|
|
1898
|
+
|
|
1899
|
+
handleKeyUp(e) {
|
|
1900
|
+
if (e.key === "Shift") this.isShiftHeld = false;
|
|
1901
|
+
}
|
|
1902
|
+
}
|
|
1903
|
+
|
|
1904
|
+
customElements.define("fig-input-joystick", FigInputJoystick);
|