@bebranded/bb-contents 1.0.99 → 1.0.101
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/bb-contents.js +77 -52
- package/package.json +1 -1
package/bb-contents.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* BeBranded Contents
|
|
3
3
|
* Contenus additionnels français pour Webflow
|
|
4
|
-
* @version 1.0.
|
|
4
|
+
* @version 1.0.101
|
|
5
5
|
* @author BeBranded
|
|
6
6
|
* @license MIT
|
|
7
7
|
* @website https://www.bebranded.xyz
|
|
@@ -32,11 +32,11 @@
|
|
|
32
32
|
window._bbContentsInitialized = true;
|
|
33
33
|
|
|
34
34
|
// Log de démarrage simple (une seule fois)
|
|
35
|
-
console.log('bb-contents | v1.0.
|
|
35
|
+
console.log('bb-contents | v1.0.101');
|
|
36
36
|
|
|
37
37
|
// Configuration
|
|
38
38
|
const config = {
|
|
39
|
-
version: '1.0.
|
|
39
|
+
version: '1.0.101',
|
|
40
40
|
debug: false, // Debug désactivé pour rendu propre
|
|
41
41
|
prefix: 'bb-', // utilisé pour générer les sélecteurs (data-bb-*)
|
|
42
42
|
youtubeEndpoint: null, // URL du worker YouTube (à définir par l'utilisateur)
|
|
@@ -394,8 +394,10 @@
|
|
|
394
394
|
// SOLUTION MOBILE : Charger toutes les images AVANT de créer les copies pour éviter le flou
|
|
395
395
|
const loadImage = (img) => {
|
|
396
396
|
return new Promise((resolve) => {
|
|
397
|
+
// Vérifier que l'image est complètement chargée avec dimensions naturelles
|
|
397
398
|
if (img.complete && img.naturalWidth > 0 && img.naturalHeight > 0) {
|
|
398
|
-
// Image déjà chargée
|
|
399
|
+
// Image déjà chargée, vérifier le rendu avec un reflow
|
|
400
|
+
void img.offsetHeight;
|
|
399
401
|
imagesLoaded++;
|
|
400
402
|
resolve();
|
|
401
403
|
return;
|
|
@@ -411,10 +413,26 @@
|
|
|
411
413
|
}
|
|
412
414
|
|
|
413
415
|
img.onload = () => {
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
416
|
+
// Vérifier que les dimensions naturelles sont disponibles
|
|
417
|
+
if (img.naturalWidth > 0 && img.naturalHeight > 0) {
|
|
418
|
+
// Forcer un reflow complet pour s'assurer que l'image est rendue
|
|
419
|
+
void img.offsetHeight;
|
|
420
|
+
void img.offsetWidth;
|
|
421
|
+
// Double reflow pour mobile (surtout Retina)
|
|
422
|
+
if (isMobile) {
|
|
423
|
+
requestAnimationFrame(() => {
|
|
424
|
+
void img.offsetHeight;
|
|
425
|
+
imagesLoaded++;
|
|
426
|
+
resolve();
|
|
427
|
+
});
|
|
428
|
+
} else {
|
|
429
|
+
imagesLoaded++;
|
|
430
|
+
resolve();
|
|
431
|
+
}
|
|
432
|
+
} else {
|
|
433
|
+
imagesLoaded++;
|
|
434
|
+
resolve();
|
|
435
|
+
}
|
|
418
436
|
};
|
|
419
437
|
img.onerror = () => {
|
|
420
438
|
imagesLoaded++;
|
|
@@ -423,59 +441,61 @@
|
|
|
423
441
|
});
|
|
424
442
|
};
|
|
425
443
|
|
|
426
|
-
//
|
|
427
|
-
Promise.all(Array.from(images).map(loadImage))
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
444
|
+
// Attendre réellement que toutes les images soient chargées
|
|
445
|
+
Promise.all(Array.from(images).map(loadImage)).then(() => {
|
|
446
|
+
// Vérifier que toutes les images ont leurs dimensions naturelles
|
|
447
|
+
let allImagesReady = true;
|
|
448
|
+
images.forEach(img => {
|
|
449
|
+
if (!img.complete || img.naturalWidth === 0 || img.naturalHeight === 0) {
|
|
450
|
+
allImagesReady = false;
|
|
451
|
+
}
|
|
452
|
+
});
|
|
435
453
|
|
|
436
|
-
if (
|
|
437
|
-
// Attendre
|
|
454
|
+
if (allImagesReady || images.length === 0) {
|
|
455
|
+
// Attendre plusieurs frames pour garantir le rendu complet, surtout sur mobile
|
|
438
456
|
requestAnimationFrame(() => {
|
|
439
457
|
requestAnimationFrame(() => {
|
|
440
|
-
//
|
|
441
|
-
const
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
458
|
+
// Délai supplémentaire sur mobile pour garantir le rendu Retina
|
|
459
|
+
const renderDelay = isMobile ? 100 : 0;
|
|
460
|
+
setTimeout(() => {
|
|
461
|
+
// Forcer un reflow complet du mainBlock avant clonage
|
|
462
|
+
void mainBlock.offsetHeight;
|
|
463
|
+
|
|
464
|
+
// Maintenant créer les copies avec les images complètement chargées et rendues
|
|
465
|
+
const repeatBlock1 = mainBlock.cloneNode(true);
|
|
466
|
+
const repeatBlock2 = mainBlock.cloneNode(true);
|
|
467
|
+
|
|
468
|
+
// Forcer un reflow après clonage pour garantir le rendu
|
|
469
|
+
scrollContainer.appendChild(repeatBlock1);
|
|
470
|
+
void repeatBlock1.offsetHeight;
|
|
471
|
+
scrollContainer.appendChild(repeatBlock2);
|
|
472
|
+
void repeatBlock2.offsetHeight;
|
|
473
|
+
|
|
474
|
+
// Démarrer l'animation
|
|
475
|
+
startSafariAnimation();
|
|
476
|
+
}, renderDelay);
|
|
448
477
|
});
|
|
449
478
|
});
|
|
450
479
|
} else {
|
|
451
|
-
|
|
480
|
+
// Fallback : attendre un peu plus si certaines images ne sont pas prêtes
|
|
481
|
+
setTimeout(() => {
|
|
482
|
+
const repeatBlock1 = mainBlock.cloneNode(true);
|
|
483
|
+
const repeatBlock2 = mainBlock.cloneNode(true);
|
|
484
|
+
scrollContainer.appendChild(repeatBlock1);
|
|
485
|
+
scrollContainer.appendChild(repeatBlock2);
|
|
486
|
+
startSafariAnimation();
|
|
487
|
+
}, 500);
|
|
452
488
|
}
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
|
|
489
|
+
}).catch(() => {
|
|
490
|
+
// En cas d'erreur, créer les copies quand même
|
|
491
|
+
const repeatBlock1 = mainBlock.cloneNode(true);
|
|
492
|
+
const repeatBlock2 = mainBlock.cloneNode(true);
|
|
493
|
+
scrollContainer.appendChild(repeatBlock1);
|
|
494
|
+
scrollContainer.appendChild(repeatBlock2);
|
|
495
|
+
startSafariAnimation();
|
|
496
|
+
});
|
|
456
497
|
|
|
457
498
|
const startSafariAnimation = () => {
|
|
458
|
-
// Forcer le chargement des images restantes si timeout
|
|
459
|
-
if (waitTimeout >= maxWaitTime && imagesLoaded < totalImages) {
|
|
460
|
-
images.forEach(img => {
|
|
461
|
-
if (img.dataset.src && !img.src) {
|
|
462
|
-
img.src = img.dataset.src;
|
|
463
|
-
// Ne pas forcer eager sur mobile, laisser le lazy loading
|
|
464
|
-
if (!img.loading && !isMobile) {
|
|
465
|
-
img.loading = 'eager';
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
});
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
// Vérifier que les images ont une taille visible
|
|
472
|
-
let imagesWithSize = 0;
|
|
473
|
-
images.forEach(img => {
|
|
474
|
-
if (img.offsetWidth > 0 && img.offsetHeight > 0) {
|
|
475
|
-
imagesWithSize++;
|
|
476
|
-
}
|
|
477
|
-
});
|
|
478
|
-
|
|
479
499
|
// Recalculer la taille après chargement des images
|
|
480
500
|
const newContentSize = isVertical ? mainBlock.offsetHeight : mainBlock.offsetWidth;
|
|
481
501
|
|
|
@@ -513,6 +533,11 @@
|
|
|
513
533
|
currentPosition = 0;
|
|
514
534
|
}
|
|
515
535
|
|
|
536
|
+
// Désactiver will-change sur mobile après initialisation pour éviter le flou
|
|
537
|
+
if (isMobile) {
|
|
538
|
+
scrollContainer.style.willChange = 'auto';
|
|
539
|
+
}
|
|
540
|
+
|
|
516
541
|
// Forcer la position initiale pour éviter l'invisibilité
|
|
517
542
|
const initialTransform = isVertical
|
|
518
543
|
? `translate3d(0, ${currentPosition}px, 0)`
|