MikaFil commited on
Commit
97898ae
·
verified ·
1 Parent(s): 9519322

fullscreen_playcanvas.js

Browse files
Files changed (1) hide show
  1. fullscreen_playcanvas.js +0 -213
fullscreen_playcanvas.js DELETED
@@ -1,213 +0,0 @@
1
- // fullscreen.js
2
- (function () {
3
- // ─── 1. Localiser la balise <script> ────────────────────────────────────────
4
- const scriptTag = document.currentScript || (function () {
5
- const all = document.getElementsByTagName('script');
6
- for (let i = all.length - 1; i >= 0; i--) {
7
- if (all[i].src && all[i].src.includes('fullscreen.js')) return all[i];
8
- }
9
- return all[all.length - 1];
10
- })();
11
-
12
- const playcanvasUrl = scriptTag.getAttribute('data-src');
13
- if (!playcanvasUrl) return;
14
-
15
- const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
16
- const id = Math.random().toString(36).substr(2, 8);
17
-
18
- // ─── 4. Calcul des ratios (Desktop & Mobile Portrait) ────────────────────────
19
- function computeAspectPadding(aspectStr) {
20
- if (!aspectStr) return null;
21
- if (aspectStr.includes(':')) {
22
- const [w, h] = aspectStr.split(':').map(Number);
23
- return (w > 0 && h > 0) ? (h / w) * 100 + '%' : null;
24
- }
25
- const v = parseFloat(aspectStr);
26
- return (v > 0) ? (100 / v) + '%' : null;
27
- }
28
-
29
- const desktopPadding = computeAspectPadding(scriptTag.getAttribute('data-aspect')) || '56.25%';
30
- const mobilePadding = computeAspectPadding(scriptTag.getAttribute('data-aspect-mobile')) || desktopPadding;
31
-
32
- // ─── 5. Injection du CSS avec Media Queries ──────────────────────────────────
33
- const style = document.createElement('style');
34
- style.textContent = `
35
- .pc-embed-wrapper-${id} {
36
- position: relative;
37
- width: 100%;
38
- height: 0;
39
- overflow: hidden;
40
- background: #000;
41
- box-sizing: border-box;
42
- /* Ratio par défaut (Paysage / Desktop) */
43
- padding-bottom: ${desktopPadding};
44
- }
45
-
46
- /* Ratio Mobile Portrait : appliqué uniquement si l'écran est plus haut que large */
47
- @media (orientation: portrait) and (max-width: 768px) {
48
- .pc-embed-wrapper-${id} {
49
- padding-bottom: ${mobilePadding};
50
- }
51
- }
52
-
53
- .pc-embed-wrapper-${id}.fake-fullscreen {
54
- position: fixed !important;
55
- top: 0 !important;
56
- left: 0 !important;
57
- width: 100vw !important;
58
- height: 100vh !important;
59
- height: 100dvh !important;
60
- max-width: 100vw !important;
61
- max-height: 100dvh !important;
62
- padding-bottom: 0 !important;
63
- margin: 0 !important;
64
- z-index: 99999;
65
- }
66
- .pc-embed-inner-${id} {
67
- position: absolute;
68
- top: 0; left: 0;
69
- width: 100%; height: 100%;
70
- }
71
- .pc-embed-inner-${id} iframe {
72
- width: 100%; height: 100%;
73
- border: none;
74
- display: block;
75
- }
76
- .pc-fs-btn-${id} {
77
- position: absolute;
78
- top: 10px;
79
- right: 10px;
80
- z-index: 10;
81
- width: 36px;
82
- height: 36px;
83
- border-radius: 50%;
84
- border: none;
85
- background: #2E2E2EB3;
86
- color: #fff;
87
- font-size: 18px;
88
- line-height: 36px;
89
- text-align: center;
90
- cursor: pointer;
91
- user-select: none;
92
- }
93
- `;
94
- document.head.appendChild(style);
95
-
96
- // ─── 6. Construction du DOM ──────────────────────────────────────────────────
97
- const wrapper = document.createElement('div');
98
- wrapper.className = `pc-embed-wrapper-${id}`;
99
-
100
- const inner = document.createElement('div');
101
- inner.className = `pc-embed-inner-${id}`;
102
-
103
- const iframe = document.createElement('iframe');
104
- const urlObj = new URL(playcanvasUrl);
105
- urlObj.searchParams.set('overlay', 'false');
106
- iframe.src = urlObj.href;
107
- iframe.setAttribute('allowfullscreen', '');
108
- iframe.setAttribute('allow', 'autoplay; fullscreen');
109
- iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-pointer-lock allow-popups allow-forms');
110
-
111
- const fsBtn = document.createElement('button');
112
- fsBtn.className = `pc-fs-btn-${id}`;
113
- fsBtn.textContent = '⇱';
114
-
115
- inner.appendChild(iframe);
116
- wrapper.appendChild(inner);
117
- wrapper.appendChild(fsBtn);
118
- scriptTag.parentNode.insertBefore(wrapper, scriptTag.nextSibling);
119
-
120
- // ─── 7. État & Helper ────────────────────────────────────────────────────────
121
- let isFullscreen = false;
122
- let savedParent = null;
123
- let savedNextSibling = null;
124
-
125
- function getHeightUnit() {
126
- return (CSS && CSS.supports && CSS.supports('height', '100dvh')) ? '100dvh' : '100vh';
127
- }
128
-
129
- // ─── 8. Styles Plein Écran ───────────────────────────────────────────────────
130
- function applyFullscreenStyles() {
131
- const h = isIOS ? getHeightUnit() : '100vh';
132
- wrapper.style.position = 'fixed';
133
- wrapper.style.top = '0';
134
- wrapper.style.left = '0';
135
- wrapper.style.width = '100vw';
136
- wrapper.style.height = h;
137
- wrapper.style.maxHeight = h;
138
- wrapper.style.paddingBottom = '0';
139
- wrapper.style.margin = '0';
140
- wrapper.style.zIndex = '99999';
141
- wrapper.classList.add('fake-fullscreen');
142
- fsBtn.textContent = '⇲';
143
- isFullscreen = true;
144
- }
145
-
146
- function applyFakeFullscreenStyles() {
147
- savedParent = wrapper.parentNode;
148
- savedNextSibling = wrapper.nextSibling;
149
- document.body.appendChild(wrapper);
150
- applyFullscreenStyles();
151
- }
152
-
153
- function restoreStyles() {
154
- wrapper.style.cssText = '';
155
- // Le CSS via les Media Queries reprendra le dessus automatiquement ici
156
- wrapper.classList.remove('fake-fullscreen');
157
- fsBtn.textContent = '⇱';
158
- isFullscreen = false;
159
-
160
- if (savedParent) {
161
- savedParent.insertBefore(wrapper, savedNextSibling);
162
- savedParent = null;
163
- savedNextSibling = null;
164
- }
165
- }
166
-
167
- // ─── 9. Gestionnaires d'événements ───────────────────────────────────────────
168
- function enterFullscreen() {
169
- if (isIOS) {
170
- applyFakeFullscreenStyles();
171
- document.body.style.overflow = 'hidden';
172
- } else {
173
- const el = wrapper;
174
- const req = el.requestFullscreen || el.webkitRequestFullscreen || el.mozRequestFullScreen || el.msRequestFullscreen;
175
- if (req) {
176
- req.call(el).catch(() => {
177
- applyFakeFullscreenStyles();
178
- document.body.style.overflow = 'hidden';
179
- });
180
- } else {
181
- applyFakeFullscreenStyles();
182
- document.body.style.overflow = 'hidden';
183
- }
184
- }
185
- }
186
-
187
- function exitFullscreen() {
188
- if (document.fullscreenElement || document.webkitFullscreenElement) {
189
- (document.exitFullscreen || document.webkitExitFullscreen || function(){}).call(document);
190
- }
191
- restoreStyles();
192
- document.body.style.overflow = '';
193
- }
194
-
195
- fsBtn.addEventListener('click', (e) => {
196
- e.stopPropagation();
197
- isFullscreen ? exitFullscreen() : enterFullscreen();
198
- });
199
-
200
- document.addEventListener('fullscreenchange', () => {
201
- const fsEl = document.fullscreenElement || document.webkitFullscreenElement;
202
- if (!fsEl && isFullscreen) exitFullscreen();
203
- else if (fsEl === wrapper && !isFullscreen) applyFullscreenStyles();
204
- });
205
-
206
- window.addEventListener('resize', () => {
207
- if (isFullscreen) {
208
- const h = isIOS ? getHeightUnit() : '100vh';
209
- wrapper.style.height = h;
210
- wrapper.style.maxHeight = h;
211
- }
212
- });
213
- })();