@profitlich/template-toolkit 2.10.0 → 2.11.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.
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import '@mux/mux-player';
|
|
2
|
+
import config from '../../config.json' with { type: 'json' };
|
|
2
3
|
import './mux-player.scss';
|
|
3
4
|
|
|
4
5
|
export class MuxPlayer {
|
|
5
6
|
#lazyLoadObserver;
|
|
6
7
|
#playPauseObserver;
|
|
8
|
+
#loop;
|
|
9
|
+
#onPlayerCreated;
|
|
7
10
|
|
|
8
|
-
constructor() {
|
|
11
|
+
constructor({ loop = false, onPlayerCreated = null } = {}) {
|
|
12
|
+
this.#loop = loop;
|
|
13
|
+
this.#onPlayerCreated = onPlayerCreated;
|
|
9
14
|
this.#lazyLoadObserver = new IntersectionObserver(this.#handleLazyLoad.bind(this));
|
|
10
15
|
this.#playPauseObserver = new IntersectionObserver(this.#handlePlayPause.bind(this));
|
|
11
16
|
}
|
|
@@ -16,6 +21,40 @@ export class MuxPlayer {
|
|
|
16
21
|
});
|
|
17
22
|
}
|
|
18
23
|
|
|
24
|
+
#setupAutoplay(player) {
|
|
25
|
+
// Guard Clause: Führe das Setup nur aus, wenn es noch nicht passiert ist.
|
|
26
|
+
if (player.dataset.isSetup === 'true') {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
player.muted = true;
|
|
31
|
+
player.style.setProperty('--controls', 'none');
|
|
32
|
+
if (this.#loop) player.loop = true;
|
|
33
|
+
|
|
34
|
+
// Flag setzen, um zukünftige Ausführungen zu verhindern.
|
|
35
|
+
player.dataset.isSetup = 'true';
|
|
36
|
+
|
|
37
|
+
// Den playPauseObserver starten, sobald die Daten geladen sind.
|
|
38
|
+
if (player.readyState >= 2) { // HAVE_CURRENT_DATA oder höher
|
|
39
|
+
this.#playPauseObserver.observe(player);
|
|
40
|
+
} else {
|
|
41
|
+
player.addEventListener('loadeddata', () => {
|
|
42
|
+
this.#playPauseObserver.observe(player);
|
|
43
|
+
}, { once: true });
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
handleVisibilityChange(player) {
|
|
48
|
+
const isVisible = window.getComputedStyle(player).display !== 'none';
|
|
49
|
+
|
|
50
|
+
if (isVisible && player.hasAttribute('data-autoplay') && player.dataset.isSetup !== 'true') {
|
|
51
|
+
this.#setupAutoplay(player);
|
|
52
|
+
} else if (!isVisible) {
|
|
53
|
+
this.#playPauseObserver.unobserve(player);
|
|
54
|
+
player.pause();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
19
58
|
#handleLazyLoad(entries) {
|
|
20
59
|
for (const entry of entries) {
|
|
21
60
|
if (entry.isIntersecting) {
|
|
@@ -30,69 +69,28 @@ export class MuxPlayer {
|
|
|
30
69
|
player.streamType = 'on-demand';
|
|
31
70
|
player.playsInline = true;
|
|
32
71
|
player.style.aspectRatio = aspectRatio;
|
|
72
|
+
player.thumbnailTime = 0;
|
|
73
|
+
player.minResolution = config.muxMinResolution || '1080p';
|
|
74
|
+
|
|
75
|
+
if (container.dataset.accentColor) {
|
|
76
|
+
player.accentColor = container.dataset.accentColor;
|
|
77
|
+
}
|
|
33
78
|
|
|
34
|
-
// Autoplay-Attribut am Player-Element setzen, damit es später gefunden werden kann
|
|
35
79
|
if (autoplay) {
|
|
36
80
|
player.setAttribute('data-autoplay', 'true');
|
|
37
81
|
}
|
|
38
82
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
// Wenn ein Wrapper gefunden wird, richte den MutationObserver ein
|
|
42
|
-
if (wrapper) {
|
|
43
|
-
const visibilityObserver = new MutationObserver(() => {
|
|
44
|
-
this.#handleVisibilityChange(player);
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
// Beobachte den gefundenen Wrapper
|
|
48
|
-
visibilityObserver.observe(wrapper, { attributes: true, childList: true, subtree: true });
|
|
49
|
-
|
|
50
|
-
// Container durch Player ersetzen BEVOR die Sichtbarkeitsprüfung
|
|
51
|
-
container.replaceWith(player);
|
|
83
|
+
container.replaceWith(player);
|
|
52
84
|
|
|
53
|
-
|
|
54
|
-
this.#
|
|
85
|
+
if (this.#onPlayerCreated) {
|
|
86
|
+
this.#onPlayerCreated(player, container);
|
|
55
87
|
} else if (autoplay) {
|
|
56
|
-
|
|
57
|
-
player.muted = true;
|
|
58
|
-
player.style.setProperty('--controls', 'none');
|
|
59
|
-
container.replaceWith(player);
|
|
60
|
-
|
|
61
|
-
player.addEventListener('loadeddata', () => {
|
|
62
|
-
this.#playPauseObserver.observe(player);
|
|
63
|
-
});
|
|
64
|
-
} else {
|
|
65
|
-
// Für Videos ohne Autoplay
|
|
66
|
-
container.replaceWith(player);
|
|
88
|
+
this.handleVisibilityChange(player);
|
|
67
89
|
}
|
|
68
90
|
}
|
|
69
91
|
}
|
|
70
92
|
}
|
|
71
93
|
|
|
72
|
-
#handleVisibilityChange(player) {
|
|
73
|
-
// Prüfe direkt am Player, ob er durch CSS sichtbar ist
|
|
74
|
-
const isVisible = window.getComputedStyle(player).display !== 'none';
|
|
75
|
-
|
|
76
|
-
if (isVisible && player.hasAttribute('data-autoplay')) {
|
|
77
|
-
// Wenn der Player sichtbar ist und Autoplay haben soll
|
|
78
|
-
player.muted = true;
|
|
79
|
-
player.style.setProperty('--controls', 'none');
|
|
80
|
-
|
|
81
|
-
// Warte auf loadeddata bevor der IntersectionObserver aktiviert wird
|
|
82
|
-
if (player.readyState >= 2) { // HAVE_CURRENT_DATA oder höher
|
|
83
|
-
this.#playPauseObserver.observe(player);
|
|
84
|
-
} else {
|
|
85
|
-
player.addEventListener('loadeddata', () => {
|
|
86
|
-
this.#playPauseObserver.observe(player);
|
|
87
|
-
}, { once: true });
|
|
88
|
-
}
|
|
89
|
-
} else if (!isVisible) {
|
|
90
|
-
// Wenn der Player unsichtbar wird, pausiere ihn und stoppe die Beobachtung
|
|
91
|
-
this.#playPauseObserver.unobserve(player);
|
|
92
|
-
player.pause();
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
94
|
#handlePlayPause(entries) {
|
|
97
95
|
for (const entry of entries) {
|
|
98
96
|
const player = entry.target;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@profitlich/template-toolkit",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.11.1",
|
|
4
4
|
"description": "Shared SCSS layout system, JS utilities, components and build scripts for profitlich template repos",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"./utils/MailAdresses": "./utils/MailAdresses.js",
|
|
17
17
|
"./utils/MediaQueries": "./utils/MediaQueries.js",
|
|
18
18
|
"./utils/Vh100": "./utils/Vh100.js",
|
|
19
|
+
"./utils/ImagesLoaded": "./utils/images-loaded/ImagesLoaded.js",
|
|
19
20
|
"./scripts/copy-files": "./scripts/copy-files.js",
|
|
20
21
|
"./scripts/deploy": "./scripts/deploy.js",
|
|
21
22
|
"./vite/jsonToScss": "./vite/jsonToScss.js"
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import './images-loaded.scss';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Steuert das sanfte Einblenden von Bildern, die nativ (loading="lazy") geladen wurden.
|
|
5
|
+
* Fügt dem Bild das Attribut 'loaded="true"' hinzu, sobald der Ladevorgang erfolgreich abgeschlossen ist.
|
|
6
|
+
*/
|
|
7
|
+
export class ImagesLoaded {
|
|
8
|
+
#selector;
|
|
9
|
+
#attributeName;
|
|
10
|
+
#attributeValue;
|
|
11
|
+
|
|
12
|
+
constructor(selector, loadedAttribute = 'data-loaded', loadedValue = 'true') {
|
|
13
|
+
this.#selector = selector;
|
|
14
|
+
this.#attributeName = loadedAttribute;
|
|
15
|
+
this.#attributeValue = loadedValue;
|
|
16
|
+
|
|
17
|
+
// Führt die Initialisierung erst nach dem vollständigen Laden des DOM aus.
|
|
18
|
+
document.addEventListener('DOMContentLoaded', this.#init.bind(this));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
#init() {
|
|
22
|
+
const images = document.querySelectorAll(this.#selector);
|
|
23
|
+
images.forEach(img => this.#setupImage(img));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
#setupImage(img) {
|
|
27
|
+
// Prüfen auf geladenen Zustand und gültige Dimensionen
|
|
28
|
+
if (img.complete && img.naturalHeight > 0) {
|
|
29
|
+
this.#signalLoaded(img);
|
|
30
|
+
} else {
|
|
31
|
+
// Ansonsten auf das erfolgreiche Lade-Event warten
|
|
32
|
+
img.addEventListener('load', () => this.#signalLoaded(img));
|
|
33
|
+
|
|
34
|
+
// Fehlerbehandlung (optional)
|
|
35
|
+
img.addEventListener('error', () => {
|
|
36
|
+
console.warn(`[ImagesLoaded] Ladevorgang fehlgeschlagen für: ${img.src}`);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
#signalLoaded(img) {
|
|
42
|
+
img.setAttribute(this.#attributeName, this.#attributeValue);
|
|
43
|
+
}
|
|
44
|
+
}
|