Se rendre au contenu

Welcome .


Sign u

Cette question a été signalée

Section épurée sur fond blanc avec gros texte (fourni en HTML encodé, automatiquement décodé) et une grande roue en SVG qui tourne une seule fois pendant ~5 secondes au chargement. Design minimal, responsive, et respect de prefers-reduced-motion. Plug-and-play, aucune dépendance.

<!-- ========== Apple-Style Ferris Wheel (Auto 5s, Decode HTML) ==========
USAGE :
- Mettez votre texte HTML ENCODÉ dans data-encoded (ou dans un <pre> enfant).
- La grande roue tourne automatiquement une seule fois (~5 s) au chargement.
======================================================================= -->
<div class="sw-apple-hero-wheel" data-encoded="&lt;strong&gt;Bienvenue&nbsp;!&lt;/strong&gt;"></div>

<style>
  .sw-apple-hero-wheel{
    position: relative;
    background:#fff;
    border-radius: 20px;
    padding: clamp(16px,4vw,40px);
    min-height: 36vh;
    overflow: visible;
  }
  .sw-hero-wrap{
    display: grid;
    align-items: center;
    gap: clamp(16px,4vw,40px);
    grid-template-columns: 1fr minmax(180px, clamp(200px, 24vw, 360px));
  }
  @media (max-width: 720px){
    .sw-hero-wrap{ grid-template-columns: 1fr; }
  }

  .sw-text{
    font-family: -apple-system, system-ui, "SF Pro Display", Segoe UI, Roboto, Helvetica, Arial, "Apple Color Emoji", "Segoe UI Emoji";
    font-weight: 700;
    font-size: clamp(28px, 7vw, 72px);
    line-height: 1.05;
    letter-spacing: .2px;
    color:#111;
    text-align:left;
    white-space: pre-wrap;
  }
  @media (max-width: 720px){
    .sw-text{ text-align:center; }
  }

  /* --- Wheel look --- */
  .sw-wheel{
    width: 100%;
    height: auto;
    display: block;
  }
  .sw-wheel *{
    vector-effect: non-scaling-stroke;
  }
  .wheel-rim{ stroke:#111; stroke-width:2.5; fill:none; opacity:.9; }
  .wheel-spoke{ stroke:#111; stroke-width:2; stroke-linecap:round; opacity:.7; }
  .wheel-hub{ fill:#111; }
  .wheel-cabin{ fill:#111; opacity:.8; rx:3; ry:3; }

  /* --- Animation (runs once ~5s) --- */
  .wheel-rotor{
    transform-box: fill-box;
    transform-origin: 50% 50%;
    animation: none;
  }
  .wheel-rotor.play{
    animation: sw-rotate 5s cubic-bezier(.2,.7,.2,1) 1 both;
  }
  @keyframes sw-rotate{
    from{ transform: rotate(0deg); }
    to  { transform: rotate(360deg); }
  }

  /* Accessibilité : réduire l’animation si demandé */
  @media (prefers-reduced-motion: reduce){
    .wheel-rotor{ animation: none !important; }
  }
</style>

<script>
(function(){
  // Decode "&lt;strong&gt;Bonjour&lt;/strong&gt;" -> "<strong>Bonjour</strong>"
  function decodeHTML(encoded){
    const ta = document.createElement('textarea');
    ta.innerHTML = encoded;
    return ta.value;
  }

  function renderHero(host){
    // 1) Décoder le texte
    let encoded = host.getAttribute('data-encoded') || '';
    if(!encoded){
      const pre = host.querySelector('pre');
      encoded = pre ? pre.innerHTML.trim() : (host.textContent || '').trim();
    }
    host.innerHTML = `
      <div class="sw-hero-wrap">
        <div class="sw-col">
          <span class="sw-text">${decodeHTML(encoded)}</span>
        </div>
        <div class="sw-col">
          <svg class="sw-wheel" viewBox="-120 -120 240 240" aria-hidden="true"></svg>
        </div>
      </div>
    `;

    // 2) Construire la grande roue en SVG
    const svg = host.querySelector('.sw-wheel');
    const rotor = document.createElementNS('http://www.w3.org/2000/svg','g');
    rotor.setAttribute('class','wheel-rotor');
    svg.appendChild(rotor);

    // Rim
    const rim = document.createElementNS(svg.namespaceURI,'circle');
    rim.setAttribute('class','wheel-rim');
    rim.setAttribute('cx','0'); rim.setAttribute('cy','0'); rim.setAttribute('r','100');
    rotor.appendChild(rim);

    // Spokes (12)
    for(let i=0; i<12; i++){
      const a = (i * Math.PI/6); // 30°
      const x = Math.cos(a) * 92;
      const y = Math.sin(a) * 92;
      const spoke = document.createElementNS(svg.namespaceURI,'line');
      spoke.setAttribute('class','wheel-spoke');
      spoke.setAttribute('x1','0'); spoke.setAttribute('y1','0');
      spoke.setAttribute('x2', x.toFixed(2)); spoke.setAttribute('y2', y.toFixed(2));
      rotor.appendChild(spoke);
    }

    // Cabins (12) sur le pourtour
    for(let i=0; i<12; i++){
      const a = (i * Math.PI/6);
      const R = 100; // rayon de la roue
      const w = 18, h = 12;
      const cx = Math.cos(a) * R;
      const cy = Math.sin(a) * R;
      const cabin = document.createElementNS(svg.namespaceURI,'rect');
      cabin.setAttribute('class','wheel-cabin');
      cabin.setAttribute('x', (cx - w/2).toFixed(2));
      cabin.setAttribute('y', (cy - h/2).toFixed(2));
      cabin.setAttribute('width', w);
      cabin.setAttribute('height', h);
      rotor.appendChild(cabin);
    }

    // Hub
    const hub = document.createElementNS(svg.namespaceURI,'circle');
    hub.setAttribute('class','wheel-hub');
    hub.setAttribute('cx','0'); hub.setAttribute('cy','0'); hub.setAttribute('r','6.5');
    rotor.appendChild(hub);

    return rotor;
  }

  // Lance l’animation une seule fois (~5 s) au chargement
  function autoplayOnce(host, rotor){
    if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
    if (host.dataset.played === '1') return;
    host.dataset.played = '1';

    // Démarre l’animation
    rotor.classList.add('play');

    // Retire la classe à la fin pour éviter tout restart involontaire via reflow
    rotor.addEventListener('animationend', ()=> {
      rotor.classList.remove('play');
    }, {once:true});
  }

  function init(){
    document.querySelectorAll('.sw-apple-hero-wheel').forEach(host=>{
      const rotor = renderHero(host);
      autoplayOnce(host, rotor);
    });
  }

  if(document.readyState === 'loading'){
    document.addEventListener('DOMContentLoaded', init);
  }else{
    init();
  }
})();
</script>

Ignorer
Publications associées Réponses Vues Activité
0
août 25
42
0
août 25
18
0
août 25
38
0
août 25
44
0
août 25
46