1/* PJB â composants du site. Tout est visible sans JS ; le script anime et rend interactif. */ 2(function () { 3 'use strict'; 4 var reduit = window.matchMedia && matchMedia('(prefers-reduced-motion: reduce)').matches; 5 var $ = function (s, c) { return (c || document).querySelector(s); }; 6 var $$ = function (s, c) { return Array.prototype.slice.call((c || document).querySelectorAll(s)); }; 7 var esc = function (s) { return String(s).replace(/[&<>"]/g, function (c) { return { '&': '&', '<': '<', '>': '>', '"': '"' }[c]; }); }; 8 var IMG = (window.PJB && PJB.img) || ''; 9 10 /* ---------- hero : la scie et l'aiguille suivent leur tracé ---------- */ 11 function suivre(path, outil, svg, duree, rot, apres) { 12 var L = path.getTotalLength(), t0 = null, dash = path.getAttribute('stroke-dasharray'); 13 path.style.strokeDasharray = L; path.style.strokeDashoffset = L; 14 function place(d) { 15 var p = path.getPointAtLength(d), m = svg.getScreenCTM(), box = outil.parentNode.getBoundingClientRect(), ob = outil.getBoundingClientRect(); 16 if (!m) return; 17 var x = p.x * m.a + m.e - box.left, y = p.y * m.d + m.f - box.top; outil.style.left = '0px'; outil.style.top = '0px'; 18 var q = path.getPointAtLength(Math.min(L, d + 2)), ang = Math.atan2(q.y - p.y, q.x - p.x) * 180 / Math.PI; 19 outil.style.transform = 'translate(' + (x - ob.width / 2) + 'px,' + (y - ob.height / 2) + 'px) rotate(' + (rot ? ang : d * 3) + 'deg)'; 20 } 21 function pas(ts) { 22 if (!t0) t0 = ts; 23 var k = Math.min(1, (ts - t0) / duree), e = k < .5 ? 2 * k * k : 1 - Math.pow(-2 * k + 2, 2) / 2, d = e * L; 24 path.style.strokeDashoffset = L - d; place(d); 25 if (k < 1) requestAnimationFrame(pas); 26 else { path.style.strokeDasharray = dash; path.style.strokeDashoffset = 0; outil.style.opacity = 0; if (apres) apres(); } 27 } 28 outil.style.opacity = 1; requestAnimationFrame(pas); 29 } 30 function sciure(demi, outil) { 31 var n = 0, it = setInterval(function () { 32 if (++n > 40 || outil.style.opacity === '0') { clearInterval(it); return; } 33 var s = document.createElement('i'); s.className = 'pj-sciure'; 34 var r = outil.getBoundingClientRect(), b = demi.getBoundingClientRect(); 35 s.style.left = (r.left - b.left + r.width / 2) + 'px'; s.style.top = (r.top - b.top + r.height / 2) + 'px'; 36 demi.appendChild(s); 37 s.animate([{ opacity: .9, transform: 'translate(0,0)' }, { opacity: 0, transform: 'translate(' + (Math.random() * 40 - 20) + 'px,' + (20 + Math.random() * 30) + 'px)' }], { duration: 900, easing: 'ease-out' }).onfinish = function () { s.remove(); }; 38 }, 90); 39 } 40 var hero = $('.pj-hero'); 41 if (hero && !reduit) { 42 var scie = $('#pj-scie'), fil = $('#pj-fil'), lame = $('.pj-lame', hero), aig = $('.pj-aiguille', hero); 43 var pieces = $$('.pj-piece', hero); 44 pieces.forEach(function (p) { p.style.opacity = .25; p.style.transform = 'translateY(14px)'; p.style.transition = 'opacity .6s, transform .6s cubic-bezier(.3,1.6,.5,1)'; }); 45 var montre = function (i) { return function () { pieces[i].style.opacity = 1; pieces[i].style.transform = 'none'; }; }; 46 setTimeout(function () { 47 if (scie && lame) { suivre(scie, lame, scie.ownerSVGElement, 3400, false, montre(0)); sciure(scie.closest('.pj-demi'), lame); } 48 if (fil && aig) setTimeout(function () { suivre(fil, aig, fil.ownerSVGElement, 3600, true, montre(1)); }, 350); 49 }, 350); 50 }
50 else if (hero) { $$('.pj-lame,.pj-aiguille', hero).forEach(function (e) { e.style.display = 'none'; }); } 51 52 /* ---------- la toise des âges ---------- */ 53 $$('[data-outil="toise"]').forEach(function (o) { 54 var D = JSON.parse(o.getAttribute('data-toise')), r = $('#pj-taille', o), sc = $('.pj-toise-scene', o), ch = $('.pj-chambr', o), mq = $('.pj-marque', o), img = $('.pj-jouet', o), der = -1; 55 function grad() { 56 $$('.gr,.cm', ch).forEach(function (n) { n.remove(); }); 57 var H = sc.clientHeight - 22; 58 for (var cm = 50; cm <= 120; cm += 2) { 59 var y = H - (cm - 48) / (122 - 48) * H, g = document.createElement('div'); 60 g.className = 'gr'; g.style.top = y + 'px'; g.style.width = cm % 10 === 0 ? '38px' : cm % 5 === 0 ? '24px' : '13px'; ch.appendChild(g); 61 if (cm % 10 === 0) { var l = document.createElement('span'); l.className = 'cm'; l.style.top = y + 'px'; l.textContent = cm; ch.appendChild(l); } 62 } 63 return H; 64 } 65 var H = grad(); 66 function poser() { 67 var cm = +r.value, i = 0; while (i < D.length - 1 && cm > D[i].cm) i++; 68 $('#pj-taille-o', o).textContent = cm + ' cm'; 69 mq.style.bottom = ((cm - 48) / (122 - 48) * H + 20) + 'px'; 70 $('em', mq).textContent = cm + ' cm · ' + D[i].t; 71 if (i === der) return; der = i; 72 $('#pj-toise-t', o).textContent = D[i].t; $('#pj-toise-g', o).textContent = D[i].g; 73 $('#pj-toise-j', o).innerHTML = D[i].j.map(function (x) { return '<li><svg class="pj-ico" aria-hidden="true"><use href="#pj-etoile"/></svg><span><b>' + esc(x[0]) + '</b> â ' + esc(x[1]) + '</span></li>'; }).join(''); 74 var u = $('#pj-toise-u', o); u.href = D[i].u; 75 var src = IMG + D[i].i + '.webp'; 76 if (window.anime && !reduit) anime({ targets: img, translateY: [0, 24], opacity: [1, 0], duration: 150, easing: 'easeInQuad', complete: function () { img.src = src; anime({ targets: img, translateY: [-36, 0], opacity: [0, 1], duration: 560, easing: 'easeOutElastic(1,.6)' }); } }); 77 else img.src = src; 78 } 79 r.addEventListener('input', poser); poser(); 80 addEventListener('resize', function () { H = grad(); der = -1; poser(); }); 81 }); 82 83 /* ---------- l'étiquette d'entretien ---------- */ 84 $$('[data-outil="entretien"]').forEach(function (o) { 85 var D = JSON.parse(o.getAttribute('data-etiq')), s = $('#pj-matiere', o); 86 s.addEventListener('change', function () { 87 var x = D[s.value]; 88 $('#pj-etiq-t', o).textContent = x[1]; 89 $('#pj-symb', o).innerHTML = x[2].map(function (y) { return '<span class="' + (y[1] ? 'non' : '') + '" title="' + (y[1] ? 'à éviter : ' : '') + esc(y[0]) + '">' + esc(y[0]) + '</span>'; }).join(''); 90 $('#pj-etiq-e', o).innerHTML = x[3].map(function (l) { return '<li>' + esc(l) + '</li>'; }).join(''); 91 }); 92 }); 93 94 /* ---------- le coffre à cadeaux ---------- */ 95 $$('[data-outil="coffre"]').forEach(function (o) { 96 var D = JSON.parse(o.getAttribute('data-coffre')); 97 function maj() { 98 var l = D[$('#pj-lien', o).value][$('#pj-budget', o).value]; 99 var z = $('#pj-idees', o); 100 z.innerHTML = l.map(function (x) { return '<div class="pj-idee"><img class="pj-illu" src="' + IMG + x[0] + '.webp" alt="' + esc(x[1]) + '" width="72" height="72" loading="lazy"><div><b>' + esc(x[1]) + '</b><p>' + esc(x[2]) + '</p></div></div>'; }).join(''); 101 if (window.anime && !reduit) anime({ targets: z.children, translateY: [16, 0], opacity: [0, 1], delay: anime.stagger(90), duration: 420, easing: 'easeOutQuad' }); 102 } 103 $('#pj-lien', o).addEventListener('change', maj); $('#pj-budget', o).addEventListener('change', maj); 104 }); 105 106 /* ---------- le test du tube (cylindre EN 71-1 : à 31,7 mm, profondeur 25,4 à 57,1 mm) ---------- */ 107 function tube(l1, l2, l3) { 108 var d = [l1, l2, l3].map(Number).sort(function (a, b) { return a - b; }); 109 if (d.some(function (x) { return !(x > 0); })) return { ok: null }; 110 var passe = d[0] <= 31.7 && d[1] <= 31.7 && d[2] <= 57.1; 111 return { ok: !passe, d: d }; 112 } 113 window.pjbTube = tube; 114 $$('[data-outil="tube"]').forEach(function (o) { 115 function maj() { 116 var r = tube($('#pj-l1', o).value, $('#pj-l2', o).value, $('#pj-l3', o).value), v = $('#pj-verdict', o); 117 if (r.ok === null) { v.className = 'pj-verdict'; v.textContent = 'Les trois dimensions, en millimètres.'; return; } 118 var d = r.d; 119 v.className = 'pj-verdict ' + (r.ok ? 'ok' : 'ko'); 120 v.innerHTML = r.ok 121 ? '<b>Elle ne passe pas.</b> ' + (d[1] > 31.7 ? 'Sa section de ' + d[0] + ' à ' + d[1] + ' mm dépasse les 31,7 mm du cylindre.' : 'Ses ' + d[2] + ' mm de long dépassent la profondeur du cylindre (57,1 mm).') 122 : '<b>Elle entre dans le tube.</b> Pièce interdite avant 3 ans : ' + d[0] + ' à ' + d[1] + ' mm tiennent dans 31,7 mm.'; 123 } 124 ['#pj-l1', '#pj-l2', '#pj-l3'].forEach(function (s) { $(s, o).addEventListener('input', maj); }); maj(); 125 }); 126 127 /* ---------- l'avis de recherche ---------- */ 128 $$('[data-outil="avis"]').forEach(function (o) { 129 function v(id) { return ($('#' + id, o).value || '').trim(); } 130 function maj() { 131 var f = $('#pj-d-forme', o), nom = v('pj-d-nom') || 'Doudou'; 132 $('#pj-d-nomA', o).textContent = nom; 133 $('#pj-d-img', o).src = IMG + f.value + '.webp'; 134 $('#pj-d-det', o).innerHTML = '<b>' + esc(f.options[f.selectedIndex].text.replace(/^un /, 'Un ')) + '</b>' + (v('pj-d-couleur') ? ', ' + esc(v('pj-d-couleur')) : '') + '.<br>Perdu ' + esc(v('pj-d-lieu')) + '.<br>Si vous lâavez trouvé : ' + esc(v('pj-d-contact')) + '.<br><b>Un enfant lâattend pour dormir. Merci !</b>'; 135 }
136 $$('input,select', o).forEach(function (e) { e.addEventListener('input', maj); e.addEventListener('change', maj); }); maj(); 137 $('[data-act="imprimer"]', o).addEventListener('click', function () { window.print(); }); 138 $('[data-act="copier"]', o).addEventListener('click', function (e) { 139 var t = 'DOUDOU PERDU â ' + v('pj-d-nom') + '\n' + $('#pj-d-det', o).innerText; 140 var b = e.currentTarget; 141 (navigator.clipboard ? navigator.clipboard.writeText(t) : Promise.reject()).then(function () { b.textContent = 'Texte copié'; }).catch(function () { b.textContent = 'Sélectionnez le texte de lâaffiche'; }); 142 }); 143 }); 144 $$('.pj-filtres').forEach(function (g) { 145 g.addEventListener('click', function (e) { 146 var b = e.target.closest('button'); if (!b) return; 147 $$('button', g).forEach(function (x) { x.setAttribute('aria-pressed', x === b); }); 148 var f = b.getAttribute('data-f'); 149 $$('.pj-annonce', g.parentNode).forEach(function (a) { a.hidden = f !== 'tous' && a.getAttribute('data-st') !== f; }); 150 }); 151 }); 152 153 /* ---------- commande : l'offre de la page présélectionnée ---------- */ 154 $$('.pj-commande[data-offre]').forEach(function (c) { var s = $('select[name="offre"]', c); if (s) s.value = c.getAttribute('data-offre'); }); 155 156 /* ---------- la toise de lecture (articles) ---------- */ 157 var lec = $('.pj-lecture i'), art = $('.single-post .entry-content'); 158 if (lec && art) { 159 var majL = function () { var r = art.getBoundingClientRect(), k = Math.min(1, Math.max(0, -r.top / Math.max(1, r.height - innerHeight))); lec.style.bottom = (k * 96) + '%'; }; 160 addEventListener('scroll', majL, { passive: true }); majL(); 161 } 162})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.