{"id":1350,"date":"2026-08-13T10:37:13","date_gmt":"2026-08-13T08:37:13","guid":{"rendered":"https:\/\/iconoclaste.net\/blog\/?p=1350"},"modified":"2026-08-13T10:55:01","modified_gmt":"2026-08-13T08:55:01","slug":"demonoida","status":"publish","type":"post","link":"https:\/\/iconoclaste.net\/blog\/2026\/08\/13\/demonoida\/","title":{"rendered":"Demonoida"},"content":{"rendered":"\n<!-- Jouet CSS + JS : D\u00e9monoida \u2013 yeux qui suivent la souris\n     + preload barre de progression (#ff33ff)\n     + survol du nez \u2192 tremblement + cri \u00abHEY ! Pas mon nez !\u00bb\n     \u00c0 coller dans un bloc HTML personnalis\u00e9 WordPress\n\n     FICHIERS \u00c0 UPLOADER dans \/wp-content\/uploads\/2026\/08\/ :\n     - demonoida.webp\n     - iris.png\n     - hey-pas-mon-nez.mp3\n-->\n<div class=\"demonoida-wrapper\" id=\"demonoida-wrapper\">\n  <!-- Loader -->\n  <div class=\"demonoida-loader\" id=\"demonoida-loader\">\n    <div class=\"demonoida-progress-wrap\">\n      <div class=\"demonoida-progress-bar\" id=\"demonoida-bar\"><\/div>\n    <\/div>\n    <div class=\"demonoida-progress-text\" id=\"demonoida-pct\">0%<\/div>\n    <div class=\"demonoida-loading-label\">chargement\u2026<\/div>\n  <\/div>\n\n  <!-- Jouet (cach\u00e9 pendant le preload) -->\n  <div id=\"demonoida-toy\" class=\"demonoida-toy\" style=\"opacity:0;visibility:hidden;\">\n    <img loading=\"lazy\" decoding=\"async\" class=\"demonoida-base\"\n         src=\"https:\/\/iconoclaste.net\/blog\/wp-content\/uploads\/2026\/08\/demonoida.webp\"\n         alt=\"D\u00e9monoida\"\n         width=\"1408\" height=\"1408\"\n         draggable=\"false\">\n    <img loading=\"lazy\" decoding=\"async\" class=\"demonoida-iris demonoida-iris-left\"\n         src=\"https:\/\/iconoclaste.net\/blog\/wp-content\/uploads\/2026\/08\/iris.png\"\n         alt=\"\"\n         width=\"60\" height=\"60\"\n         draggable=\"false\">\n    <img loading=\"lazy\" decoding=\"async\" class=\"demonoida-iris demonoida-iris-right\"\n         src=\"https:\/\/iconoclaste.net\/blog\/wp-content\/uploads\/2026\/08\/iris.png\"\n         alt=\"\"\n         width=\"60\" height=\"60\"\n         draggable=\"false\">\n    <!-- Zone invisible du nez -->\n    <div class=\"demonoida-nose-hit\" id=\"demonoida-nose\" title=\"\"><\/div>\n  <\/div>\n<\/div>\n\n<style>\n  .demonoida-wrapper {\n    position: relative;\n    width: 100%;\n    max-width: 100%;\n    margin: 0 auto;\n    aspect-ratio: 1 \/ 1;\n    background: #0a0a0a;\n    overflow: hidden;\n    user-select: none;\n    -webkit-user-select: none;\n  }\n\n  \/* === LOADER === *\/\n  .demonoida-loader {\n    position: absolute;\n    inset: 0;\n    z-index: 20;\n    display: flex;\n    flex-direction: column;\n    align-items: center;\n    justify-content: center;\n    background: #0a0a0a;\n    transition: opacity 0.35s ease;\n  }\n\n  .demonoida-progress-wrap {\n    width: 55%;\n    max-width: 280px;\n    height: 6px;\n    background: #2a2a2a;\n    border-radius: 3px;\n    overflow: hidden;\n    margin-bottom: 12px;\n  }\n\n  .demonoida-progress-bar {\n    height: 100%;\n    width: 0%;\n    background: #ff33ff;\n    border-radius: 3px;\n    transition: width 0.2s ease;\n  }\n\n  .demonoida-progress-text {\n    font-family: \"Courier New\", Courier, monospace;\n    font-size: 15px;\n    color: #ff33ff;\n    letter-spacing: 1px;\n    margin-bottom: 6px;\n  }\n\n  .demonoida-loading-label {\n    font-family: \"Courier New\", Courier, monospace;\n    font-size: 12px;\n    color: #888;\n    text-transform: lowercase;\n  }\n\n  \/* === TOY === *\/\n  .demonoida-toy {\n    position: absolute;\n    inset: 0;\n    width: 100%;\n    height: 100%;\n    line-height: 0;\n    transition: opacity 0.4s ease;\n  }\n\n  .demonoida-toy .demonoida-base {\n    display: block;\n    width: 100%;\n    height: 100%;\n    object-fit: contain;\n    margin: 0;\n    padding: 0;\n    border: 0;\n    pointer-events: none;\n  }\n\n  .demonoida-toy .demonoida-iris {\n    position: absolute;\n    width: 4.261%;          \/* 60 \/ 1408 *\/\n    height: 4.261%;\n    left: 0;\n    top: 0;\n    transform: translate(-50%, -50%);\n    pointer-events: none;\n    z-index: 2;\n    will-change: left, top;\n  }\n\n  \/* positions de repos (centres des yeux) *\/\n  .demonoida-toy .demonoida-iris-left {\n    left: 39.84%;   \/* 561 \/ 1408 *\/\n    top: 40.55%;    \/* 571 \/ 1408 *\/\n  }\n  .demonoida-toy .demonoida-iris-right {\n    left: 60.01%;   \/* 845 \/ 1408 *\/\n    top: 40.70%;    \/* 573 \/ 1408 *\/\n  }\n\n  \/* Zone invisible du nez (hit area) *\/\n  .demonoida-nose-hit {\n    position: absolute;\n    left: 49.93%;           \/* 703 \/ 1408 *\/\n    top: 49.01%;            \/* 690 \/ 1408 *\/\n    width: 11%;\n    height: 12.5%;\n    transform: translate(-50%, -50%);\n    z-index: 5;\n    cursor: pointer;\n  }\n\n  \/* Tremblement pendant le survol du nez *\/\n  .demonoida-toy.is-hover-nose {\n    animation: demonoida-shake 0.32s infinite ease-in-out;\n  }\n\n  @keyframes demonoida-shake {\n    0%, 100% { transform: translate(0, 0) rotate(0deg); }\n    10%  { transform: translate(-3px,  2px) rotate(-0.9deg); }\n    20%  { transform: translate( 3px, -2px) rotate( 0.8deg); }\n    30%  { transform: translate(-2px,  3px) rotate(-0.6deg); }\n    40%  { transform: translate( 2px, -1px) rotate( 0.7deg); }\n    50%  { transform: translate(-3px,  1px) rotate(-0.5deg); }\n    60%  { transform: translate( 3px,  2px) rotate( 0.9deg); }\n    70%  { transform: translate(-1px, -3px) rotate(-0.7deg); }\n    80%  { transform: translate( 2px,  1px) rotate( 0.4deg); }\n    90%  { transform: translate(-2px, -1px) rotate(-0.3deg); }\n  }\n<\/style>\n\n<script>\n(function () {\n  const wrapper   = document.getElementById('demonoida-wrapper');\n  const loader    = document.getElementById('demonoida-loader');\n  const bar       = document.getElementById('demonoida-bar');\n  const pctEl     = document.getElementById('demonoida-pct');\n  const container = document.getElementById('demonoida-toy');\n  const noseHit   = document.getElementById('demonoida-nose');\n\n  if (!wrapper || !container) return;\n\n  const BASE_URL  = 'https:\/\/iconoclaste.net\/blog\/wp-content\/uploads\/2026\/08\/demonoida.webp';\n  const IRIS_URL  = 'https:\/\/iconoclaste.net\/blog\/wp-content\/uploads\/2026\/08\/iris.png';\n  const HEY_URL   = 'https:\/\/iconoclaste.net\/blog\/wp-content\/uploads\/2026\/08\/hey-pas-mon-nez.mp3';\n\n  \/\/ ========== PRELOAD ==========\n  \/\/ On mobile, canplaythrough de l'audio bloque souvent \u2192 on ne compte QUE les images\n  \/\/ L'audio se charge en arri\u00e8re-plan et sera pr\u00eat au premier survol.\n  const total = 2;\n  let loaded = 0;\n  let finished = false;\n\n  function updateProgress() {\n    if (finished) return;\n    loaded++;\n    const pct = Math.min(100, Math.round((loaded \/ total) * 100));\n    bar.style.width = pct + '%';\n    pctEl.textContent = pct + '%';\n\n    if (loaded >= total) {\n      finishLoader();\n    }\n  }\n\n  function finishLoader() {\n    if (finished) return;\n    finished = true;\n    setTimeout(function () {\n      loader.style.opacity = '0';\n      setTimeout(function () {\n        loader.style.display = 'none';\n        container.style.visibility = 'visible';\n        container.style.opacity = '1';\n        initToy();\n      }, 320);\n    }, 180);\n  }\n\n  \/\/ Images (seuls \u00e9l\u00e9ments qui comptent pour la barre)\n  [BASE_URL, IRIS_URL].forEach(function (url) {\n    const img = new Image();\n    img.onload = updateProgress;\n    img.onerror = updateProgress;\n    img.src = url;\n  });\n\n  \/\/ Audio \u2013 chargement silencieux en arri\u00e8re-plan (ne bloque plus le loader)\n  const heyAudio = new Audio();\n  heyAudio.preload = 'auto';\n  heyAudio.src = HEY_URL;\n\n  \/\/ S\u00e9curit\u00e9 : si quelque chose coince, on force l'affichage apr\u00e8s 5 s\n  setTimeout(function () {\n    if (!finished) {\n      bar.style.width = '100%';\n      pctEl.textContent = '100%';\n      finishLoader();\n    }\n  }, 5000);\n\n  \/\/ ========== TOY LOGIC ==========\n  function initToy() {\n    const base = container.querySelector('.demonoida-base');\n    const irisLeft  = container.querySelector('.demonoida-iris-left');\n    const irisRight = container.querySelector('.demonoida-iris-right');\n\n    \/\/ Coordonn\u00e9es normalis\u00e9es (0\u20131) \u2013 image originale 1408\u00d71408\n    const ORIG = 1408;\n    const eyes = [\n      { el: irisLeft,  cx: 561 \/ ORIG, cy: 571 \/ ORIG, max: 48 \/ ORIG },\n      { el: irisRight, cx: 845 \/ ORIG, cy: 573 \/ ORIG, max: 48 \/ ORIG }\n    ];\n\n    let raf = null;\n    let lastEvent = null;\n\n    function clampEyes() {\n      if (!lastEvent || !base) return;\n      const rect = base.getBoundingClientRect();\n      if (rect.width < 10) return;\n\n      const mx = (lastEvent.clientX - rect.left) \/ rect.width;\n      const my = (lastEvent.clientY - rect.top)  \/ rect.height;\n\n      eyes.forEach(function (eye) {\n        let dx = mx - eye.cx;\n        let dy = my - eye.cy;\n        const dist = Math.sqrt(dx * dx + dy * dy);\n        if (dist > eye.max) {\n          const s = eye.max \/ dist;\n          dx *= s;\n          dy *= s;\n        }\n        eye.el.style.left = ((eye.cx + dx) * 100).toFixed(3) + '%';\n        eye.el.style.top  = ((eye.cy + dy) * 100).toFixed(3) + '%';\n      });\n      raf = null;\n    }\n\n    function onMove(e) {\n      lastEvent = e;\n      if (!raf) raf = requestAnimationFrame(clampEyes);\n    }\n\n    document.addEventListener('mousemove', onMove, { passive: true });\n    document.addEventListener('touchmove', function (e) {\n      if (e.touches && e.touches[0]) {\n        lastEvent = e.touches[0];\n        if (!raf) raf = requestAnimationFrame(clampEyes);\n      }\n    }, { passive: true });\n\n    \/\/ Position initiale\n    eyes.forEach(function (eye) {\n      eye.el.style.left = (eye.cx * 100).toFixed(3) + '%';\n      eye.el.style.top  = (eye.cy * 100).toFixed(3) + '%';\n    });\n\n    window.addEventListener('resize', function () {\n      if (lastEvent) onMove(lastEvent);\n    });\n\n    \/\/ ========== NEZ : tremblement + cri ==========\n    let heyCooldown = false;\n\n    function playHey() {\n      if (heyCooldown) return;\n      heyCooldown = true;\n      setTimeout(function () { heyCooldown = false; }, 1200);\n\n      try {\n        heyAudio.currentTime = 0;\n        heyAudio.volume = 1;\n        const p = heyAudio.play();\n        if (p && typeof p.catch === 'function') {\n          p.catch(function () {}); \/\/ ignore autoplay policy errors\n        }\n      } catch (e) {}\n    }\n\n    noseHit.addEventListener('mouseenter', function () {\n      container.classList.add('is-hover-nose');\n      playHey();\n    });\n\n    noseHit.addEventListener('mouseleave', function () {\n      container.classList.remove('is-hover-nose');\n    });\n\n    \/\/ Support tactile\n    noseHit.addEventListener('touchstart', function (e) {\n      e.preventDefault();\n      container.classList.add('is-hover-nose');\n      playHey();\n      setTimeout(function () {\n        container.classList.remove('is-hover-nose');\n      }, 700);\n    }, { passive: false });\n  }\n})();\n<\/script>\n\n\n\n\n<p class=\"wp-block-paragraph\">On avait dit \u00abPas le nez!\u00bb<\/p>\n","protected":false},"excerpt":{"rendered":"<p>0% chargement\u2026 On avait dit \u00abPas le nez!\u00bb<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[269],"tags":[134,225,81,304,303],"class_list":["post-1350","post","type-post","status-publish","format-standard","hentry","category-experiences","tag-demon","tag-expression","tag-fuzzout","tag-grimace","tag-interactif"],"_links":{"self":[{"href":"https:\/\/iconoclaste.net\/blog\/wp-json\/wp\/v2\/posts\/1350","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/iconoclaste.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/iconoclaste.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/iconoclaste.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/iconoclaste.net\/blog\/wp-json\/wp\/v2\/comments?post=1350"}],"version-history":[{"count":4,"href":"https:\/\/iconoclaste.net\/blog\/wp-json\/wp\/v2\/posts\/1350\/revisions"}],"predecessor-version":[{"id":1355,"href":"https:\/\/iconoclaste.net\/blog\/wp-json\/wp\/v2\/posts\/1350\/revisions\/1355"}],"wp:attachment":[{"href":"https:\/\/iconoclaste.net\/blog\/wp-json\/wp\/v2\/media?parent=1350"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/iconoclaste.net\/blog\/wp-json\/wp\/v2\/categories?post=1350"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/iconoclaste.net\/blog\/wp-json\/wp\/v2\/tags?post=1350"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}