@bebranded/bb-contents 1.0.105 → 1.0.107

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.
Files changed (2) hide show
  1. package/bb-contents.js +73 -112
  2. 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.105
4
+ * @version 1.0.107
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.105');
35
+ console.log('bb-contents | v1.0.107');
36
36
 
37
37
  // Configuration
38
38
  const config = {
39
- version: '1.0.105',
39
+ version: '1.0.107',
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,117 +391,84 @@
391
391
  const totalImages = images.length;
392
392
 
393
393
 
394
- // SOLUTION MOBILE : Amélioration du rendu des images sur mobile
395
- const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent) ||
396
- (window.innerWidth <= 768 && /Chrome|CriOS/i.test(navigator.userAgent));
397
-
398
- // SOLUTION MOBILE : Charger toutes les images AVANT de créer les copies pour éviter le flou
399
- const loadImage = (img) => {
400
- return new Promise((resolve) => {
401
- // Vérifier que l'image est complètement chargée avec dimensions naturelles
402
- if (img.complete && img.naturalWidth > 0 && img.naturalHeight > 0) {
403
- // Image déjà chargée, vérifier le rendu avec un reflow
404
- void img.offsetHeight;
405
- imagesLoaded++;
406
- resolve();
407
- return;
394
+ // OPTIMISATION: Charger les images sans forcer les dimensions
395
+ images.forEach(img => {
396
+ if (img.dataset.src && !img.src) {
397
+ img.src = img.dataset.src;
398
+ img.loading = 'eager';
399
+ }
400
+
401
+ // OPTIMISATION: Préserver les styles CSS existants (object-fit, etc.)
402
+ const originalObjectFit = img.style.objectFit || getComputedStyle(img).objectFit;
403
+ const originalObjectPosition = img.style.objectPosition || getComputedStyle(img).objectPosition;
404
+ const originalWidth = img.style.width;
405
+ const originalHeight = img.style.height;
406
+
407
+ img.onload = () => {
408
+ // OPTIMISATION: Restaurer les styles CSS après chargement
409
+ if (originalObjectFit && originalObjectFit !== 'none') {
410
+ img.style.objectFit = originalObjectFit;
408
411
  }
409
-
410
- if (img.dataset.src && !img.src) {
411
- img.src = img.dataset.src;
412
+ if (originalObjectPosition && originalObjectPosition !== 'initial') {
413
+ img.style.objectPosition = originalObjectPosition;
412
414
  }
413
415
 
414
- // Utiliser eager sur mobile pour éviter le flou de lazy loading
415
- if (!img.loading && isMobile) {
416
- img.loading = 'eager';
416
+ // OPTIMISATION: Préserver les dimensions naturelles des images
417
+ if (!originalWidth || originalWidth === '') {
418
+ img.style.width = 'auto';
419
+ }
420
+ if (!originalHeight || originalHeight === '') {
421
+ img.style.height = 'auto';
417
422
  }
418
423
 
419
- img.onload = () => {
420
- // Vérifier que les dimensions naturelles sont disponibles
421
- if (img.naturalWidth > 0 && img.naturalHeight > 0) {
422
- // Forcer un reflow complet pour s'assurer que l'image est rendue
423
- void img.offsetHeight;
424
- void img.offsetWidth;
425
- // Double reflow pour mobile (surtout Retina)
426
- if (isMobile) {
427
- requestAnimationFrame(() => {
428
- void img.offsetHeight;
429
- imagesLoaded++;
430
- resolve();
431
- });
432
- } else {
433
- imagesLoaded++;
434
- resolve();
435
- }
436
- } else {
437
- imagesLoaded++;
438
- resolve();
439
- }
440
- };
441
- img.onerror = () => {
442
- imagesLoaded++;
443
- resolve(); // Résoudre même en cas d'erreur
444
- };
445
- });
446
- };
424
+ imagesLoaded++;
425
+ };
426
+ img.onerror = () => {
427
+ imagesLoaded++;
428
+ };
429
+ });
447
430
 
448
- // Attendre réellement que toutes les images soient chargées
449
- Promise.all(Array.from(images).map(loadImage)).then(() => {
450
- // Vérifier que toutes les images ont leurs dimensions naturelles
451
- let allImagesReady = true;
452
- images.forEach(img => {
453
- if (!img.complete || img.naturalWidth === 0 || img.naturalHeight === 0) {
454
- allImagesReady = false;
455
- }
456
- });
431
+ // SOLUTION SAFARI MOBILE SIMPLE : Attendre plus longtemps
432
+ const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
433
+
434
+ // Timeout plus long sur mobile pour laisser le temps aux images de se charger
435
+ const maxWaitTime = isMobile ? 5000 : 3000; // 5 secondes sur mobile
436
+ let waitTimeout = 0;
437
+
438
+ const waitForImages = () => {
439
+ waitTimeout += 100;
457
440
 
458
- if (allImagesReady || images.length === 0) {
459
- // Attendre plusieurs frames pour garantir le rendu complet, surtout sur mobile
460
- requestAnimationFrame(() => {
461
- requestAnimationFrame(() => {
462
- // Délai supplémentaire sur mobile pour garantir le rendu Retina
463
- const renderDelay = isMobile ? 100 : 0;
464
- setTimeout(() => {
465
- // Forcer un reflow complet du mainBlock avant clonage
466
- void mainBlock.offsetHeight;
467
-
468
- // Maintenant créer les copies avec les images complètement chargées et rendues
469
- const repeatBlock1 = mainBlock.cloneNode(true);
470
- const repeatBlock2 = mainBlock.cloneNode(true);
471
-
472
- // Forcer un reflow après clonage pour garantir le rendu
473
- scrollContainer.appendChild(repeatBlock1);
474
- void repeatBlock1.offsetHeight;
475
- scrollContainer.appendChild(repeatBlock2);
476
- void repeatBlock2.offsetHeight;
477
-
478
- // Démarrer l'animation
479
- startSafariAnimation();
480
- }, renderDelay);
481
- });
482
- });
483
- } else {
484
- // Fallback : attendre un peu plus si certaines images ne sont pas prêtes
441
+ if (imagesLoaded >= totalImages || imagesLoaded === 0 || waitTimeout >= maxWaitTime) {
442
+ // Attendre plus longtemps sur mobile pour le rendu visuel
443
+ const renderDelay = isMobile ? 1000 : 200;
485
444
  setTimeout(() => {
486
- const repeatBlock1 = mainBlock.cloneNode(true);
487
- const repeatBlock2 = mainBlock.cloneNode(true);
488
- scrollContainer.appendChild(repeatBlock1);
489
- scrollContainer.appendChild(repeatBlock2);
490
445
  startSafariAnimation();
491
- }, 500);
446
+ }, renderDelay);
447
+ } else {
448
+ setTimeout(waitForImages, 100);
492
449
  }
493
- }).catch(() => {
494
- // En cas d'erreur, créer les copies quand même
495
- const repeatBlock1 = mainBlock.cloneNode(true);
496
- const repeatBlock2 = mainBlock.cloneNode(true);
497
- scrollContainer.appendChild(repeatBlock1);
498
- scrollContainer.appendChild(repeatBlock2);
499
- startSafariAnimation();
500
- });
450
+ };
451
+
452
+ waitForImages();
501
453
 
502
454
  const startSafariAnimation = () => {
503
- // Vérifier que speed est bien défini et valide
504
- const validSpeed = parseFloat(speed) || 100;
455
+ // Forcer le chargement des images restantes si timeout
456
+ if (waitTimeout >= maxWaitTime && imagesLoaded < totalImages) {
457
+ images.forEach(img => {
458
+ if (img.dataset.src && !img.src) {
459
+ img.src = img.dataset.src;
460
+ img.loading = 'eager';
461
+ }
462
+ });
463
+ }
464
+
465
+ // Vérifier que les images ont une taille visible
466
+ let imagesWithSize = 0;
467
+ images.forEach(img => {
468
+ if (img.offsetWidth > 0 && img.offsetHeight > 0) {
469
+ imagesWithSize++;
470
+ }
471
+ });
505
472
 
506
473
  // Recalculer la taille après chargement des images
507
474
  const newContentSize = isVertical ? mainBlock.offsetHeight : mainBlock.offsetWidth;
@@ -522,7 +489,7 @@
522
489
 
523
490
  // Solution Safari simplifiée
524
491
  const totalSize = finalContentSize * 3 + gapSize * 2;
525
- const step = (validSpeed * (isVertical ? 1.5 : 0.8)) / 60;
492
+ const step = (parseFloat(speed) * (isVertical ? 1.5 : 0.8)) / 60;
526
493
  let isPaused = false;
527
494
 
528
495
  // Ajuster la taille du conteneur
@@ -540,11 +507,6 @@
540
507
  currentPosition = 0;
541
508
  }
542
509
 
543
- // Désactiver will-change sur mobile après initialisation pour éviter le flou
544
- if (isMobile) {
545
- scrollContainer.style.willChange = 'auto';
546
- }
547
-
548
510
  // Forcer la position initiale pour éviter l'invisibilité
549
511
  const initialTransform = isVertical
550
512
  ? `translate3d(0, ${currentPosition}px, 0)`
@@ -583,11 +545,10 @@
583
545
  requestAnimationFrame(animate);
584
546
  };
585
547
 
586
- // Démarrer l'animation immédiatement (les copies sont déjà créées)
587
- // Utiliser requestAnimationFrame pour garantir le rendu
588
- requestAnimationFrame(() => {
548
+ // Démarrer l'animation avec un petit délai pour Safari
549
+ setTimeout(() => {
589
550
  animate();
590
- });
551
+ }, 50);
591
552
 
592
553
  // Pause au survol pour Safari
593
554
  if (element.getAttribute('bb-marquee-pause') === 'true') {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bebranded/bb-contents",
3
- "version": "1.0.105",
3
+ "version": "1.0.107",
4
4
  "description": "Contenus additionnels français pour Webflow",
5
5
  "main": "bb-contents.js",
6
6
  "scripts": {