Retrouvez les paires

Cliquez sur un mot français puis sur sa traduction coréenne correspondante.

Palmok
Kyong Rye
Avant-bras
Ap
Position en L
Niunja Sogi
Charyot
Devant
Attention
Saluez
0 / 5 paires trouvées
/* position:fixed + top:0/left:0 explicites, z-index très haut : le calque reste calé sur le vrai écran visible et toujours au-dessus de tout le reste de la page (carte de fin d'exercice comprise), quel que soit l'endroit où ce widget HTML est placé dans la mise en page. */ #confetti-wrapper { position: fixed; top: 0; left: 0; width: 100%; height: 100vh; overflow: hidden; pointer-events: none; z-index: 999999; background: transparent; } #confettiCanvas { display: block; width: 100%; height: 100%; background: transparent; } (function () { // ========================================================================= // CONFETTI — reprend fidèlement le moteur de particules fourni comme // référence ("c'est cet effet que je veux") : explosion en forme de // comètes (tête étoilée + traînée dessinée directement, dont la longueur // dépend de la vitesse COURANTE de la particule à chaque image -> elle // s'amenuise naturellement quand la particule ralentit, sans aucun // bricolage de canvas), suivies d'étoiles simples scintillantes. // // Différences par rapport au fichier de référence (qui était une démo // "cliquez pour rejouer") : // - Le canvas est calé en plein écran (position fixed) et surveille la // section .taekwon_page_complete comme le reste du site : l'effet se // déclenche automatiquement à la fin d'un exercice, pas au clic. // - La pluie d'étoiles est maintenant ILLIMITÉE : au lieu d'un seul lot // fini de particules, de nouveaux petits lots sont générés en continu // (confettiRain rappelée à intervalle régulier) tant que l'écran de // fin d'exercice reste affiché, et s'arrêtent dès qu'il se referme. // - Plus de dépendance externe (canvas-confetti) : ce moteur est // autonome, ce qui règle aussi au passage tous les problèmes qu'on // avait avec les formes figées/la rotation impossible par particule // de cette librairie -- ici chaque comète est simplement tournée // (ctx.rotate) selon sa propre direction de vol à chaque image. var wrapper = document.getElementById('confetti-wrapper'); var canvas = document.getElementById('confettiCanvas'); var ctx = canvas.getContext('2d'); // Palette reprise telle quelle du fichier de référence (turquoise / // jaune / corail / orange). var COLORS = ['#3FC7C1', '#FFCE45', '#F2726B', '#FFA94D']; var W, H, DPR; function resize() { DPR = Math.min(window.devicePixelRatio || 1, 2); W = wrapper.clientWidth || window.innerWidth; H = wrapper.clientHeight || window.innerHeight; canvas.width = W * DPR; canvas.height = H * DPR; ctx.setTransform(DPR, 0, 0, DPR, 0, 0); } window.addEventListener('resize', resize); resize(); var MAX_PARTICLES = 500; // garde-fou : jamais un nombre illimité de // particules à l'écran, même si la pluie // tourne très longtemps. var particles = []; var rand = function (a, b) { return a + Math.random() * (b - a); }; var pick = function (arr) { return arr[(Math.random() * arr.length) | 0]; }; // Une particule = une "comète" : une petite étoile à 4 branches en tête, // suivie d'une traînée qui s'amenuise. La traînée est dessinée en // fonction de la vitesse courante -> elle rétrécit naturellement quand // la particule ralentit, exactement comme demandé ("les étoiles ont // parfois des traînées au début quand elles accélèrent, ensuite elles // n'en ont plus"). `delay` retarde le "vrai" départ de la particule // (utilisé par la pluie pour faire apparaître les étoiles de façon // échelonnée plutôt que toutes d'un coup). function spawnParticle(x, y, opts) { if (particles.length >= MAX_PARTICLES) particles.shift(); // évite tout emballement opts = opts || {}; var angle = opts.angle !== undefined ? opts.angle : rand(0, Math.PI * 2); var speed = opts.speed !== undefined ? opts.speed : rand(340, 780); var isComet = Math.random() < 0.72; // certaines restent de simples étoiles particles.push({ x: x, y: y, vx: Math.cos(angle) * speed, vy: Math.sin(angle) * speed, size: opts.size !== undefined ? opts.size : rand(9, 18), color: pick(COLORS), isComet: isComet, age: 0, delay: opts.delay || 0, // durée avant de commencer à s'estomper, puis durée du fondu holdTime: opts.holdTime !== undefined ? opts.holdTime : rand(0.45, 0.9), fadeTime: opts.fadeTime !== undefined ? opts.fadeTime : rand(0.7, 1.3), // rotation propre de l'étoile (indépendante de la trajectoire) spin: rand(-4, 4), rot: rand(0, Math.PI * 2), // les étoiles "résiduelles" scintillent au lieu de juste disparaître twinkle: !isComet ? rand(3, 7) : (opts.twinkle || 0), gravity: opts.gravity !== undefined ? opts.gravity : 260, alpha: 1, dead: false }); } function confettiBurst(x, y, count) { count = count || 90; for (var i = 0; i < count; i++) spawnParticle(x, y); } // Pluie d'étoiles qui tombent du haut de l'écran et s'évanouissent en // cours de chute. `originX` centre la zone de chute (facultatif, sinon // toute la largeur). function confettiRain(originX, count, spread) { count = count || 26; var cx = originX === undefined ? W / 2 : originX; var half = (spread === undefined ? W * 0.85 : spread) / 2; for (var i = 0; i < count; i++) { var x = cx + rand(-half, half); var y = rand(-70, -10); // part juste au-dessus du cadre visible spawnParticle(x, y, { angle: Math.PI / 2 + rand(-0.15, 0.15), // vers le bas, léger dérapage speed: rand(50, 130), // vitesse initiale faible... gravity: 220, // ...qui s'accélère en tombant size: rand(7, 14), delay: rand(0, 1.3), // apparition échelonnée holdTime: rand(0.8, 1.5), fadeTime: rand(0.5, 0.9), twinkle: rand(4, 8) }); } } // Vide instantanément toutes les particules à l'écran. function confettiStop() { particles.length = 0; } function drawStar(cx, cy, outerR, innerR, rotation, color, alpha) { ctx.save(); ctx.translate(cx, cy); ctx.rotate(rotation); ctx.beginPath(); var spikes = 4; for (var i = 0; i 2) { var grad = ctx.createLinearGradient(0, 0, -tailLen, 0); grad.addColorStop(0, p.color); grad.addColorStop(1, 'transparent'); ctx.beginPath(); ctx.moveTo(0, -p.size * 0.35); ctx.lineTo(-tailLen, 0); ctx.lineTo(0, p.size * 0.35); ctx.closePath(); ctx.fillStyle = grad; ctx.fill(); } ctx.restore(); // petite étoile à la tête de la comète drawStar(p.x, p.y, p.size, p.size * 0.42, p.rot, p.color, p.alpha); } var boucleActive = false; var last = 0; function frame(now) { if (!boucleActive) return; if (!last) last = now; var dt = Math.min((now - last) / 1000, 0.05); last = now; ctx.clearRect(0, 0, W, H); // reste transparent, pas de fillRect for (var i = particles.length - 1; i >= 0; i--) { var p = particles[i]; p.age += dt; // particule en attente (delay pas encore écoulé) : invisible, immobile if (p.age

p.holdTime) { var t = (localAge - p.holdTime) / p.fadeTime; baseAlpha = Math.max(0, 1 - t); } if (localAge > p.holdTime + p.fadeTime || baseAlpha <= 0.01) { particles.splice(i, 1); continue; } // le scintillement module juste l'alpha affiché à l'instant t, sans // jamais s'accumuler d'une image à l'autre p.alpha = p.twinkle ? baseAlpha * (0.55 + 0.45 * Math.sin(localAge * p.twinkle)) : baseAlpha; if (p.isComet && localAge <p.holdTime * 0.9) { drawComet(p); } else { drawStar(p.x, p.y, p.size, p.size * 0.42, p.rot, p.color, p.alpha); } } requestAnimationFrame(frame); } function demarrerBoucle() { if (boucleActive) return; boucleActive = true; last = 0; requestAnimationFrame(frame); } function arreterBoucle() { boucleActive = false; } // ✅ Pluie continue : au lieu d'un seul lot fini de particules, on // relance confettiRain() à intervalle régulier tant que l'écran de fin // d'exercice reste affiché -- elle ne s'arrête donc jamais d'elle-même. var pluieInterval = null; function demarrerPluie() { arreterPluie(); // sécurité : jamais deux pluies en même temps pluieInterval = setInterval(function () { confettiRain(undefined, 3 + Math.floor(Math.random() * 3), W * 0.9); }, 320); } function arreterPluie() { if (pluieInterval) { clearInterval(pluieInterval); pluieInterval = null; } } var sectionVisible = false; function tirerConfettis() { resize(); demarrerBoucle(); // Explosion près du haut de l'écran ("centre haut"). confettiBurst(W / 2, H * 0.2); // La pluie enchaîne tout de suite : chaque étoile de pluie a son // propre délai d'apparition échelonné (voir confettiRain), donc la // transition avec l'explosion reste douce même sans attendre ici. demarrerPluie(); } function arreterTout() { arreterPluie(); confettiStop(); arreterBoucle(); ctx.clearRect(0, 0, W, H); } // ✅ On surveille la section .taekwon_page_complete (voir // showCompletionSection() dans taekwon-progress.js, qui passe sa // visibilité à "visible" quand l'exercice est terminé) et on tire // l'explosion exactement à ce moment-là, à chaque fois qu'elle // réapparaît -- et on arrête tout (boucle + pluie continue) dès qu'elle // se referme. function surveillerSection() { var section = document.querySelector('[class*="taekwon_page_complete"]'); if (!section) { setTimeout(surveillerSection, 200); return; } var arretDifféré = null; var observer = new MutationObserver(function () { var visible = section.style.visibility === 'visible'; if (visible) { // La section redevient (ou reste) visible : on annule un arrêt // qui aurait pu être programmé juste avant (voir ci-dessous). if (arretDifféré) { clearTimeout(arretDifféré); arretDifféré = null; } if (!sectionVisible) { sectionVisible = true; tirerConfettis(); } } else if (sectionVisible && !arretDifféré) { // On n'arrête pas tout de suite : le chargement du résumé de fin // d'exercice (badges, score, bouton "Rejouer"...) peut modifier // brièvement le style de la section pendant son rendu, ce qui // déclenche cet observer sans que la section ait vraiment été // refermée. Un arrêt immédiat sur ce simple "scintillement" // coupait la pluie de confettis en plein milieu. On attend donc // un court instant : si la section n'est toujours pas visible // passé ce délai, on arrête pour de bon. arretDifféré = setTimeout(function () { arretDifféré = null; if (section.style.visibility !== 'visible') { sectionVisible = false; arreterTout(); } }, 500); } }); observer.observe(section, { attributes: true, attributeFilter: ['style'] }); // La pluie pouvant durer longtemps, on garde le canvas à la bonne // taille si l'écran change (rotation du téléphone, etc.) pendant // qu'elle est affichée. window.addEventListener('resize', function () { if (sectionVisible) resize(); }); } surveillerSection(); })();

Well done!

Congratulations on finishing the matching game!

You can check out the other reviews.

Profil

tkbappsid67

Mon grade

Ceinture blanche

Mes badges

tkbappsid67

Mon grade

Ceinture blanche