myetv-player 1.0.6 → 1.0.10
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 +13 -0
- package/css/myetv-player.css +374 -208
- package/css/myetv-player.min.css +1 -1
- package/dist/myetv-player.js +213 -31
- package/dist/myetv-player.min.js +188 -20
- package/package.json +3 -1
- package/plugins/youtube/README.md +13 -5
- package/plugins/youtube/myetv-player-youtube-plugin.js +1150 -141
- package/scss/_base.scss +0 -15
- package/scss/_controls.scss +311 -30
- package/scss/_menus.scss +51 -0
- package/scss/_responsive.scss +187 -321
- package/scss/_video.scss +0 -75
- package/scss/_watermark.scss +120 -0
- package/scss/myetv-player.scss +7 -7
- package/src/controls.js +73 -22
- package/src/core.js +56 -4
- package/src/events.js +33 -5
- package/src/watermark.js +51 -0
package/dist/myetv-player.js
CHANGED
|
@@ -448,6 +448,8 @@ constructor(videoElement, options = {}) {
|
|
|
448
448
|
dashLibUrl: 'https://cdn.dashjs.org/latest/dash.all.min.js', // Dash.js library URL
|
|
449
449
|
hlsLibUrl: 'https://cdn.jsdelivr.net/npm/hls.js@latest', // HLS.js library URL
|
|
450
450
|
adaptiveQualityControl: true, // Show quality control for adaptive streams
|
|
451
|
+
//seek shape
|
|
452
|
+
seekHandleShape: 'circle', // Available shape: none, circle, square, diamond, arrow, triangle, heart, star
|
|
451
453
|
// AUDIO PLAYER
|
|
452
454
|
audiofile: false,
|
|
453
455
|
audiowave: false,
|
|
@@ -1531,14 +1533,19 @@ seek(e) {
|
|
|
1531
1533
|
if (!this.video || !this.progressContainer || !this.progressFilled || !this.progressHandle || this.isChangingQuality) return;
|
|
1532
1534
|
|
|
1533
1535
|
const rect = this.progressContainer.getBoundingClientRect();
|
|
1534
|
-
|
|
1536
|
+
|
|
1537
|
+
// Support both mouse and touch events
|
|
1538
|
+
const clientX = e.clientX !== undefined ? e.clientX : (e.touches && e.touches[0] ? e.touches[0].clientX : (e.changedTouches && e.changedTouches[0] ? e.changedTouches[0].clientX : 0));
|
|
1539
|
+
|
|
1540
|
+
const clickX = clientX - rect.left;
|
|
1535
1541
|
const percentage = Math.max(0, Math.min(1, clickX / rect.width));
|
|
1536
1542
|
|
|
1537
1543
|
if (this.video.duration && !isNaN(this.video.duration)) {
|
|
1538
1544
|
this.video.currentTime = percentage * this.video.duration;
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
this.
|
|
1545
|
+
|
|
1546
|
+
const progress = `${percentage * 100}%`;
|
|
1547
|
+
this.progressFilled.style.width = progress;
|
|
1548
|
+
this.progressHandle.style.left = progress;
|
|
1542
1549
|
}
|
|
1543
1550
|
}
|
|
1544
1551
|
|
|
@@ -2091,6 +2098,51 @@ loadScript(src) {
|
|
|
2091
2098
|
});
|
|
2092
2099
|
}
|
|
2093
2100
|
|
|
2101
|
+
/**
|
|
2102
|
+
* Set seek handle shape dynamically
|
|
2103
|
+
* @param {string} shape - Shape type: none, circle, square, diamond, arrow, triangle, heart, star
|
|
2104
|
+
* @returns {Object} this
|
|
2105
|
+
*/
|
|
2106
|
+
setSeekHandleShape(shape) {
|
|
2107
|
+
const validShapes = ['none', 'circle', 'square', 'diamond', 'arrow', 'triangle', 'heart', 'star'];
|
|
2108
|
+
|
|
2109
|
+
if (!validShapes.includes(shape)) {
|
|
2110
|
+
if (this.options.debug) console.warn('Invalid seek handle shape:', shape);
|
|
2111
|
+
return this;
|
|
2112
|
+
}
|
|
2113
|
+
|
|
2114
|
+
this.options.seekHandleShape = shape;
|
|
2115
|
+
|
|
2116
|
+
// Update handle class
|
|
2117
|
+
if (this.progressHandle) {
|
|
2118
|
+
// Remove all shape classes
|
|
2119
|
+
validShapes.forEach(s => {
|
|
2120
|
+
this.progressHandle.classList.remove(`progress-handle-${s}`);
|
|
2121
|
+
});
|
|
2122
|
+
// Add new shape class
|
|
2123
|
+
this.progressHandle.classList.add(`progress-handle-${shape}`);
|
|
2124
|
+
}
|
|
2125
|
+
|
|
2126
|
+
if (this.options.debug) console.log('Seek handle shape changed to:', shape);
|
|
2127
|
+
return this;
|
|
2128
|
+
}
|
|
2129
|
+
|
|
2130
|
+
/**
|
|
2131
|
+
* Get current seek handle shape
|
|
2132
|
+
* @returns {string} Current shape
|
|
2133
|
+
*/
|
|
2134
|
+
getSeekHandleShape() {
|
|
2135
|
+
return this.options.seekHandleShape;
|
|
2136
|
+
}
|
|
2137
|
+
|
|
2138
|
+
/**
|
|
2139
|
+
* Get available seek handle shapes
|
|
2140
|
+
* @returns {Array} Array of available shapes
|
|
2141
|
+
*/
|
|
2142
|
+
getAvailableSeekHandleShapes() {
|
|
2143
|
+
return ['none', 'circle', 'square', 'diamond', 'arrow', 'triangle', 'heart', 'star'];
|
|
2144
|
+
}
|
|
2145
|
+
|
|
2094
2146
|
dispose() {
|
|
2095
2147
|
if (this.qualityMonitorInterval) {
|
|
2096
2148
|
clearInterval(this.qualityMonitorInterval);
|
|
@@ -2467,12 +2519,28 @@ addEventListener(eventType, callback) {
|
|
|
2467
2519
|
});
|
|
2468
2520
|
}
|
|
2469
2521
|
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2522
|
+
if (this.progressContainer) {
|
|
2523
|
+
// Mouse events (desktop)
|
|
2524
|
+
this.progressContainer.addEventListener('click', (e) => this.seek(e));
|
|
2525
|
+
this.progressContainer.addEventListener('mousedown', (e) => this.startSeeking(e));
|
|
2526
|
+
|
|
2527
|
+
// Touch events (mobile)
|
|
2528
|
+
this.progressContainer.addEventListener('touchstart', (e) => {
|
|
2529
|
+
e.preventDefault(); // Prevent scrolling when touching the seek bar
|
|
2530
|
+
this.startSeeking(e);
|
|
2531
|
+
}, { passive: false });
|
|
2474
2532
|
|
|
2475
2533
|
this.setupSeekTooltip();
|
|
2534
|
+
}
|
|
2535
|
+
|
|
2536
|
+
// Add touch events directly on the handle for better mobile dragging
|
|
2537
|
+
if (this.progressHandle) {
|
|
2538
|
+
this.progressHandle.addEventListener('touchstart', (e) => {
|
|
2539
|
+
e.preventDefault(); // Prevent default touch behavior
|
|
2540
|
+
e.stopPropagation(); // Stop event from bubbling to progressContainer
|
|
2541
|
+
this.startSeeking(e);
|
|
2542
|
+
}, { passive: false });
|
|
2543
|
+
}
|
|
2476
2544
|
|
|
2477
2545
|
// NOTE: Auto-hide events are handled in initAutoHide() after everything is ready
|
|
2478
2546
|
|
|
@@ -2493,7 +2561,19 @@ addEventListener(eventType, callback) {
|
|
|
2493
2561
|
document.addEventListener('mozfullscreenchange', () => this.updateFullscreenButton());
|
|
2494
2562
|
|
|
2495
2563
|
document.addEventListener('mousemove', (e) => this.continueSeeking(e));
|
|
2496
|
-
|
|
2564
|
+
document.addEventListener('mouseup', () => this.endSeeking());
|
|
2565
|
+
|
|
2566
|
+
// Touch events for seeking (mobile)
|
|
2567
|
+
document.addEventListener('touchmove', (e) => {
|
|
2568
|
+
if (this.isUserSeeking) {
|
|
2569
|
+
e.preventDefault(); // Prevent scrolling while seeking
|
|
2570
|
+
this.continueSeeking(e);
|
|
2571
|
+
}
|
|
2572
|
+
}, { passive: false });
|
|
2573
|
+
|
|
2574
|
+
document.addEventListener('touchend', () => this.endSeeking());
|
|
2575
|
+
document.addEventListener('touchcancel', () => this.endSeeking());
|
|
2576
|
+
|
|
2497
2577
|
}
|
|
2498
2578
|
|
|
2499
2579
|
/* Controls Module for MYETV Video Player
|
|
@@ -2501,7 +2581,7 @@ addEventListener(eventType, callback) {
|
|
|
2501
2581
|
* Created by https://www.myetv.tv https://oskarcosimo.com
|
|
2502
2582
|
*/
|
|
2503
2583
|
|
|
2504
|
-
/* AUTO-HIDE SYSTEM
|
|
2584
|
+
/* AUTO-HIDE SYSTEM */
|
|
2505
2585
|
initAutoHide() {
|
|
2506
2586
|
if (!this.options.autoHide) {
|
|
2507
2587
|
if (this.options.debug) console.log('Auto-hide disabled in options');
|
|
@@ -2641,12 +2721,17 @@ showControlsNow() {
|
|
|
2641
2721
|
this.controls.classList.add('show');
|
|
2642
2722
|
}
|
|
2643
2723
|
|
|
2644
|
-
//
|
|
2724
|
+
// Add has-controls class to container for watermark visibility
|
|
2645
2725
|
if (this.container) {
|
|
2646
2726
|
this.container.classList.add('has-controls');
|
|
2727
|
+
this.updateControlbarHeight();
|
|
2728
|
+
// Update watermark position
|
|
2729
|
+
if (this.updateWatermarkPosition) {
|
|
2730
|
+
this.updateWatermarkPosition();
|
|
2731
|
+
}
|
|
2647
2732
|
}
|
|
2648
2733
|
|
|
2649
|
-
//
|
|
2734
|
+
// Show title overlay with controls if not persistent
|
|
2650
2735
|
if (this.options.showTitleOverlay && !this.options.persistentTitle && this.options.videoTitle) {
|
|
2651
2736
|
this.showTitleOverlay();
|
|
2652
2737
|
}
|
|
@@ -2657,32 +2742,44 @@ showControlsNow() {
|
|
|
2657
2742
|
hideControlsNow() {
|
|
2658
2743
|
// Don't hide if mouse is still over controls (allow hiding on touch devices)
|
|
2659
2744
|
const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0;
|
|
2745
|
+
|
|
2660
2746
|
if (this.mouseOverControls && !isTouchDevice) {
|
|
2661
|
-
if (this.autoHideDebug && this.options.debug)
|
|
2747
|
+
if (this.autoHideDebug && this.options.debug) {
|
|
2748
|
+
console.log('🚫 Not hiding - mouse still over controls');
|
|
2749
|
+
}
|
|
2662
2750
|
return;
|
|
2663
2751
|
}
|
|
2664
2752
|
|
|
2665
2753
|
// Don't hide if video is paused
|
|
2666
2754
|
if (this.video && this.video.paused) {
|
|
2667
|
-
if (this.autoHideDebug && this.options.debug)
|
|
2755
|
+
if (this.autoHideDebug && this.options.debug) {
|
|
2756
|
+
console.log('🚫 Not hiding - video is paused');
|
|
2757
|
+
}
|
|
2668
2758
|
return;
|
|
2669
2759
|
}
|
|
2670
2760
|
|
|
2671
2761
|
if (this.controls) {
|
|
2672
2762
|
this.controls.classList.remove('show');
|
|
2673
|
-
}
|
|
2674
2763
|
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2764
|
+
// Remove has-controls class from container for watermark visibility
|
|
2765
|
+
if (this.container) {
|
|
2766
|
+
this.container.classList.remove('has-controls');
|
|
2767
|
+
this.updateControlbarHeight();
|
|
2768
|
+
// Update watermark position
|
|
2769
|
+
if (this.updateWatermarkPosition) {
|
|
2770
|
+
this.updateWatermarkPosition();
|
|
2771
|
+
}
|
|
2772
|
+
}
|
|
2678
2773
|
}
|
|
2679
2774
|
|
|
2680
|
-
//
|
|
2775
|
+
// Hide title overlay with controls (if not persistent)
|
|
2681
2776
|
if (this.options.showTitleOverlay && !this.options.persistentTitle) {
|
|
2682
2777
|
this.hideTitleOverlay();
|
|
2683
2778
|
}
|
|
2684
2779
|
|
|
2685
|
-
if (this.autoHideDebug && this.options.debug)
|
|
2780
|
+
if (this.autoHideDebug && this.options.debug) {
|
|
2781
|
+
console.log('👁️ Controls hidden');
|
|
2782
|
+
}
|
|
2686
2783
|
}
|
|
2687
2784
|
|
|
2688
2785
|
showControls() {
|
|
@@ -2851,7 +2948,7 @@ createControls() {
|
|
|
2851
2948
|
<div class="progress-bar">
|
|
2852
2949
|
<div class="progress-buffer"></div>
|
|
2853
2950
|
<div class="progress-filled"></div>
|
|
2854
|
-
<div class="progress-handle"></div>
|
|
2951
|
+
<div class="progress-handle progress-handle-${this.options.seekHandleShape}"></div>
|
|
2855
2952
|
</div>
|
|
2856
2953
|
${this.options.showSeekTooltip ? '<div class="seek-tooltip">0:00</div>' : ''}
|
|
2857
2954
|
</div>
|
|
@@ -2961,28 +3058,62 @@ createControls() {
|
|
|
2961
3058
|
// NEW: Initialize responsive settings menu
|
|
2962
3059
|
setTimeout(() => {
|
|
2963
3060
|
this.initializeResponsiveMenu();
|
|
3061
|
+
this.updateControlbarHeight();
|
|
2964
3062
|
}, 100);
|
|
2965
3063
|
}
|
|
2966
3064
|
|
|
2967
|
-
/*
|
|
3065
|
+
/* Initialize responsive menu with dynamic width calculation */
|
|
2968
3066
|
initializeResponsiveMenu() {
|
|
2969
3067
|
if (!this.controls) return;
|
|
2970
3068
|
|
|
2971
3069
|
// Track screen size
|
|
2972
3070
|
this.isSmallScreen = false;
|
|
2973
3071
|
|
|
2974
|
-
// Check initial size
|
|
3072
|
+
// Check initial size
|
|
2975
3073
|
this.checkScreenSize();
|
|
2976
3074
|
|
|
2977
|
-
|
|
3075
|
+
// Bind resize handler with updateControlbarHeight
|
|
3076
|
+
const resizeHandler = () => {
|
|
2978
3077
|
this.checkScreenSize();
|
|
2979
|
-
|
|
3078
|
+
this.updateControlbarHeight();
|
|
3079
|
+
};
|
|
3080
|
+
|
|
3081
|
+
// Bind del context
|
|
3082
|
+
this.resizeHandler = resizeHandler.bind(this);
|
|
3083
|
+
window.addEventListener('resize', this.resizeHandler);
|
|
2980
3084
|
|
|
2981
3085
|
// Bind events for settings menu
|
|
2982
3086
|
this.bindSettingsMenuEvents();
|
|
2983
3087
|
}
|
|
2984
3088
|
|
|
2985
|
-
|
|
3089
|
+
// Dynamic controlbar height tracking for watermark positioning
|
|
3090
|
+
updateControlbarHeight() {
|
|
3091
|
+
if (!this.controls) return;
|
|
3092
|
+
|
|
3093
|
+
const height = this.controls.offsetHeight;
|
|
3094
|
+
if (this.container) {
|
|
3095
|
+
|
|
3096
|
+
this.container.style.setProperty('--player-controls-height', `${height}px`);
|
|
3097
|
+
|
|
3098
|
+
const watermark = this.container.querySelector('.video-watermark.watermark-bottomleft, .video-watermark.watermark-bottomright');
|
|
3099
|
+
if (watermark) {
|
|
3100
|
+
const hasControls = this.container.classList.contains('has-controls');
|
|
3101
|
+
const isHideOnAutoHide = watermark.classList.contains('hide-on-autohide');
|
|
3102
|
+
|
|
3103
|
+
if (hasControls || !isHideOnAutoHide) {
|
|
3104
|
+
watermark.style.bottom = `${height + 15}px`;
|
|
3105
|
+
} else {
|
|
3106
|
+
watermark.style.bottom = '15px';
|
|
3107
|
+
}
|
|
3108
|
+
}
|
|
3109
|
+
}
|
|
3110
|
+
|
|
3111
|
+
if (this.options.debug) {
|
|
3112
|
+
console.log(`Controlbar height updated: ${height}px`);
|
|
3113
|
+
}
|
|
3114
|
+
}
|
|
3115
|
+
|
|
3116
|
+
/* Dynamic width calculation based on logo presence */
|
|
2986
3117
|
getResponsiveThreshold() {
|
|
2987
3118
|
// Check if brand logo is enabled and present
|
|
2988
3119
|
const hasLogo = this.options.brandLogoEnabled && this.options.brandLogoUrl;
|
|
@@ -2991,7 +3122,7 @@ getResponsiveThreshold() {
|
|
|
2991
3122
|
return hasLogo ? 650 : 550;
|
|
2992
3123
|
}
|
|
2993
3124
|
|
|
2994
|
-
/*
|
|
3125
|
+
/* Check if screen is under dynamic threshold */
|
|
2995
3126
|
checkScreenSize() {
|
|
2996
3127
|
const threshold = this.getResponsiveThreshold();
|
|
2997
3128
|
const newIsSmallScreen = window.innerWidth <= threshold;
|
|
@@ -3001,12 +3132,12 @@ checkScreenSize() {
|
|
|
3001
3132
|
this.updateSettingsMenuVisibility();
|
|
3002
3133
|
|
|
3003
3134
|
if (this.options.debug) {
|
|
3004
|
-
console.log(`Screen check: ${window.innerWidth}px vs ${threshold}px threshold
|
|
3135
|
+
console.log(`Screen check: ${window.innerWidth}px vs ${threshold}px (threshold), logo: ${this.options.brandLogoEnabled}, small: ${this.isSmallScreen}`);
|
|
3005
3136
|
}
|
|
3006
3137
|
}
|
|
3007
3138
|
}
|
|
3008
3139
|
|
|
3009
|
-
/*
|
|
3140
|
+
/* Update settings menu visibility based on screen size */
|
|
3010
3141
|
updateSettingsMenuVisibility() {
|
|
3011
3142
|
const settingsControl = this.controls?.querySelector('.settings-control');
|
|
3012
3143
|
if (!settingsControl) return;
|
|
@@ -3046,7 +3177,7 @@ updateSettingsMenuVisibility() {
|
|
|
3046
3177
|
}
|
|
3047
3178
|
}
|
|
3048
3179
|
|
|
3049
|
-
/*
|
|
3180
|
+
/* Populate settings menu with controls */
|
|
3050
3181
|
populateSettingsMenu() {
|
|
3051
3182
|
const settingsMenu = this.controls?.querySelector('.settings-menu');
|
|
3052
3183
|
if (!settingsMenu) return;
|
|
@@ -3108,7 +3239,7 @@ populateSettingsMenu() {
|
|
|
3108
3239
|
settingsMenu.innerHTML = menuHTML;
|
|
3109
3240
|
}
|
|
3110
3241
|
|
|
3111
|
-
/*
|
|
3242
|
+
/* Bind settings menu events */
|
|
3112
3243
|
bindSettingsMenuEvents() {
|
|
3113
3244
|
const settingsMenu = this.controls?.querySelector('.settings-menu');
|
|
3114
3245
|
if (!settingsMenu) return;
|
|
@@ -5737,9 +5868,19 @@ initializeWatermark() {
|
|
|
5737
5868
|
this.container.appendChild(watermark);
|
|
5738
5869
|
}
|
|
5739
5870
|
|
|
5871
|
+
// Store reference to watermark element
|
|
5740
5872
|
// Store reference to watermark element
|
|
5741
5873
|
this.watermarkElement = watermark;
|
|
5742
5874
|
|
|
5875
|
+
// Set initial position
|
|
5876
|
+
this.updateWatermarkPosition();
|
|
5877
|
+
|
|
5878
|
+
// Update position on window resize
|
|
5879
|
+
this.watermarkResizeHandler = () => {
|
|
5880
|
+
this.updateWatermarkPosition();
|
|
5881
|
+
};
|
|
5882
|
+
window.addEventListener('resize', this.watermarkResizeHandler);
|
|
5883
|
+
|
|
5743
5884
|
if (this.options.debug) {
|
|
5744
5885
|
console.log('🏷️ Watermark created:', {
|
|
5745
5886
|
url: this.options.watermarkUrl,
|
|
@@ -5758,6 +5899,7 @@ initializeWatermark() {
|
|
|
5758
5899
|
* @param {string} position - Position of watermark (topleft, topright, bottomleft, bottomright)
|
|
5759
5900
|
* @param {string} title - Optional tooltip title for the watermark
|
|
5760
5901
|
*/
|
|
5902
|
+
|
|
5761
5903
|
setWatermark(url, link = '', position = 'bottomright', title = '') {
|
|
5762
5904
|
// Update options
|
|
5763
5905
|
this.options.watermarkUrl = url;
|
|
@@ -5788,6 +5930,12 @@ removeWatermark() {
|
|
|
5788
5930
|
this.watermarkElement = null;
|
|
5789
5931
|
}
|
|
5790
5932
|
|
|
5933
|
+
// Remove resize listener
|
|
5934
|
+
if (this.watermarkResizeHandler) {
|
|
5935
|
+
window.removeEventListener('resize', this.watermarkResizeHandler);
|
|
5936
|
+
this.watermarkResizeHandler = null;
|
|
5937
|
+
}
|
|
5938
|
+
|
|
5791
5939
|
this.options.watermarkUrl = '';
|
|
5792
5940
|
this.options.watermarkLink = '';
|
|
5793
5941
|
this.options.watermarkPosition = 'bottomright';
|
|
@@ -5802,6 +5950,7 @@ removeWatermark() {
|
|
|
5802
5950
|
* Update watermark position
|
|
5803
5951
|
* @param {string} position - New position (topleft, topright, bottomleft, bottomright)
|
|
5804
5952
|
*/
|
|
5953
|
+
|
|
5805
5954
|
setWatermarkPosition(position) {
|
|
5806
5955
|
if (!['topleft', 'topright', 'bottomleft', 'bottomright'].includes(position)) {
|
|
5807
5956
|
if (this.options.debug) console.warn('🏷️ Invalid watermark position:', position);
|
|
@@ -5828,6 +5977,39 @@ setWatermarkPosition(position) {
|
|
|
5828
5977
|
return this;
|
|
5829
5978
|
}
|
|
5830
5979
|
|
|
5980
|
+
/**
|
|
5981
|
+
* Update watermark position based on current controlbar height
|
|
5982
|
+
* Called during window resize to keep watermark above controlbar
|
|
5983
|
+
*/
|
|
5984
|
+
updateWatermarkPosition() {
|
|
5985
|
+
if (!this.watermarkElement) return;
|
|
5986
|
+
if (!this.controls) return;
|
|
5987
|
+
|
|
5988
|
+
const position = this.options.watermarkPosition || 'bottomright';
|
|
5989
|
+
|
|
5990
|
+
// Only update bottom positions (top positions don't need adjustment)
|
|
5991
|
+
if (position === 'bottomleft' || position === 'bottomright') {
|
|
5992
|
+
const controlsHeight = this.controls.offsetHeight;
|
|
5993
|
+
const spacing = 15; // Same spacing used in CSS
|
|
5994
|
+
const bottomValue = controlsHeight + spacing;
|
|
5995
|
+
|
|
5996
|
+
// Check if controls are visible
|
|
5997
|
+
const hasControls = this.container.classList.contains('has-controls');
|
|
5998
|
+
|
|
5999
|
+
if (hasControls || !this.options.hideWatermark) {
|
|
6000
|
+
// Position above controlbar
|
|
6001
|
+
this.watermarkElement.style.bottom = `${bottomValue}px`;
|
|
6002
|
+
} else {
|
|
6003
|
+
// Position at bottom corner when controls hidden
|
|
6004
|
+
this.watermarkElement.style.bottom = '15px';
|
|
6005
|
+
}
|
|
6006
|
+
|
|
6007
|
+
if (this.options.debug) {
|
|
6008
|
+
console.log(`🏷️ Watermark position updated: bottom ${this.watermarkElement.style.bottom}`);
|
|
6009
|
+
}
|
|
6010
|
+
}
|
|
6011
|
+
}
|
|
6012
|
+
|
|
5831
6013
|
/**
|
|
5832
6014
|
* Set whether watermark should hide with controls
|
|
5833
6015
|
* @param {boolean} hide - True to hide watermark with controls, false to keep always visible
|