Effets visuels créatifs

Effet de trace lumineuse du pointeur du couloir du lac nuageux

Dans le contexte d’un couloir de nuages au bord du lac, réalisez un effet de traînée du pointeur : contenu authentique, contrôles actionnables, retours d’état clairs et mise en page adaptée à toutes les tailles.

Effets visuels créatifsEffet de traînée du pointeurHTMLCanvasJavaScript
Après activation de JavaScript, ce cas peut être modifié, exécuté et enregistré. Code source fixe ci-dessous :
<!doctype html>
<html lang="fr" dir="ltr">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Effet de trace lumineuse du pointeur du couloir du lac nuageux</title>
  <style>
    :root { --ink:#30231f; --paper:#f9efe5; --accent:#8b6fb0; --secondary:#d7a971; --line:color-mix(in srgb, var(--ink) 18%, transparent); --shadow:0 24px 60px color-mix(in srgb, var(--ink) 16%, transparent); color-scheme:light; }
    * { box-sizing:border-box; }
    html { min-width:320px; background:var(--paper); }
    body { min-height:100vh; margin:0; overflow-x:hidden; color:var(--ink); font-family:Avenir,"PingFang SC",sans-serif; background:var(--paper); }
    button,input,select,textarea { color:inherit; font:inherit; }
    button,[role="button"],input,select,textarea { accent-color:var(--accent); }
    button { cursor:pointer; }
    button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible,[tabindex]:focus-visible { outline:3px solid var(--accent); outline-offset:3px; }
    [hidden] { display:none !important; }
    @media (max-width:700px) { .mast h1 { line-height:1.08 !important; letter-spacing:-.035em !important; overflow-wrap:anywhere; } }
    @media (prefers-reduced-motion:reduce) { *,*::before,*::after { scroll-behavior:auto !important; animation-duration:.01ms !important; animation-iteration-count:1 !important; transition-duration:.01ms !important; } }
    .page{width:min(1320px,calc(100% - 56px));margin:auto;padding:10vh 0}.mast{display:grid;grid-template-columns:minmax(0,1fr) 160px;gap:10vw;margin-block:6vh;align-items:start;margin-bottom:10vh}.mast h1{font-family:Avenir,"PingFang SC",sans-serif;font-weight:500;font-size:clamp(38px,8vw,88px);letter-spacing:-.055em;margin:0;line-height:.96}.eyebrow{display:block;margin-bottom:24px;font:600 10px/1 ui-monospace,monospace;letter-spacing:.22em}.intro{max-width:52ch;margin-top:28px;line-height:1.8}.scenario{font-size:13px;text-align:right}.demo{border-radius:1px;border-color:color-mix(in srgb,var(--ink) 35%,transparent);box-shadow:none;position:relative;min-height:420px;padding:clamp(28px,5vw,70px);background:transparent}@media(max-width:700px){.page{width:calc(100% - 24px);padding:36px 0}.mast{grid-template-columns:1fr;margin-bottom:30px}.scenario{text-align:left}.demo{padding:18px}}
    .panel{padding:18px;border:3px solid var(--ink);background:var(--paper);box-shadow:8px 8px 0 var(--ink)}.stack{display:grid;gap:12px}.row{display:flex;flex-wrap:wrap;gap:8px}.action{min-height:42px;padding:8px 13px;border:3px solid var(--ink);background:var(--paper);font-weight:900}.action.primary,.action.is-active{color:var(--paper);background:var(--ink)}.status{min-height:24px;padding:8px;color:var(--paper);background:var(--ink);font-weight:900}.metric{font-size:clamp(34px,8vw,76px);font-weight:900;letter-spacing:-.08em}.muted{font-weight:600}.chip{padding:5px 8px;border:2px solid var(--ink);font-weight:900}.meter{height:14px;border:3px solid var(--ink)}.meter>i{display:block;height:100%;background:var(--ink)}
    .composition-deck{display:grid;grid-template-rows:auto 1fr;border:1px solid var(--line);border-radius:24px;overflow:hidden;background:color-mix(in srgb,var(--ink) 4%,var(--paper))}.deck-bar{display:flex;justify-content:space-between;gap:18px;align-items:center;padding:12px 18px;color:var(--paper);background:var(--ink);font:700 12px/1 ui-monospace,monospace}.deck-lights{display:flex;gap:7px}.deck-lights i{width:10px;height:10px;border-radius:50%;background:var(--accent)}.deck-lights i:nth-child(2){background:var(--secondary)}.deck-lights i:nth-child(3){background:color-mix(in srgb,var(--paper) 55%,transparent)}.composition-deck .demo{border:0;border-radius:0;box-shadow:none}
    .cursor-trail-lab{display:grid;grid-template-columns:minmax(0,1.42fr) minmax(220px,.58fr);gap:16px}.trail-stage{position:relative;min-height:450px;overflow:hidden;border:1px solid var(--line);border-radius:24px;background:#070b18;color:#fff}.trail-stage canvas{position:absolute;inset:0;z-index:2;width:100%;height:100%;touch-action:none}.trail-stage>div{position:relative;z-index:1;max-width:590px;padding:clamp(30px,7vw,78px)}.trail-stage h2{font-size:clamp(36px,7vw,78px);line-height:.94}.trail-controls{display:grid;align-content:center;gap:17px}.trail-controls label{display:grid;grid-template-columns:1fr auto;gap:8px;font-weight:800}.trail-controls input{grid-column:1/-1}.cursor-trail-lab[data-trail-layout="garden-orbit"]{grid-template-columns:1fr}.cursor-trail-lab[data-trail-layout="garden-orbit"] .trail-stage{min-height:520px;border-radius:50% 50% 28px 28px;background:radial-gradient(circle at 50% 58%,#31572c,#101d16 48%,#050907 72%)}.cursor-trail-lab[data-trail-layout="garden-orbit"] .trail-stage>div{margin-left:auto;text-align:right}.cursor-trail-lab[data-trail-layout="garden-orbit"] .trail-controls{grid-template-columns:auto minmax(160px,1fr) minmax(160px,1fr) auto;align-items:end;border-radius:999px}.cursor-trail-lab[data-trail-layout="garden-orbit"] .trail-controls h2{grid-column:1/-1}.cursor-trail-lab[data-trail-layout="aurora-band"]{grid-template-columns:minmax(220px,.55fr) minmax(0,1.45fr)}.cursor-trail-lab[data-trail-layout="aurora-band"] .trail-stage{order:2;min-height:360px;border-radius:2px;background:linear-gradient(160deg,#071a2b,#123c49 55%,#39165c)}.cursor-trail-lab[data-trail-layout="aurora-band"] .trail-stage>div{max-width:470px}.cursor-trail-lab[data-trail-layout="aurora-band"] .trail-controls{border-left:8px solid var(--accent)}@media(max-width:740px){.cursor-trail-lab,.cursor-trail-lab[data-trail-layout="garden-orbit"],.cursor-trail-lab[data-trail-layout="aurora-band"]{grid-template-columns:1fr}.trail-stage{min-height:350px}.cursor-trail-lab[data-trail-layout="garden-orbit"] .trail-stage{min-height:410px;border-radius:50%}.cursor-trail-lab[data-trail-layout="garden-orbit"] .trail-controls{order:-1;grid-template-columns:1fr;border-radius:28px}.cursor-trail-lab[data-trail-layout="aurora-band"] .trail-stage{order:0;min-height:320px}}.workflow-spatial{display:grid;gap:16px}.workflow-spatial>header{display:grid;grid-template-columns:1fr minmax(170px,.35fr) minmax(170px,.35fr);gap:18px;align-items:end;padding-bottom:16px;border-bottom:5px solid var(--ink)}.workflow-spatial h2{margin:.2em 0}.workflow-spatial header label{display:grid;grid-template-columns:1fr auto;gap:7px}.workflow-spatial header input{grid-column:1/-1;width:100%}.spatial-grid{display:grid;grid-template-columns:minmax(0,var(--spatial-width)) 20px minmax(180px,1fr);gap:0;align-items:stretch}.spatial-core{min-width:0;transform:scale(var(--spatial-zoom));transform-origin:top left;transition:transform .2s}.spatial-handle{display:grid;min-height:300px;place-items:center;border:0;border-inline:1px dashed var(--accent);background:color-mix(in srgb,var(--accent) 10%,transparent);cursor:col-resize}.spatial-grid>aside{display:grid;align-content:center;gap:14px;padding:22px;background:color-mix(in srgb,var(--secondary) 14%,var(--paper))}.spatial-grid>aside strong{font-size:clamp(24px,4vw,42px)}@media(max-width:900px){.workflow-spatial>header{grid-template-columns:1fr}.spatial-grid{order:-1;grid-template-columns:1fr}.spatial-handle{min-height:44px;cursor:row-resize}.spatial-core{transform:none}}
  </style>
</head>
<body data-aesthetic="minimal" data-composition="control-deck">
  <main class="page">
    <header class="mast"><div><span class="eyebrow">minimal / effet de traînée du pointeur / ADVANCED</span><h1>Effet de trace lumineuse du pointeur du couloir du lac nuageux</h1><p class="intro">Dans le contexte d’un couloir de nuages au bord du lac, réalisez un effet de traînée du pointeur : contenu authentique, contrôles actionnables, retours d’état clairs et mise en page adaptée à toutes les tailles.</p></div><span class="scenario">Promenade du lac de nuages</span></header>
    <div class="composition-deck"><div class="deck-bar"><span>CONTROL DECK · 04</span><span>Effet de traînée du pointeur</span><span class="deck-lights" aria-hidden="true"><i></i><i></i><i></i></span></div><section class="demo" aria-label="Zone interactive de l’effet de traînée lumineuse du pointeur du couloir du lac nuageux"><div id="workflowSpatial" class="workflow-spatial" style="--spatial-width:64%;--spatial-zoom:1"><header><div><span class="eyebrow">Couloir du lac de nuages SPATIAL CANVAS</span><h2>Comptoir d’ajustement de la Galerie du lac nuageux</h2></div><label>Proportion d’intensité visuelle<input id="workflowSpatialWidth" type="range" min="38" max="82" value="64"><output id="workflowSpatialWidthValue">64%</output></label><label>Redimensionnement du contenu<input id="workflowSpatialZoom" type="range" min="80" max="120" value="100"><output id="workflowSpatialZoomValue">100%</output></label></header><div class="spatial-grid"><section id="workflowCore" class="workflow-core spatial-core"><!-- 11DZ_CORE_START:creative-effects-cursor-trail --><div class="cursor-trail-lab" data-trail-layout="aurora-band"><section class="trail-stage"><canvas id="trailCanvas" width="960" height="460" tabindex="0" aria-label="Toile de traînée lumineuse du curseur du couloir du lac nuageux ; déplacez le curseur ou utilisez les touches fléchées pour dessiner une traînée lumineuse" aria-describedby="trailHelp">Le navigateur actuel ne prend pas en charge Canvas.</canvas><div><span>Promenade du lac de nuages</span><h2>La traînée d’aurore traverse la zone d’observation en laissant une rémanence colorée</h2><p id="trailHelp">Déplacez la souris, touchez la toile, ou, une fois au focus, utilisez les touches fléchées pour dessiner.</p></div></section><aside class="trail-controls panel"><span class="eyebrow">CURSOR TRAIL</span><h2>Bande d’observation des aurores polaires</h2><label>Longueur de la traînée lumineuse <input id="trailLength" type="range" min="12" max="90" value="72" data-core-bridge="creative-effects-cursor-trail"><output id="trailLengthValue">72</output></label><label>Taille des points lumineux <input id="trailSize" type="range" min="3" max="18" value="6"><output id="trailSizeValue">6px</output></label><button id="trailClear" class="action" type="button">Effacer la trace lumineuse</button></aside></div><!-- 11DZ_CORE_END --></section><input id="workflowSpatialHandle" class="spatial-handle" type="button" value="↔" aria-label="Faire glisser pour ajuster la largeur de l’aperçu du cas principal"><aside><strong>Couche de base de la galerie du lac nuageux</strong><p>La profondeur dynamique du couloir du lac nuageux et la profondeur de l’affichage du couloir du lac nuageux seront réorganisées en fonction de la taille du canevas.</p><output id="workflowSpatialStatus">Largeur 64%, zoom 100%</output><input id="workflowSpatialApply" class="action primary" type="button" value="Effet d’application"></aside></div></div><p id="status" class="status" role="status" aria-live="polite"></p></section></div>
  </main>
  <script>
    'use strict';
    const statusOutput = document.querySelector('#status');
    const announce = message => { statusOutput.textContent = message; };
    /* 11DZ_CORE_SCRIPT_START:creative-effects-cursor-trail */
const trailCanvas=document.querySelector('#trailCanvas');const trailContext=trailCanvas.getContext('2d');const trailLength=document.querySelector('#trailLength');const trailSize=document.querySelector('#trailSize');const trailReduced=matchMedia('(prefers-reduced-motion: reduce)').matches;const trailHueOffset=220;let trailPoints=[];let trailCursor={x:0,y:0};let trailFrame=0;function sizeTrailCanvas(){const rect=trailCanvas.getBoundingClientRect();const ratio=Math.min(2,devicePixelRatio||1);trailCanvas.width=Math.max(320,Math.round(rect.width*ratio));trailCanvas.height=Math.max(280,Math.round(rect.height*ratio));trailContext.setTransform(ratio,0,0,ratio,0,0);trailCursor={x:rect.width/2,y:rect.height/2};}function addTrailPoint(x,y){trailCursor={x,y};trailPoints.push({x,y,life:1,hue:(trailHueOffset+trailPoints.length*17)%360});while(trailPoints.length>Number(trailLength.value))trailPoints.shift();cancelAnimationFrame(trailFrame);drawTrail();}function drawTrail(){const rect=trailCanvas.getBoundingClientRect();trailContext.clearRect(0,0,rect.width,rect.height);trailPoints.forEach((point,index)=>{if(!trailReduced)point.life-=.018;const ratio=(index+1)/trailPoints.length;trailContext.beginPath();trailContext.fillStyle='hsla('+point.hue+',90%,68%,'+Math.max(0,point.life*ratio)+')';trailContext.shadowBlur=18;trailContext.shadowColor='hsl('+point.hue+' 90% 68%)';trailContext.arc(point.x,point.y,Number(trailSize.value)*ratio,0,Math.PI*2);trailContext.fill();});trailContext.shadowBlur=0;trailPoints=trailPoints.filter(point=>point.life>0);if(trailPoints.length&&!trailReduced)trailFrame=requestAnimationFrame(drawTrail);}function pointerTrail(event){const rect=trailCanvas.getBoundingClientRect();addTrailPoint(event.clientX-rect.left,event.clientY-rect.top);}trailCanvas.addEventListener('pointermove',pointerTrail);trailCanvas.addEventListener('pointerdown',pointerTrail);trailCanvas.addEventListener('keydown',event=>{if(!['ArrowLeft','ArrowRight','ArrowUp','ArrowDown'].includes(event.key))return;event.preventDefault();const rect=trailCanvas.getBoundingClientRect();trailCursor.x=Math.max(0,Math.min(rect.width,trailCursor.x+(event.key==='ArrowRight'?18:event.key==='ArrowLeft'?-18:0)));trailCursor.y=Math.max(0,Math.min(rect.height,trailCursor.y+(event.key==='ArrowDown'?18:event.key==='ArrowUp'?-18:0)));addTrailPoint(trailCursor.x,trailCursor.y);});trailLength.addEventListener('input',()=>{document.querySelector('#trailLengthValue').textContent=trailLength.value;announce('Longueur de la traînée lumineuse '+trailLength.value);});trailSize.addEventListener('input',()=>{document.querySelector('#trailSizeValue').textContent=trailSize.value+'px';announce('Taille des points lumineux '+trailSize.value+' pixel');});document.querySelector('#trailClear').addEventListener('click',()=>{trailPoints=[];cancelAnimationFrame(trailFrame);drawTrail();announce('La trace du pointeur a été effacée');});addEventListener('resize',sizeTrailCanvas,{passive:true});sizeTrailCanvas();
/* 11DZ_CORE_SCRIPT_END */
const workflowBridgeSpec={"name":"creative-effects-cursor-trail","selector":"[data-core-bridge=\"creative-effects-cursor-trail\"]","mode":"range","key":"ArrowRight"};const workflowBridgeCore=document.querySelector('#workflowCore');const workflowBridgeControl=workflowBridgeCore.querySelector(workflowBridgeSpec.selector);if(!workflowBridgeControl)throw new Error('Missing core bridge: '+workflowBridgeSpec.name);const workflowBridgeControlledId=workflowBridgeControl.getAttribute('aria-controls');const workflowBridgeControlled=workflowBridgeControlledId?document.getElementById(workflowBridgeControlledId):null;workflowBridgeCore.dataset.workflowBridge=workflowBridgeSpec.name;workflowBridgeCore.dataset.workflowVersion='0';function workflowBridgeSerialize(){const visualNode=workflowBridgeCore.firstElementChild||workflowBridgeCore;const visual=getComputedStyle(visualNode);const outputs=[...workflowBridgeCore.querySelectorAll('output,[role="status"],[aria-live],meter,progress')].map(node=>node.textContent.trim()+'|'+node.getAttribute('aria-valuenow')+'|'+node.getAttribute('value'));const canvas=[...workflowBridgeCore.querySelectorAll('canvas')].map(node=>{try{return node.toDataURL().slice(-160);}catch{return 'canvas-unavailable';}});return JSON.stringify({html:workflowBridgeCore.innerHTML,status:statusOutput.textContent,outputs,canvas,visual:[visual.display,visual.visibility,visual.opacity,visual.transform,visual.filter,visual.backgroundColor,visual.width,visual.height],scroll:workflowBridgeSpec.mode==='scroll'?workflowBridgeControl.scrollTop:null});}let workflowBridgeLastEffect=workflowBridgeSerialize();function workflowBridgeSummary(){const label=(workflowBridgeControl.getAttribute('aria-label')||workflowBridgeControl.textContent||workflowBridgeControl.value||workflowBridgeSpec.name).trim().replace(/\s+/g,' ').slice(0,72);return label+' · Version de base '+workflowBridgeCore.dataset.workflowVersion;}function workflowBridgeCommit(){const effect=workflowBridgeSerialize();if(effect===workflowBridgeLastEffect)return {changed:false,summary:workflowBridgeSummary()};workflowBridgeLastEffect=effect;workflowBridgeCore.dataset.workflowVersion=String(Number(workflowBridgeCore.dataset.workflowVersion||0)+1);return {changed:true,summary:workflowBridgeSummary()};}function workflowBridgeScheduleCommit(){queueMicrotask(workflowBridgeCommit);setTimeout(workflowBridgeCommit,0);}workflowBridgeControl.addEventListener("input",workflowBridgeScheduleCommit);workflowBridgeControl.addEventListener('change',workflowBridgeScheduleCommit);const workflowBridgeStateTargets=new Set(workflowBridgeCore.querySelectorAll('dialog'));if(workflowBridgeControlled&&workflowBridgeCore.contains(workflowBridgeControlled))workflowBridgeStateTargets.add(workflowBridgeControlled);workflowBridgeStateTargets.forEach(target=>['close','cancel','toggle'].forEach(eventName=>target.addEventListener(eventName,workflowBridgeScheduleCommit)));function workflowBridgeActivate(){workflowBridgeControl.focus();const step=Number(workflowBridgeControl.step)||1;const min=workflowBridgeControl.min===''?-Infinity:Number(workflowBridgeControl.min);const max=workflowBridgeControl.max===''?Infinity:Number(workflowBridgeControl.max);let next=Math.min(max,Math.max(min,(Number(workflowBridgeControl.value)||0)+step));if(next===Number(workflowBridgeControl.value))next=Math.max(min,Number(workflowBridgeControl.value)-step);workflowBridgeControl.value=String(next);workflowBridgeControl.dispatchEvent(new Event('input',{bubbles:true}));workflowBridgeControl.dispatchEvent(new Event('change',{bubbles:true}));const result=workflowBridgeCommit();setTimeout(workflowBridgeCommit,0);return result;}function workflowBridgeReset(){workflowBridgeCore.dataset.workflowVersion='0';workflowBridgeLastEffect=workflowBridgeSerialize();}
const workflowSpatial=document.querySelector('#workflowSpatial');const workflowSpatialCore=document.querySelector('#workflowCore');const workflowSpatialWidth=document.querySelector('#workflowSpatialWidth');const workflowSpatialZoom=document.querySelector('#workflowSpatialZoom');const workflowSpatialHandle=document.querySelector('#workflowSpatialHandle');const workflowSpatialState={width:64,zoom:1,dragging:false};function workflowSpatialDrive(){workflowSpatial.style.setProperty('--spatial-width',workflowSpatialState.width+'%');workflowSpatial.style.setProperty('--spatial-zoom',String(workflowSpatialState.zoom));workflowSpatialWidth.value=String(workflowSpatialState.width);workflowSpatialZoom.value=String(Math.round(workflowSpatialState.zoom*100));document.querySelector('#workflowSpatialWidthValue').textContent=workflowSpatialState.width+'%';document.querySelector('#workflowSpatialZoomValue').textContent=Math.round(workflowSpatialState.zoom*100)+'%';document.querySelector('#workflowSpatialStatus').textContent='largeur '+workflowSpatialState.width+'%,mise à l’échelle '+Math.round(workflowSpatialState.zoom*100)+'%';announce('Le canevas de la galerie de la vallée nuageuse a été réorganisé');}workflowSpatialWidth.addEventListener('input',()=>{workflowSpatialState.width=Number(workflowSpatialWidth.value);workflowSpatialDrive();});workflowSpatialZoom.addEventListener('input',()=>{workflowSpatialState.zoom=Number(workflowSpatialZoom.value)/100;workflowSpatialDrive();});workflowSpatialHandle.addEventListener('pointerdown',event=>{workflowSpatialState.dragging=true;workflowSpatialHandle.setPointerCapture(event.pointerId);});workflowSpatialHandle.addEventListener('pointermove',event=>{if(!workflowSpatialState.dragging)return;const rect=workflowSpatial.getBoundingClientRect();workflowSpatialState.width=Math.max(38,Math.min(82,Math.round((event.clientX-rect.left)/rect.width*100)));workflowSpatialDrive();});workflowSpatialHandle.addEventListener('pointerup',event=>{workflowSpatialState.dragging=false;workflowSpatialHandle.releasePointerCapture(event.pointerId);});workflowSpatialHandle.addEventListener('wheel',event=>{event.preventDefault();workflowSpatialState.zoom=Math.max(.8,Math.min(1.2,workflowSpatialState.zoom+(event.deltaY<0?.05:-.05)));workflowSpatialDrive();},{passive:false});workflowSpatialHandle.addEventListener('keydown',event=>{if(!['ArrowLeft','ArrowRight'].includes(event.key))return;event.preventDefault();workflowSpatialState.width=Math.max(38,Math.min(82,workflowSpatialState.width+(event.key==='ArrowRight'?2:-2)));workflowSpatialDrive();});document.querySelector('#workflowSpatialApply').addEventListener('click',()=>{const bridge=workflowBridgeActivate();document.querySelector('#workflowSpatialStatus').textContent='Effet appliqué · largeur '+workflowSpatialState.width+'%,mise à l’échelle '+Math.round(workflowSpatialState.zoom*100)+'% · '+bridge.summary;announce(document.querySelector('#workflowSpatialStatus').textContent);});workflowSpatialDrive();
workflowBridgeReset();
  </script>
</body>
</html>
Commentaires sur la pageVous avez découvert un problème ou avez une suggestion d’amélioration ?
Les fonctions de retour nécessitent l’utilisation de la version en ligne

Veuillez activer JavaScript dans la version en ligne avant de soumettre ; les fonctionnalités locales de l’outil ou du cas ne sont pas affectées.

Aller vers la version en ligne pour envoyer des commentaires