efectos visuales creativos

Efecto de estela de cursor en el corredor del lago de nubes

En el contexto del corredor del lago de nubes, completa un efecto de estela del puntero: incluye contenido real, controles interactivos, retroalimentación de estado clara y diseño adaptable a distintos tamaños.

efectos visuales creativosEfecto de estela del punteroHTMLCanvasJavaScript
Tras activar JavaScript, puedes editar, ejecutar y guardar este ejemplo. El código fuente fijado es el siguiente:
<!doctype html>
<html lang="es" dir="ltr">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Efecto de estela de cursor en el corredor del lago de nubes</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 / efecto de estela del puntero / ADVANCED</span><h1>Efecto de estela de cursor en el corredor del lago de nubes</h1><p class="intro">En el contexto del corredor del lago de nubes, completa un efecto de estela del puntero: incluye contenido real, controles interactivos, retroalimentación de estado clara y diseño adaptable a distintos tamaños.</p></div><span class="scenario">Pasarela del lago de nubes</span></header>
    <div class="composition-deck"><div class="deck-bar"><span>CONTROL DECK · 04</span><span>Efecto de estela del puntero</span><span class="deck-lights" aria-hidden="true"><i></i><i></i><i></i></span></div><section class="demo" aria-label="Área interactiva del efecto de estela de luz del puntero en el pasillo del lago de nubes"><div id="workflowSpatial" class="workflow-spatial" style="--spatial-width:64%;--spatial-zoom:1"><header><div><span class="eyebrow">SPATIAL CANVAS del corredor del lago de nubes</span><h2>Puesto de ajuste del corredor del lago de nubes</h2></div><label>Proporción de intensidad visual<input id="workflowSpatialWidth" type="range" min="38" max="82" value="64"><output id="workflowSpatialWidthValue">64%</output></label><label>Escala de contenido<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="Lienzo de trazos de luz del puntero en el corredor del lago de nubes; mueve el puntero o usa las teclas de dirección para dibujar trazos de luz" aria-describedby="trailHelp">El navegador actual no admite Canvas.</canvas><div><span>Pasarela del lago de nubes</span><h2>Una estela aurora cruza la franja de observación y deja un resplandor multicolor</h2><p id="trailHelp">Mueve el ratón, toca el lienzo o, cuando esté enfocado, usa las teclas de dirección para dibujar.</p></div></section><aside class="trail-controls panel"><span class="eyebrow">CURSOR TRAIL</span><h2>Zona de observación de auroras</h2><label>Longitud de la estela luminosa <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>Tamaño del punto de luz <input id="trailSize" type="range" min="3" max="18" value="6"><output id="trailSizeValue">6px</output></label><button id="trailClear" class="action" type="button">Borrar estela luminosa</button></aside></div><!-- 11DZ_CORE_END --></section><input id="workflowSpatialHandle" class="spatial-handle" type="button" value="↔" aria-label="Arrastra para ajustar el ancho de la vista previa del ejemplo principal"><aside><strong>Capas básicas del corredor del lago de nubes</strong><p>La profundidad dinámica del paseo del lago de nubes y la capa de exhibición del paseo del lago de nubes se reordenarán según el tamaño del lienzo.</p><output id="workflowSpatialStatus">Ancho 64%, escala 100%</output><input id="workflowSpatialApply" class="action primary" type="button" value="Efecto de aplicación"></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('Longitud de la estela luminosa '+trailLength.value);});trailSize.addEventListener('input',()=>{document.querySelector('#trailSizeValue').textContent=trailSize.value+'px';announce('Tamaño del punto de luz '+trailSize.value+' píxel');});document.querySelector('#trailClear').addEventListener('click',()=>{trailPoints=[];cancelAnimationFrame(trailFrame);drawTrail();announce('La traza del puntero se ha vaciado');});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+' · versión principal '+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='Ancho '+workflowSpatialState.width+'%, zoom '+Math.round(workflowSpatialState.zoom*100)+'%';announce('El lienzo del paseo del lago de nubes se ha reordenado');}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='Efecto aplicado · ancho '+workflowSpatialState.width+'%, zoom '+Math.round(workflowSpatialState.zoom*100)+'% · '+bridge.summary;announce(document.querySelector('#workflowSpatialStatus').textContent);});workflowSpatialDrive();
workflowBridgeReset();
  </script>
</body>
</html>
Comentarios de la página¿Has encontrado un problema o tienes sugerencias de mejora?
Las funciones de retroalimentación deben usarse en la versión en línea

Envía tras activar JavaScript en la versión en línea; las funciones locales de la herramienta o del ejemplo no se verán afectadas.

Ir a la versión en línea para dar feedback