@diabolic/pointy 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +53 -1
- package/dist/pointy.esm.js +250 -30
- package/dist/pointy.js +250 -30
- package/dist/pointy.min.js +1 -1
- package/dist/pointy.min.js.map +1 -1
- package/package.json +1 -1
- package/src/pointy.js +249 -29
package/README.md
CHANGED
|
@@ -64,11 +64,41 @@ pointy.show();
|
|
|
64
64
|
{
|
|
65
65
|
target: '#element', // CSS selector or HTMLElement
|
|
66
66
|
content: 'Message', // String, HTML, array, or React element
|
|
67
|
-
direction: 'up',
|
|
67
|
+
direction: 'up-left', // Direction preset or null (auto)
|
|
68
68
|
duration: 3000 // Step-specific autoplay duration (ms)
|
|
69
69
|
}
|
|
70
70
|
```
|
|
71
71
|
|
|
72
|
+
### Direction Presets
|
|
73
|
+
|
|
74
|
+
Control the pointer and bubble direction manually:
|
|
75
|
+
|
|
76
|
+
| Direction | Description |
|
|
77
|
+
|-----------|-------------|
|
|
78
|
+
| `null` | Auto (default) - automatically adjusts based on viewport |
|
|
79
|
+
| `'up'` | Pointer points up, bubble below target |
|
|
80
|
+
| `'down'` | Pointer points down, bubble above target |
|
|
81
|
+
| `'left'` | Bubble on left side of target |
|
|
82
|
+
| `'right'` | Bubble on right side of target |
|
|
83
|
+
| `'up-left'` | Pointer up, bubble on left |
|
|
84
|
+
| `'up-right'` | Pointer up, bubble on right |
|
|
85
|
+
| `'down-left'` | Pointer down, bubble on left |
|
|
86
|
+
| `'down-right'` | Pointer down, bubble on right |
|
|
87
|
+
|
|
88
|
+
```javascript
|
|
89
|
+
// In steps
|
|
90
|
+
{ target: '#el', content: 'Hello', direction: 'down-right' }
|
|
91
|
+
|
|
92
|
+
// Runtime
|
|
93
|
+
pointy.setDirection('up-left'); // Both axes
|
|
94
|
+
pointy.setHorizontalDirection('right'); // Only horizontal
|
|
95
|
+
pointy.setVerticalDirection('down'); // Only vertical
|
|
96
|
+
pointy.setDirection(null); // Reset to auto
|
|
97
|
+
|
|
98
|
+
// pointTo with direction
|
|
99
|
+
pointy.pointTo('#element', 'Message', 'down-left');
|
|
100
|
+
```
|
|
101
|
+
|
|
72
102
|
### Animation
|
|
73
103
|
|
|
74
104
|
| Option | Type | Default | Description |
|
|
@@ -192,6 +222,12 @@ pointy.setOffset(30, 20);
|
|
|
192
222
|
pointy.setInitialPosition('top-left');
|
|
193
223
|
pointy.setInitialPositionOffset(50);
|
|
194
224
|
pointy.setZIndex(10000);
|
|
225
|
+
pointy.setStayInViewport(true, { x: 50, y: 80 }); // Auto-flip with custom thresholds
|
|
226
|
+
|
|
227
|
+
// Direction
|
|
228
|
+
pointy.setDirection('up-left'); // Set both directions
|
|
229
|
+
pointy.setHorizontalDirection('right'); // Only horizontal (left/right/null)
|
|
230
|
+
pointy.setVerticalDirection('down'); // Only vertical (up/down/null)
|
|
195
231
|
|
|
196
232
|
// Tracking
|
|
197
233
|
pointy.setTracking(true);
|
|
@@ -297,6 +333,15 @@ pointy.on('all', (data) => {
|
|
|
297
333
|
| `moveComplete` | `{ index, step, target }` |
|
|
298
334
|
| `introAnimationStart` | `{ duration, initialPosition }` |
|
|
299
335
|
| `introAnimationEnd` | `{ initialPosition }` |
|
|
336
|
+
| `flipHorizontal` | `{ from: 'left'\|'right', to: 'left'\|'right' }` |
|
|
337
|
+
| `flipVertical` | `{ from: 'up'\|'down', to: 'up'\|'down' }` |
|
|
338
|
+
|
|
339
|
+
#### Direction
|
|
340
|
+
| Event | Data |
|
|
341
|
+
|-------|------|
|
|
342
|
+
| `directionChange` | `{ from: { horizontal, vertical }, to: { horizontal, vertical } }` |
|
|
343
|
+
| `horizontalDirectionChange` | `{ from, to }` |
|
|
344
|
+
| `verticalDirectionChange` | `{ from, to }` |
|
|
300
345
|
|
|
301
346
|
#### Content
|
|
302
347
|
| Event | Data |
|
|
@@ -339,6 +384,13 @@ pointy.on('all', (data) => {
|
|
|
339
384
|
| `autoplayNext` | `{ fromIndex, duration?, afterMessages? }` |
|
|
340
385
|
| `autoplayComplete` | `{ totalSteps }` |
|
|
341
386
|
| `autoHide` | `{ delay, source }` |
|
|
387
|
+
| `autoplayChange` | `{ from, to }` |
|
|
388
|
+
| `autoplayWaitForMessagesChange` | `{ from, to }` |
|
|
389
|
+
|
|
390
|
+
#### Viewport
|
|
391
|
+
| Event | Data |
|
|
392
|
+
|-------|------|
|
|
393
|
+
| `stayInViewportChange` | `{ from: { enabled, x, y }, to: { enabled, x, y } }` |
|
|
342
394
|
|
|
343
395
|
#### Config
|
|
344
396
|
All setter methods emit `*Change` events with `{ from, to }` data.
|
package/dist/pointy.esm.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Pointy - A lightweight tooltip library with animated pointer
|
|
3
|
-
* @version 1.1.
|
|
3
|
+
* @version 1.1.1
|
|
4
4
|
* @license MIT
|
|
5
5
|
*/
|
|
6
6
|
/**
|
|
@@ -26,6 +26,11 @@
|
|
|
26
26
|
* - target {string|HTMLElement} - Initial target element
|
|
27
27
|
* - content {string|string[]} - Initial content/messages (single-step use)
|
|
28
28
|
* - zIndex {number} - CSS z-index for the container (default: 9999)
|
|
29
|
+
* - stayInViewport {boolean|object} - Auto-flip bubble to stay within viewport (default: true)
|
|
30
|
+
* - true/false: Enable/disable with default thresholds (x: 40, y: 60)
|
|
31
|
+
* - { x: number, y: number }: Enable with custom thresholds
|
|
32
|
+
* - { x: number }: Enable with custom horizontal threshold only
|
|
33
|
+
* - { y: number }: Enable with custom vertical threshold only
|
|
29
34
|
* - offsetX {number} - Horizontal offset from target (default: 20)
|
|
30
35
|
* - offsetY {number} - Vertical offset from target (default: 16)
|
|
31
36
|
* - trackingFps {number} - Position update FPS, 0 = unlimited (default: 60)
|
|
@@ -78,6 +83,11 @@
|
|
|
78
83
|
* - moveComplete: Position update finished
|
|
79
84
|
* - introAnimationStart: Initial fade-in animation started
|
|
80
85
|
* - introAnimationEnd: Initial fade-in animation completed
|
|
86
|
+
* - flipHorizontal: Bubble flipped horizontally (left/right) due to viewport bounds
|
|
87
|
+
* - flipVertical: Bubble flipped vertically (up/down) due to viewport bounds
|
|
88
|
+
* - directionChange: Manual direction changed via setDirection()
|
|
89
|
+
* - horizontalDirectionChange: Horizontal direction changed via setHorizontalDirection()
|
|
90
|
+
* - verticalDirectionChange: Vertical direction changed via setVerticalDirection()
|
|
81
91
|
*
|
|
82
92
|
* Content:
|
|
83
93
|
* - messagesSet: Messages array replaced via setMessages() or setMessage()
|
|
@@ -143,8 +153,10 @@
|
|
|
143
153
|
* Setters (all emit change events):
|
|
144
154
|
* setEasing(), setAnimationDuration(), setIntroFadeDuration(), setBubbleFadeDuration(),
|
|
145
155
|
* setMessageInterval(), setMessageTransitionDuration(), setOffset(), setZIndex(),
|
|
146
|
-
*
|
|
147
|
-
*
|
|
156
|
+
* setStayInViewport(enabled, thresholds?), setDirection(direction),
|
|
157
|
+
* setHorizontalDirection(direction), setVerticalDirection(direction),
|
|
158
|
+
* setResetOnComplete(), setFloatingAnimation(),
|
|
159
|
+
* setInitialPosition(), setInitialPositionOffset(), setAutoplay(), setAutoplayWaitForMessages()
|
|
148
160
|
*
|
|
149
161
|
* Static Helpers:
|
|
150
162
|
* - Pointy.renderContent(element, content) - Render string/JSX to element
|
|
@@ -279,6 +291,7 @@ class Pointy {
|
|
|
279
291
|
.${cn.bubble} {
|
|
280
292
|
position: absolute;
|
|
281
293
|
right: 26px;
|
|
294
|
+
left: auto;
|
|
282
295
|
top: 0;
|
|
283
296
|
background: #0a1551;
|
|
284
297
|
color: white;
|
|
@@ -290,7 +303,7 @@ class Pointy {
|
|
|
290
303
|
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.25);
|
|
291
304
|
white-space: nowrap;
|
|
292
305
|
overflow: hidden;
|
|
293
|
-
transition: width 0.5s cubic-bezier(0.4, 0, 0.2, 1), height 0.5s cubic-bezier(0.4, 0, 0.2, 1), transform var(--${vp}-duration) var(--${vp}-easing), opacity var(--${vp}-bubble-fade) ease;
|
|
306
|
+
transition: width 0.5s cubic-bezier(0.4, 0, 0.2, 1), height 0.5s cubic-bezier(0.4, 0, 0.2, 1), transform var(--${vp}-duration) var(--${vp}-easing), opacity var(--${vp}-bubble-fade) ease, left var(--${vp}-duration) var(--${vp}-easing), right var(--${vp}-duration) var(--${vp}-easing);
|
|
294
307
|
}
|
|
295
308
|
|
|
296
309
|
.${cn.bubbleText} {
|
|
@@ -441,6 +454,18 @@ class Pointy {
|
|
|
441
454
|
|
|
442
455
|
this.steps = options.steps || [];
|
|
443
456
|
this.zIndex = options.zIndex !== undefined ? options.zIndex : 9999; // CSS z-index
|
|
457
|
+
|
|
458
|
+
// stayInViewport: boolean or { x?: number, y?: number }
|
|
459
|
+
this.viewportThresholdX = 40; // Default horizontal margin
|
|
460
|
+
this.viewportThresholdY = 60; // Default vertical margin
|
|
461
|
+
if (typeof options.stayInViewport === 'object' && options.stayInViewport !== null) {
|
|
462
|
+
this.stayInViewport = true;
|
|
463
|
+
if (options.stayInViewport.x !== undefined) this.viewportThresholdX = options.stayInViewport.x;
|
|
464
|
+
if (options.stayInViewport.y !== undefined) this.viewportThresholdY = options.stayInViewport.y;
|
|
465
|
+
} else {
|
|
466
|
+
this.stayInViewport = options.stayInViewport !== undefined ? options.stayInViewport : true;
|
|
467
|
+
}
|
|
468
|
+
|
|
444
469
|
this.offsetX = options.offsetX !== undefined ? options.offsetX : 20;
|
|
445
470
|
this.offsetY = options.offsetY !== undefined ? options.offsetY : 16;
|
|
446
471
|
this.tracking = options.tracking !== undefined ? options.tracking : true; // Enable/disable position tracking
|
|
@@ -478,10 +503,12 @@ class Pointy {
|
|
|
478
503
|
this._messageIntervalId = null;
|
|
479
504
|
this.isVisible = false;
|
|
480
505
|
this.isPointingUp = true; // Always start pointing up
|
|
506
|
+
this.isPointingLeft = true; // Pointer on left side of target (bubble on right)
|
|
481
507
|
this.lastTargetY = null;
|
|
482
508
|
this._targetYHistory = []; // Track Y positions for velocity detection
|
|
483
509
|
this._lastDirectionChangeTime = 0; // Debounce direction changes
|
|
484
|
-
this.
|
|
510
|
+
this.manualHorizontalDirection = null; // 'left', 'right', or null (auto)
|
|
511
|
+
this.manualVerticalDirection = null; // 'up', 'down', or null (auto)
|
|
485
512
|
this.moveTimeout = null;
|
|
486
513
|
this._hasShownBefore = false; // For intro animation
|
|
487
514
|
|
|
@@ -585,10 +612,19 @@ class Pointy {
|
|
|
585
612
|
const targetRect = this.targetElement.getBoundingClientRect();
|
|
586
613
|
const scrollX = window.scrollX;
|
|
587
614
|
const scrollY = window.scrollY;
|
|
615
|
+
const viewportWidth = window.innerWidth;
|
|
616
|
+
const viewportHeight = window.innerHeight;
|
|
617
|
+
const bubbleWidth = this.bubble.offsetWidth || 100;
|
|
618
|
+
const bubbleHeight = this.bubble.offsetHeight || 28;
|
|
619
|
+
|
|
620
|
+
// Manual horizontal direction takes priority
|
|
621
|
+
if (this.manualHorizontalDirection !== null) {
|
|
622
|
+
this.isPointingLeft = this.manualHorizontalDirection === 'left';
|
|
623
|
+
}
|
|
588
624
|
|
|
589
|
-
// Manual direction takes priority
|
|
590
|
-
if (this.
|
|
591
|
-
this.isPointingUp = this.
|
|
625
|
+
// Manual vertical direction takes priority
|
|
626
|
+
if (this.manualVerticalDirection !== null) {
|
|
627
|
+
this.isPointingUp = this.manualVerticalDirection === 'up';
|
|
592
628
|
} else {
|
|
593
629
|
// Auto: Track velocity over time to detect movement direction
|
|
594
630
|
const currentTargetY = targetRect.top + scrollY;
|
|
@@ -624,30 +660,107 @@ class Pointy {
|
|
|
624
660
|
this.lastTargetY = currentTargetY;
|
|
625
661
|
}
|
|
626
662
|
|
|
663
|
+
// Stay in viewport: check if bubble would go off-screen and flip accordingly
|
|
664
|
+
// Only auto-flip directions that are not manually set
|
|
665
|
+
if (this.stayInViewport) {
|
|
666
|
+
const prevIsPointingLeft = this.isPointingLeft;
|
|
667
|
+
const prevIsPointingUp = this.isPointingUp;
|
|
668
|
+
|
|
669
|
+
// Horizontal flip check (only if not manually set)
|
|
670
|
+
if (this.manualHorizontalDirection === null) {
|
|
671
|
+
const bubbleLeftIfPointingLeft = targetRect.left - bubbleWidth - this.viewportThresholdX;
|
|
672
|
+
const bubbleRightIfPointingRight = targetRect.right + bubbleWidth + this.viewportThresholdX;
|
|
673
|
+
|
|
674
|
+
// Flip to right side if bubble goes off left edge
|
|
675
|
+
if (bubbleLeftIfPointingLeft < 0 && this.isPointingLeft) {
|
|
676
|
+
this.isPointingLeft = false;
|
|
677
|
+
}
|
|
678
|
+
// Flip to left side if bubble goes off right edge
|
|
679
|
+
else if (bubbleRightIfPointingRight > viewportWidth && !this.isPointingLeft) {
|
|
680
|
+
this.isPointingLeft = true;
|
|
681
|
+
}
|
|
682
|
+
// Return to default (left) if there's room
|
|
683
|
+
else if (bubbleLeftIfPointingLeft >= 0 && !this.isPointingLeft) {
|
|
684
|
+
this.isPointingLeft = true;
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
// Vertical flip check (only if not manually set)
|
|
689
|
+
if (this.manualVerticalDirection === null) {
|
|
690
|
+
const bubbleBottomIfPointingUp = targetRect.bottom + bubbleHeight + this.viewportThresholdY;
|
|
691
|
+
const bubbleTopIfPointingDown = targetRect.top - bubbleHeight - this.viewportThresholdY;
|
|
692
|
+
|
|
693
|
+
// Flip to pointing down if bubble goes off bottom edge
|
|
694
|
+
if (bubbleBottomIfPointingUp > viewportHeight && this.isPointingUp) {
|
|
695
|
+
this.isPointingUp = false;
|
|
696
|
+
}
|
|
697
|
+
// Flip to pointing up if bubble goes off top edge
|
|
698
|
+
else if (bubbleTopIfPointingDown < 0 && !this.isPointingUp) {
|
|
699
|
+
this.isPointingUp = true;
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
// Emit flip events if direction changed
|
|
704
|
+
if (prevIsPointingLeft !== this.isPointingLeft) {
|
|
705
|
+
this._emit('flipHorizontal', {
|
|
706
|
+
from: prevIsPointingLeft ? 'left' : 'right',
|
|
707
|
+
to: this.isPointingLeft ? 'left' : 'right'
|
|
708
|
+
});
|
|
709
|
+
}
|
|
710
|
+
if (prevIsPointingUp !== this.isPointingUp) {
|
|
711
|
+
this._emit('flipVertical', {
|
|
712
|
+
from: prevIsPointingUp ? 'up' : 'down',
|
|
713
|
+
to: this.isPointingUp ? 'up' : 'down'
|
|
714
|
+
});
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
|
|
627
718
|
// Pointer tip position varies based on rotation
|
|
628
719
|
// Default SVG (0deg): tip at approximately (25, 8) - points top-right
|
|
629
720
|
// Rotated 90deg: tip at approximately (25, 25) - points bottom-right
|
|
721
|
+
// Rotated -90deg (270deg): points top-left (flipped horizontally via rotation)
|
|
630
722
|
let left, top;
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
723
|
+
let pointerRotation;
|
|
724
|
+
let bubbleTransform;
|
|
725
|
+
|
|
726
|
+
if (this.isPointingLeft) {
|
|
727
|
+
// Pointer on LEFT side of target, bubble extends to the LEFT
|
|
728
|
+
if (this.isPointingUp) {
|
|
729
|
+
pointerRotation = 'rotate(0deg)';
|
|
730
|
+
left = targetRect.left + scrollX - 25 + this.offsetX;
|
|
731
|
+
top = targetRect.bottom + scrollY - 8 - this.offsetY;
|
|
732
|
+
bubbleTransform = 'translateY(28px)';
|
|
733
|
+
} else {
|
|
734
|
+
pointerRotation = 'rotate(90deg)';
|
|
735
|
+
left = targetRect.left + scrollX - 25 + this.offsetX;
|
|
736
|
+
top = targetRect.top + scrollY - 25 + this.offsetY;
|
|
737
|
+
bubbleTransform = `translateY(-${bubbleHeight}px)`;
|
|
738
|
+
}
|
|
739
|
+
// Bubble position: right of pointer (default CSS)
|
|
740
|
+
this.bubble.style.right = '26px';
|
|
741
|
+
this.bubble.style.left = 'auto';
|
|
640
742
|
} else {
|
|
641
|
-
// Pointer
|
|
642
|
-
this.
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
743
|
+
// Pointer on RIGHT side of target, bubble extends to the RIGHT
|
|
744
|
+
if (this.isPointingUp) {
|
|
745
|
+
// Rotate -90deg to point top-left instead of top-right
|
|
746
|
+
pointerRotation = 'rotate(-90deg)';
|
|
747
|
+
left = targetRect.right + scrollX - 8 - this.offsetX;
|
|
748
|
+
top = targetRect.bottom + scrollY - 25 - this.offsetY;
|
|
749
|
+
bubbleTransform = 'translateY(28px)';
|
|
750
|
+
} else {
|
|
751
|
+
// Rotate 180deg to point bottom-left
|
|
752
|
+
pointerRotation = 'rotate(180deg)';
|
|
753
|
+
left = targetRect.right + scrollX - 8 - this.offsetX;
|
|
754
|
+
top = targetRect.top + scrollY - 8 + this.offsetY;
|
|
755
|
+
bubbleTransform = `translateY(-${bubbleHeight}px)`;
|
|
756
|
+
}
|
|
757
|
+
// Bubble position: left of pointer (flipped)
|
|
758
|
+
this.bubble.style.left = '26px';
|
|
759
|
+
this.bubble.style.right = 'auto';
|
|
649
760
|
}
|
|
650
761
|
|
|
762
|
+
this.pointer.style.transform = pointerRotation;
|
|
763
|
+
this.bubble.style.transform = bubbleTransform;
|
|
651
764
|
this.container.style.left = `${left}px`;
|
|
652
765
|
this.container.style.top = `${top}px`;
|
|
653
766
|
}
|
|
@@ -1421,6 +1534,113 @@ class Pointy {
|
|
|
1421
1534
|
this._emit('zIndexChange', { from: oldValue, to: zIndex });
|
|
1422
1535
|
}
|
|
1423
1536
|
|
|
1537
|
+
/**
|
|
1538
|
+
* Set stayInViewport enabled/disabled with optional thresholds
|
|
1539
|
+
* @param {boolean} enabled - Whether stayInViewport is enabled
|
|
1540
|
+
* @param {object} [thresholds] - Optional threshold values { x?: number, y?: number }
|
|
1541
|
+
*/
|
|
1542
|
+
setStayInViewport(enabled, thresholds) {
|
|
1543
|
+
const oldEnabled = this.stayInViewport;
|
|
1544
|
+
const oldX = this.viewportThresholdX;
|
|
1545
|
+
const oldY = this.viewportThresholdY;
|
|
1546
|
+
|
|
1547
|
+
this.stayInViewport = enabled;
|
|
1548
|
+
|
|
1549
|
+
// Update thresholds if provided
|
|
1550
|
+
if (thresholds && typeof thresholds === 'object') {
|
|
1551
|
+
if (thresholds.x !== undefined) this.viewportThresholdX = thresholds.x;
|
|
1552
|
+
if (thresholds.y !== undefined) this.viewportThresholdY = thresholds.y;
|
|
1553
|
+
}
|
|
1554
|
+
|
|
1555
|
+
// Reset to default positions if disabling
|
|
1556
|
+
if (!enabled) {
|
|
1557
|
+
this.isPointingLeft = true;
|
|
1558
|
+
this.isPointingUp = true;
|
|
1559
|
+
}
|
|
1560
|
+
|
|
1561
|
+
this.updatePosition();
|
|
1562
|
+
this._emit('stayInViewportChange', {
|
|
1563
|
+
from: { enabled: oldEnabled, x: oldX, y: oldY },
|
|
1564
|
+
to: { enabled, x: this.viewportThresholdX, y: this.viewportThresholdY }
|
|
1565
|
+
});
|
|
1566
|
+
}
|
|
1567
|
+
|
|
1568
|
+
/**
|
|
1569
|
+
* Parse direction string into horizontal and vertical components
|
|
1570
|
+
* @private
|
|
1571
|
+
* @param {string|null} direction - Direction string like 'up', 'left', 'up-left', 'down-right', etc.
|
|
1572
|
+
*/
|
|
1573
|
+
_parseDirection(direction) {
|
|
1574
|
+
if (!direction) {
|
|
1575
|
+
this.manualHorizontalDirection = null;
|
|
1576
|
+
this.manualVerticalDirection = null;
|
|
1577
|
+
return;
|
|
1578
|
+
}
|
|
1579
|
+
|
|
1580
|
+
const dir = direction.toLowerCase();
|
|
1581
|
+
|
|
1582
|
+
// Parse horizontal component
|
|
1583
|
+
if (dir.includes('left')) {
|
|
1584
|
+
this.manualHorizontalDirection = 'left';
|
|
1585
|
+
} else if (dir.includes('right')) {
|
|
1586
|
+
this.manualHorizontalDirection = 'right';
|
|
1587
|
+
} else {
|
|
1588
|
+
this.manualHorizontalDirection = null;
|
|
1589
|
+
}
|
|
1590
|
+
|
|
1591
|
+
// Parse vertical component
|
|
1592
|
+
if (dir.includes('up')) {
|
|
1593
|
+
this.manualVerticalDirection = 'up';
|
|
1594
|
+
} else if (dir.includes('down')) {
|
|
1595
|
+
this.manualVerticalDirection = 'down';
|
|
1596
|
+
} else {
|
|
1597
|
+
this.manualVerticalDirection = null;
|
|
1598
|
+
}
|
|
1599
|
+
}
|
|
1600
|
+
|
|
1601
|
+
/**
|
|
1602
|
+
* Set the pointer direction manually
|
|
1603
|
+
* @param {string|null} direction - Direction: 'up', 'down', 'left', 'right', 'up-left', 'up-right', 'down-left', 'down-right', or null for auto
|
|
1604
|
+
*/
|
|
1605
|
+
setDirection(direction) {
|
|
1606
|
+
const oldH = this.manualHorizontalDirection;
|
|
1607
|
+
const oldV = this.manualVerticalDirection;
|
|
1608
|
+
|
|
1609
|
+
this._parseDirection(direction);
|
|
1610
|
+
|
|
1611
|
+
this.updatePosition();
|
|
1612
|
+
this._emit('directionChange', {
|
|
1613
|
+
from: { horizontal: oldH, vertical: oldV },
|
|
1614
|
+
to: { horizontal: this.manualHorizontalDirection, vertical: this.manualVerticalDirection }
|
|
1615
|
+
});
|
|
1616
|
+
}
|
|
1617
|
+
|
|
1618
|
+
/**
|
|
1619
|
+
* Set only the horizontal direction
|
|
1620
|
+
* @param {string|null} direction - 'left', 'right', or null for auto
|
|
1621
|
+
*/
|
|
1622
|
+
setHorizontalDirection(direction) {
|
|
1623
|
+
const oldValue = this.manualHorizontalDirection;
|
|
1624
|
+
if (oldValue === direction) return;
|
|
1625
|
+
|
|
1626
|
+
this.manualHorizontalDirection = direction;
|
|
1627
|
+
this.updatePosition();
|
|
1628
|
+
this._emit('horizontalDirectionChange', { from: oldValue, to: direction });
|
|
1629
|
+
}
|
|
1630
|
+
|
|
1631
|
+
/**
|
|
1632
|
+
* Set only the vertical direction
|
|
1633
|
+
* @param {string|null} direction - 'up', 'down', or null for auto
|
|
1634
|
+
*/
|
|
1635
|
+
setVerticalDirection(direction) {
|
|
1636
|
+
const oldValue = this.manualVerticalDirection;
|
|
1637
|
+
if (oldValue === direction) return;
|
|
1638
|
+
|
|
1639
|
+
this.manualVerticalDirection = direction;
|
|
1640
|
+
this.updatePosition();
|
|
1641
|
+
this._emit('verticalDirectionChange', { from: oldValue, to: direction });
|
|
1642
|
+
}
|
|
1643
|
+
|
|
1424
1644
|
setOffset(offsetX, offsetY) {
|
|
1425
1645
|
const oldOffsetX = this.offsetX;
|
|
1426
1646
|
const oldOffsetY = this.offsetY;
|
|
@@ -1744,8 +1964,8 @@ class Pointy {
|
|
|
1744
1964
|
fromTarget: previousTarget
|
|
1745
1965
|
});
|
|
1746
1966
|
|
|
1747
|
-
//
|
|
1748
|
-
this.
|
|
1967
|
+
// Parse direction: can be 'up', 'down', 'left', 'right', 'up-left', 'down-right', etc.
|
|
1968
|
+
this._parseDirection(step.direction);
|
|
1749
1969
|
|
|
1750
1970
|
// Reset velocity tracking for new target
|
|
1751
1971
|
this._targetYHistory = [];
|
|
@@ -2053,7 +2273,7 @@ class Pointy {
|
|
|
2053
2273
|
* When next() is called, it will continue from where it left off.
|
|
2054
2274
|
* @param {string|HTMLElement} target - The target element or selector
|
|
2055
2275
|
* @param {string} content - Optional content to show
|
|
2056
|
-
* @param {string} direction - Optional direction: 'up', 'down', or null for auto
|
|
2276
|
+
* @param {string} direction - Optional direction: 'up', 'down', 'left', 'right', 'up-left', 'down-right', etc. or null for auto
|
|
2057
2277
|
*/
|
|
2058
2278
|
pointTo(target, content, direction) {
|
|
2059
2279
|
const previousTarget = this.targetElement;
|
|
@@ -2068,8 +2288,8 @@ class Pointy {
|
|
|
2068
2288
|
fromTarget: previousTarget
|
|
2069
2289
|
});
|
|
2070
2290
|
|
|
2071
|
-
//
|
|
2072
|
-
this.
|
|
2291
|
+
// Parse direction (null means auto)
|
|
2292
|
+
this._parseDirection(direction);
|
|
2073
2293
|
|
|
2074
2294
|
// Reset velocity tracking for new target
|
|
2075
2295
|
this._targetYHistory = [];
|