@bebranded/bb-contents 1.0.111 → 1.0.113
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 +120 -85
- 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.113
|
|
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.113');
|
|
36
36
|
|
|
37
37
|
// Configuration
|
|
38
38
|
const config = {
|
|
39
|
-
version: '1.0.
|
|
39
|
+
version: '1.0.113',
|
|
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)
|
|
@@ -391,13 +391,17 @@
|
|
|
391
391
|
const totalImages = images.length;
|
|
392
392
|
|
|
393
393
|
|
|
394
|
-
// OPTIMISATION: Charger les images
|
|
394
|
+
// OPTIMISATION: Charger les images et appliquer les styles SVG AVANT le clonage
|
|
395
|
+
// pour éviter les reflows qui causent la saccade de l'animation
|
|
395
396
|
images.forEach(img => {
|
|
396
397
|
if (img.dataset.src && !img.src) {
|
|
397
398
|
img.src = img.dataset.src;
|
|
398
399
|
img.loading = 'eager';
|
|
399
400
|
}
|
|
400
401
|
|
|
402
|
+
// Détecter si c'est un SVG (par l'extension du src ou le type)
|
|
403
|
+
const isSVG = img.src && (img.src.toLowerCase().endsWith('.svg') || img.src.includes('data:image/svg+xml'));
|
|
404
|
+
|
|
401
405
|
// OPTIMISATION: Préserver les styles CSS existants (object-fit, etc.)
|
|
402
406
|
const originalObjectFit = img.style.objectFit || getComputedStyle(img).objectFit;
|
|
403
407
|
const originalObjectPosition = img.style.objectPosition || getComputedStyle(img).objectPosition;
|
|
@@ -405,20 +409,77 @@
|
|
|
405
409
|
const originalHeight = img.style.height;
|
|
406
410
|
|
|
407
411
|
img.onload = () => {
|
|
408
|
-
//
|
|
409
|
-
if (
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
img.style.objectPosition =
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
412
|
+
// SOLUTION MOBILE SAFARI : Pour les SVG sur mobile Safari, approche différente
|
|
413
|
+
if (isSVG && isMobile && isSafari) {
|
|
414
|
+
// SUR SAFARI MOBILE : Ne PAS utiliser object-fit qui cause du flou
|
|
415
|
+
// Utiliser des dimensions fixes et laisser le SVG se dimensionner naturellement
|
|
416
|
+
img.style.objectFit = 'none';
|
|
417
|
+
img.style.objectPosition = 'center';
|
|
418
|
+
|
|
419
|
+
// Forcer les dimensions du conteneur parent pour contraindre le SVG
|
|
420
|
+
const parent = img.parentElement;
|
|
421
|
+
if (parent) {
|
|
422
|
+
// S'assurer que le parent a des dimensions fixes
|
|
423
|
+
const parentComputed = getComputedStyle(parent);
|
|
424
|
+
if (!parentComputed.width || parentComputed.width === 'auto') {
|
|
425
|
+
parent.style.width = '100%';
|
|
426
|
+
}
|
|
427
|
+
if (!parentComputed.height || parentComputed.height === 'auto') {
|
|
428
|
+
parent.style.height = '100%';
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
parent.style.display = 'flex';
|
|
432
|
+
parent.style.alignItems = 'center';
|
|
433
|
+
parent.style.justifyContent = 'center';
|
|
434
|
+
parent.style.overflow = 'hidden';
|
|
435
|
+
parent.style.boxSizing = 'border-box';
|
|
436
|
+
|
|
437
|
+
// Forcer le SVG à prendre la taille du parent sans object-fit
|
|
438
|
+
img.style.width = '100%';
|
|
439
|
+
img.style.height = '100%';
|
|
440
|
+
img.style.maxWidth = '100%';
|
|
441
|
+
img.style.maxHeight = '100%';
|
|
442
|
+
img.style.boxSizing = 'border-box';
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// Améliorer le rendu des SVG sans object-fit
|
|
446
|
+
img.style.imageRendering = 'crisp-edges';
|
|
447
|
+
img.style.webkitBackfaceVisibility = 'hidden';
|
|
448
|
+
img.style.backfaceVisibility = 'hidden';
|
|
449
|
+
} else if (isSVG && isMobile) {
|
|
450
|
+
// Pour Chrome mobile, utiliser contain normalement
|
|
451
|
+
img.style.objectFit = 'contain';
|
|
452
|
+
img.style.objectPosition = 'center';
|
|
453
|
+
img.style.maxWidth = '100%';
|
|
454
|
+
img.style.maxHeight = '100%';
|
|
455
|
+
img.style.width = '100%';
|
|
456
|
+
img.style.height = '100%';
|
|
457
|
+
img.style.boxSizing = 'border-box';
|
|
458
|
+
|
|
459
|
+
const parent = img.parentElement;
|
|
460
|
+
if (parent) {
|
|
461
|
+
parent.style.display = 'flex';
|
|
462
|
+
parent.style.alignItems = 'center';
|
|
463
|
+
parent.style.justifyContent = 'center';
|
|
464
|
+
parent.style.overflow = 'hidden';
|
|
465
|
+
parent.style.boxSizing = 'border-box';
|
|
466
|
+
}
|
|
467
|
+
} else {
|
|
468
|
+
// OPTIMISATION: Restaurer les styles CSS après chargement pour les non-SVG
|
|
469
|
+
if (originalObjectFit && originalObjectFit !== 'none') {
|
|
470
|
+
img.style.objectFit = originalObjectFit;
|
|
471
|
+
}
|
|
472
|
+
if (originalObjectPosition && originalObjectPosition !== 'initial') {
|
|
473
|
+
img.style.objectPosition = originalObjectPosition;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
// OPTIMISATION: Préserver les dimensions naturelles des images
|
|
477
|
+
if (!originalWidth || originalWidth === '') {
|
|
478
|
+
img.style.width = 'auto';
|
|
479
|
+
}
|
|
480
|
+
if (!originalHeight || originalHeight === '') {
|
|
481
|
+
img.style.height = 'auto';
|
|
482
|
+
}
|
|
422
483
|
}
|
|
423
484
|
|
|
424
485
|
imagesLoaded++;
|
|
@@ -430,6 +491,8 @@
|
|
|
430
491
|
|
|
431
492
|
// SOLUTION SAFARI MOBILE SIMPLE : Attendre plus longtemps
|
|
432
493
|
const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
|
|
494
|
+
// Détecter spécifiquement Safari (pas Chrome mobile)
|
|
495
|
+
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent) || /iPhone|iPad|iPod/.test(navigator.userAgent);
|
|
433
496
|
|
|
434
497
|
// Timeout plus long sur mobile pour laisser le temps aux images de se charger
|
|
435
498
|
const maxWaitTime = isMobile ? 5000 : 3000; // 5 secondes sur mobile
|
|
@@ -471,63 +534,9 @@
|
|
|
471
534
|
});
|
|
472
535
|
}
|
|
473
536
|
|
|
474
|
-
//
|
|
475
|
-
//
|
|
476
|
-
|
|
477
|
-
allImages.forEach(img => {
|
|
478
|
-
// Détecter si c'est un SVG (par l'extension du src ou le type)
|
|
479
|
-
const isSVG = img.src && (img.src.toLowerCase().endsWith('.svg') || img.src.includes('data:image/svg+xml'));
|
|
480
|
-
|
|
481
|
-
// SOLUTION MOBILE SAFARI : Pour les SVG sur mobile, éviter object-fit qui cause du flou
|
|
482
|
-
if (isSVG && isMobile) {
|
|
483
|
-
// Sur mobile, utiliser contain pour éviter le débordement, mais avec optimisations anti-flou
|
|
484
|
-
img.style.objectFit = 'contain';
|
|
485
|
-
img.style.objectPosition = 'center';
|
|
486
|
-
|
|
487
|
-
// Ajouter des contraintes pour empêcher le débordement
|
|
488
|
-
img.style.maxWidth = '100%';
|
|
489
|
-
img.style.maxHeight = '100%';
|
|
490
|
-
img.style.width = '100%';
|
|
491
|
-
img.style.height = '100%';
|
|
492
|
-
|
|
493
|
-
// Forcer le GPU rendering
|
|
494
|
-
img.style.webkitTransform = 'translate3d(0, 0, 0)';
|
|
495
|
-
img.style.transform = 'translate3d(0, 0, 0)';
|
|
496
|
-
|
|
497
|
-
// Améliorer le rendu des SVG
|
|
498
|
-
img.style.imageRendering = 'crisp-edges';
|
|
499
|
-
|
|
500
|
-
// S'assurer que le conteneur parent permet au SVG de s'afficher correctement
|
|
501
|
-
// et empêche le débordement avec overflow hidden
|
|
502
|
-
const parent = img.parentElement;
|
|
503
|
-
if (parent) {
|
|
504
|
-
parent.style.display = 'flex';
|
|
505
|
-
parent.style.alignItems = 'center';
|
|
506
|
-
parent.style.justifyContent = 'center';
|
|
507
|
-
parent.style.overflow = 'hidden'; // Empêcher le débordement
|
|
508
|
-
}
|
|
509
|
-
} else {
|
|
510
|
-
// Pour les images non-SVG ou sur desktop, appliquer les styles normaux
|
|
511
|
-
// Vérifier si l'image a déjà des styles inline
|
|
512
|
-
if (!img.style.objectFit) {
|
|
513
|
-
const computedStyle = getComputedStyle(img);
|
|
514
|
-
const objectFit = computedStyle.objectFit;
|
|
515
|
-
const objectPosition = computedStyle.objectPosition;
|
|
516
|
-
|
|
517
|
-
// Appliquer object-fit si défini dans le CSS
|
|
518
|
-
if (objectFit && objectFit !== 'none' && objectFit !== 'fill') {
|
|
519
|
-
img.style.objectFit = objectFit;
|
|
520
|
-
}
|
|
521
|
-
// Appliquer object-position si défini dans le CSS
|
|
522
|
-
if (objectPosition && objectPosition !== 'initial' && objectPosition !== '50% 50%') {
|
|
523
|
-
img.style.objectPosition = objectPosition;
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
// Forcer un reflow pour stabiliser le rendu
|
|
529
|
-
void img.offsetHeight;
|
|
530
|
-
});
|
|
537
|
+
// Les styles sont maintenant appliqués AVANT le clonage (dans img.onload)
|
|
538
|
+
// Cela évite les reflows qui causaient la saccade de l'animation
|
|
539
|
+
// Les copies héritent automatiquement des styles des images originales
|
|
531
540
|
|
|
532
541
|
// Vérifier que les images ont une taille visible
|
|
533
542
|
let imagesWithSize = 0;
|
|
@@ -559,6 +568,13 @@
|
|
|
559
568
|
const step = (parseFloat(speed) * (isVertical ? 1.5 : 0.8)) / 60;
|
|
560
569
|
let isPaused = false;
|
|
561
570
|
|
|
571
|
+
// OPTIMISATION SAFARI MOBILE : Ajouter will-change pour améliorer la fluidité
|
|
572
|
+
if (isSafari && isMobile) {
|
|
573
|
+
scrollContainer.style.willChange = 'transform';
|
|
574
|
+
scrollContainer.style.webkitBackfaceVisibility = 'hidden';
|
|
575
|
+
scrollContainer.style.backfaceVisibility = 'hidden';
|
|
576
|
+
}
|
|
577
|
+
|
|
562
578
|
// Ajuster la taille du conteneur
|
|
563
579
|
if (isVertical && !useAutoHeight) {
|
|
564
580
|
scrollContainer.style.height = totalSize + 'px';
|
|
@@ -579,27 +595,35 @@
|
|
|
579
595
|
? `translate3d(0, ${currentPosition}px, 0)`
|
|
580
596
|
: `translate3d(${currentPosition}px, 0, 0)`;
|
|
581
597
|
scrollContainer.style.transform = initialTransform;
|
|
598
|
+
|
|
599
|
+
// OPTIMISATION SAFARI MOBILE : Forcer un reflow avant de démarrer l'animation
|
|
600
|
+
if (isSafari && isMobile) {
|
|
601
|
+
void scrollContainer.offsetHeight;
|
|
602
|
+
}
|
|
582
603
|
|
|
583
|
-
// Fonction d'animation Safari
|
|
604
|
+
// Fonction d'animation Safari optimisée
|
|
584
605
|
let frameCount = 0;
|
|
585
|
-
|
|
606
|
+
let lastTime = performance.now();
|
|
607
|
+
const animate = (currentTime) => {
|
|
586
608
|
if (!isPaused) {
|
|
587
609
|
frameCount++;
|
|
588
610
|
|
|
611
|
+
// OPTIMISATION SAFARI MOBILE : Utiliser le temps réel pour une animation plus fluide
|
|
612
|
+
const deltaTime = isSafari && isMobile ? (currentTime - lastTime) / 16.67 : 1;
|
|
613
|
+
lastTime = currentTime;
|
|
614
|
+
|
|
589
615
|
if (direction === (isVertical ? 'bottom' : 'right')) {
|
|
590
|
-
currentPosition += step;
|
|
616
|
+
currentPosition += step * deltaTime;
|
|
591
617
|
if (currentPosition >= 0) {
|
|
592
618
|
currentPosition = -(finalContentSize + gapSize);
|
|
593
619
|
}
|
|
594
620
|
} else {
|
|
595
|
-
currentPosition -= step;
|
|
621
|
+
currentPosition -= step * deltaTime;
|
|
596
622
|
if (currentPosition <= -(2 * (finalContentSize + gapSize))) {
|
|
597
623
|
currentPosition = -(finalContentSize + gapSize);
|
|
598
624
|
}
|
|
599
625
|
}
|
|
600
626
|
|
|
601
|
-
// Animation continue
|
|
602
|
-
|
|
603
627
|
// ARRONDI pour éviter les erreurs de précision JavaScript
|
|
604
628
|
currentPosition = Math.round(currentPosition * 100) / 100;
|
|
605
629
|
|
|
@@ -612,10 +636,21 @@
|
|
|
612
636
|
requestAnimationFrame(animate);
|
|
613
637
|
};
|
|
614
638
|
|
|
615
|
-
// Démarrer l'animation avec un
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
639
|
+
// Démarrer l'animation avec un délai adapté pour Safari
|
|
640
|
+
if (isSafari && isMobile) {
|
|
641
|
+
// Safari mobile : attendre un peu plus pour que tout soit prêt
|
|
642
|
+
requestAnimationFrame(() => {
|
|
643
|
+
requestAnimationFrame(() => {
|
|
644
|
+
lastTime = performance.now();
|
|
645
|
+
animate(lastTime);
|
|
646
|
+
});
|
|
647
|
+
});
|
|
648
|
+
} else {
|
|
649
|
+
setTimeout(() => {
|
|
650
|
+
lastTime = performance.now();
|
|
651
|
+
animate(lastTime);
|
|
652
|
+
}, 50);
|
|
653
|
+
}
|
|
619
654
|
|
|
620
655
|
// Pause au survol pour Safari
|
|
621
656
|
if (element.getAttribute('bb-marquee-pause') === 'true') {
|