Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

213
Visualizações
Creando un rastro de cursor estilo polvo de disney

Estoy tratando de hacer un cursor que deje un rastro de polvo mágico como en esa introducción a cualquier película de Disney: ejemplo . Así que la forma en que lo veo es que está dividido en dos partes. 1. el rastro y 2. rastro similar que cae y se desvanece. Hasta ahora he hecho que el rastro básico funcione bastante bien, el siguiente código es para el rastro descendente y esencialmente una copia del mismo con una animación css.

El problema que tengo es que tiembla mucho. Supongo que la animación css no es excelente para el rendimiento y está causando que esto realmente se mueva en mi página. Acabo de leer sobre requestAnimationFrame pero soy nuevo en esto, así que no estoy seguro de cómo implementarlo. ¿Cómo podría usar requestAnimationFrame en lugar de css aquí?

También creo que crear la animación personalizada en js permitiría que también haya un desplazamiento aleatorio en la animación de las partículas que caen... mucho más como en el video.

 window.addEventListener('mousemove', function (e) { //trail [1, .9, .8, .5, .25, .6, .4, .3, .2].forEach(function (i) { var j = (1 - i) * 50; var elem = document.createElement('div'); var size = Math.ceil(Math.random() * 10 * i) + 'px'; elem.style.position = 'fixed'; elem.style.zIndex = 6; elem.style.top = e.pageY - window.scrollY + Math.round(Math.random() * j - j / 2) + 'px'; elem.style.left = e.pageX + Math.round(Math.random() * j - j / 2) + 'px'; elem.style.width = size; elem.style.opacity = "0.5"; elem.style.height = size; elem.style.background = 'hsla(' + Math.round(Math.random() * 160) + ', ' + '60%, ' + '90%, ' + i + ')'; elem.style.borderRadius = size; elem.style.pointerEvents = 'none'; document.body.appendChild(elem); window.setTimeout(function () { document.body.removeChild(elem); }, Math.round(Math.random() * i * 1000)); }); // falling trail [1, .9, .8, .5, .25, .6, .3, .2].forEach(function (i) { var j = (1 - i) * 50; var elem = document.createElement('div'); var size = Math.ceil(Math.random() * 10 * i) + 'px'; elem.style.position = 'fixed'; elem.style.zIndex = 6; elem.style.top = e.pageY - window.scrollY + Math.round(Math.random() * j - j / 2) + 'px'; elem.style.left = e.pageX + Math.round(Math.random() * j - j / 2) + 'px'; elem.style.width = size; elem.style.opacity = "0.5"; elem.style.height = size; elem.style.animation = "fallingsparkles 1s"; elem.style.background = 'hsla(' + Math.round(Math.random() * 160) + ', ' + '60%, ' + '90%, ' + i + ')'; elem.style.borderRadius = size; elem.style.pointerEvents = 'none'; document.body.appendChild(elem); window.setTimeout(function () { document.body.removeChild(elem); }, Math.round(Math.random() * i * 1000)); }); }, false);
 body { width:100%; height:100%; background-color: #000; } @keyframes fallingsparkles { from { transform: translateY(0); } to { transform: translateY(50px); } }
 <body></body>

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

Principalmente estoy publicando esto para que otros lo usen, donde refactoricé un poco el código. Nada ha cambiado, pero es más fácil de seguir. Seguiré con una respuesta real.

 let trailArr = [1, .9, .8, .5, .25, .6, .4, .3, .2]; function trailAnimation(e, i, callbackFn) { var elem = document.createElement('div'); elem = styleSparkle(elem, e, i); if (typeof callbackFn == 'function') { elem = callbackFn(elem); } elem.classList.add("sparkle"); document.body.appendChild(elem); window.setTimeout(function () { document.body.removeChild(elem); }, Math.round(Math.random() * i * 1000)); } function styleSparkle(elem, e, i) { let j = (1 - i) * 50; let size = Math.ceil(Math.random() * 10 * i) + 'px'; elem.style.top = e.pageY - window.scrollY + Math.round(Math.random() * j - j / 2) + 'px'; elem.style.left = e.pageX + Math.round(Math.random() * j - j / 2) + 'px'; elem.style.width = size; elem.style.height = size; elem.style.borderRadius = size; elem.style.background = 'hsla(' + Math.round(Math.random() * 160) + ', ' + '60%, ' + '90%, ' + i + ')'; return elem; } window.addEventListener('mousemove', function (e) { trailArr.forEach((i) => {trailAnimation(e, i)}); trailArr.forEach((i) => {trailAnimation(e, i, (elem) => { elem.style.animation = "fallingsparkles 1s"; return elem; })}); }, false);
 body { width:100%; height:100%; background-color: #000; } .sparkle { position: fixed; z-index: 6; opacity: 0.5; pointer-events: none; } @keyframes fallingsparkles { from { transform: translateY(0); } to { transform: translateY(50px); } }
 <body></body>

over 4 years ago · Santiago Trujillo Relatório

0

Qué pequeña animación genial. Creo que será molesto a la larga, pero aún así: genial.

Lo que no me gusta de esta solución es que tuve que hacer un bucle recursivo continuo, que continúa incluso si no hay elementos para animar. Probablemente haya formas de evitar eso, pero sería demasiado complejo mostrar cómo implementar requestAnimationFrame . Como puede ver, no es tan difícil de usar requestAnimationFrame. Simplemente llame al mismo método en el que hace los cálculos.

Además de agregar cada elemento al cuerpo, también agregué el elemento en sparkleArr con algunas propiedades más a través addAnimationProperties . Finalmente agregué un método completamente nuevo, moveSparkles , para calcular el movimiento y eliminar los elementos. calculateInterpolation calcula el porcentaje de cuánto tiempo debe moverse el elemento, en función de cuándo se creó el elemento, cuándo desaparecerá y la hora actual.

Creo que el código se explica por sí mismo. Tuve que hacer un comentario en un lugar, donde no creo que sea posible explicar el código a través de variables o nombres de métodos.

 let trailArr = [1, .9, .8, .5, .25, .6, .4, .3, .2]; var sparklesArr = []; function trailAnimation(e, i, maxYTranslation) { let elem = document.createElement('div'); elem = styleSparkle(elem, e, i); elem.classList.add("sparkle"); document.body.appendChild(elem); elem = addAnimationProperties(elem, i, maxYTranslation); sparklesArr.push(elem); } function styleSparkle(elem, e, i) { let j = (1 - i) * 50; let size = Math.ceil(Math.random() * 10 * i) + 'px'; elem.style.top = e.pageY - window.scrollY + Math.round(Math.random() * j - j / 2) + 'px'; elem.style.left = e.pageX + Math.round(Math.random() * j - j / 2) + 'px'; elem.style.width = size; elem.style.height = size; elem.style.borderRadius = size; elem.style.background = 'hsla(' + Math.round(Math.random() * 160) + ', ' + '60%, ' + '90%, ' + i + ')'; return elem; } function addAnimationProperties(elem, i, maxYTranslation) { const ANIMATION_SPEED = 1100; let lifeExpectancy = Math.round(Math.random() * i * ANIMATION_SPEED); elem.maxYTranslation = maxYTranslation; elem.animationSpeed = ANIMATION_SPEED; elem.created = Date.now(); elem.diesAt = elem.created + lifeExpectancy; return elem; } function moveSparkles() { let remove = false; let moveIndex = 0; let sparkle; for (let i = 0; i < sparklesArr.length; i++) { sparkle = sparklesArr[i]; remove = sparkle.diesAt <= Date.now(); if (remove) { document.body.removeChild(sparkle); } else { if (sparkle.maxYTranslation) { let interpolation = calculateInterpolation(sparkle); sparkle.style.transform = `translateY(${interpolation}px)`; } sparklesArr[moveIndex++] = sparkle; // faster than array.splice() } } sparklesArr.length = moveIndex; requestAnimationFrame(moveSparkles); } function calculateInterpolation(sparkle) { let currentMillis = Date.now(); let lifeProgress = (currentMillis - sparkle.created) / sparkle.animationSpeed; let interpolation = sparkle.maxYTranslation * lifeProgress; return interpolation; } window.addEventListener('mousemove', function (e) { trailArr.forEach((i) => {trailAnimation(e, i)}); let maxYTranslation = '80'; trailArr.forEach((i) => {trailAnimation(e, i, maxYTranslation)}); }, false); moveSparkles(); // starts the recursive loop
 body { width:100%; height:100%; background-color: #000; } .sparkle { position: fixed; z-index: 6; opacity: 0.5; pointer-events: none; }
 <body></body>

over 4 years ago · Santiago Trujillo Relatório

0

Hice otra versión que es bastante divertida.

 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> body { width: 100%; height: 100%; background-color: #000; } .star-five { background: transparent; margin: 50px 0; position: relative; display: block; color: #ffffff; width: 0px; height: 0px; border-right: 100px solid transparent; border-bottom: 70px solid #ffffff; border-left: 100px solid transparent; /* transform: rotate(35deg) scale(0.1) translate(-1450px, -250px); */ } .star-five:before { border-bottom: 80px solid #ffffff; border-left: 30px solid transparent; border-right: 30px solid transparent; background-color: transparent; position: absolute; height: 0; width: 0; top: -45px; left: -65px; display: block; content: ''; transform: rotate(-35deg); } .star-five:after { background-color: transparent; position: absolute; display: block; color: #ffffff; top: 3px; left: -105px; width: 0px; height: 0px; border-right: 100px solid transparent; border-bottom: 70px solid #ffffff; border-left: 100px solid transparent; transform: rotate(-70deg); content: ''; } </style> </head> <body> <script> window.addEventListener('mousemove', function (e) { //trail [.7, .9, .8, .5, .25, .6, .4, .3, .2].forEach(function (i) { var j = (1 - i) * 50; var elem = document.createElement('div'); var size = Math.ceil(Math.random() * 10 * i) + 'px'; //ramdom number between 0 and 1 var precision = 50; // 2 decimals var randomnum = Math.floor(Math.random() * (10 * precision - 1 * precision) + 1 * precision) / (1*precision); var rOpacity = randomnum/10; var rSize = randomnum/120; elem.style.position = 'fixed'; elem.classList.add('star-five') elem.style.zIndex = 6; elem.style.transform = `rotate(35deg) scale(${rSize})` //elem.style.transform = `rotate(35deg) scale(${rSize}) translate(-1450px, -250px)` elem.style.top = e.pageY - window.scrollY + Math.round(Math.random() * j - j / 2) - 100 + 'px'; elem.style.left = e.pageX + Math.round(Math.random() * j - j / 2) - 100 + 'px'; //elem.style.width = size; //console.log(rSize); elem.style.opacity = rOpacity; //elem.style.height = size; // elem.style.background = 'hsla(' + // Math.round(Math.random() * 160) + ', ' + // '60%, ' + // '100%, ' + // i + ')'; //elem.style.borderRadius = size; elem.style.pointerEvents = 'none'; document.body.appendChild(elem); window.setTimeout(function () { document.body.removeChild(elem); }, Math.round(Math.random() * i * 1000)); }); //// }, false); </script> </body> </html>

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda