繁体   English   中英

如何在 div 中淡入文本,同时在 JavaScript 中解扰文本

[英]How do I fade in text in a div, while simultaneously descrambling the text in JavaScript

在动画转换期间执行淡入效果时,如何对文本执行动画转换?

 // —————————————————————————————————————————————————— // TextScramble // —————————————————————————————————————————————————— class TextScramble { constructor(elm, numWords) { this.el = el this.numWords = numWords; this.chars = '!<>-_\\\\/[]{}—=+*^?#1234567890________' this.update = this.update.bind(this) } setText(newText) { const oldText = this.el.innerText const length = Math.max(oldText.length, newText.length) const promise = new Promise((resolve) => this.resolve = resolve) this.queue = [] for (let i = 0; i < length; i++) { const from = oldText[i] || '' const to = newText[i] || '' const start = Math.floor(Math.random() * 40) const end = start + Math.floor(Math.random() * 40) this.queue.push({ from, to, start, end }) } cancelAnimationFrame(this.frameRequest) this.frame = 0 this.update() return promise } update() { let output = '' let complete = 0 for (let i = 0, n = this.queue.length; i < n; i++) { let { from, to, start, end, char } = this.queue[i] if (this.frame >= end) { complete++ output += to } else if (this.frame >= start) { if (!char || Math.random() < 0.28) { char = this.randomChar() this.queue[i].char = char } output += `<span class="dud">${char}</span>` } else { output += from } } this.el.innerHTML = output if (complete === this.queue.length) { this.resolve() } else { this.frameRequest = requestAnimationFrame(this.update) this.frame++ } } randomChar() { return this.chars[Math.floor(Math.random() * this.chars.length)] } } // —————————————————————————————————————————————————— // Example // —————————————————————————————————————————————————— const phrases = { 'Coding' : 'none', 'With' : 'none', 'Muhammad': 'none', 'Coding With Muhammad' : 'fade' } let phraseValues = Object.keys(phrases); const el = document.querySelector('.text') const fx = new TextScramble(el, phraseValues.length) let counter = 0 let animation = phraseValues[0]; let animate = () => { return function(callback) { document.querySelector(".text").animate([ // keyframes { opacity: '0' }, { opacity: '1' } ], { // timing options duration: 3500, iterations: 1 }); callback(); } } const next = () => { fx.setText(phraseValues[counter]).then(() => { if (counter <= phraseValues.length) setTimeout(next, 800) else { animation = phrases[phraseValues[counter]] setTimeout(animate(next), 800) } }) counter = (counter + 1) % phraseValues.length } next()
 html, body { font-family: 'Roboto Mono', monospace; background: #212121; height: 100%; } .container { height: 100%; width: 100%; justify-content: center; align-items: center; display: flex; } .text { font-weight: 100; font-size: 28px; color: #FAFAFA; } .dud { color: #757575; } .fadeIn { animation: fade 10s; }
 <div class="container"> <div class="text"></div> </div>

我非常接近:

我将回调调用语句移到其下方的闭包返回语句上方。 我保留了动画关键帧。

最后我修改了要动画的短语中的setTimeout,如下:

我在 setTimeout 中放置了 next 和 animate 作为回调,以级联顺序回调。

我使用箭头表示法使用匿名函数定义。

在 animate(我编写的函数)上,我传入 fx.update 函数定义作为回调,并调用返回 animate 的闭包函数作为高阶函数,就像这样。

查看结果!

 // —————————————————————————————————————————————————— // TextScramble // —————————————————————————————————————————————————— class TextScramble { constructor(elm, numWords) { this.el = el this.numWords = numWords; this.chars = '!<>-_\\\\/[]{}—=+*^?#1234567890________' this.update = this.update.bind(this) } setText(newText) { const oldText = this.el.innerText const length = Math.max(oldText.length, newText.length) const promise = new Promise((resolve) => this.resolve = resolve) this.queue = [] for (let i = 0; i < length; i++) { const from = oldText[i] || '' const to = newText[i] || '' const start = Math.floor(Math.random() * 40) const end = start + Math.floor(Math.random() * 40) this.queue.push({ from, to, start, end }) } cancelAnimationFrame(this.frameRequest) this.frame = 0 this.update() return promise } update = () => { let output = '' let complete = 0 for (let i = 0, n = this.queue.length; i < n; i++) { let { from, to, start, end, char } = this.queue[i] if (this.frame >= end) { complete++ output += to } else if (this.frame >= start) { if (!char || Math.random() < 0.28) { char = this.randomChar() this.queue[i].char = char } output += `<span class="span">${char}</span>` } else { output += from } } this.el.innerHTML = output if (complete === this.queue.length) { this.resolve() } else { this.frameRequest = requestAnimationFrame(this.update) this.frame++ } } randomChar() { return this.chars[Math.floor(Math.random() * this.chars.length)] } } // —————————————————————————————————————————————————— // Example // —————————————————————————————————————————————————— const phrases = { 'Coding' : 'none', 'With' : 'none', 'Muhammad': 'none', 'Coding With Muhammad' : 'fade' } let phraseValues = Object.keys(phrases); const el = document.querySelector('.text') const fx = new TextScramble(el, phraseValues.length) let counter = 0 let animation = phraseValues[0]; let animate = (callback) => { callback(); return function() { document.querySelector(".text").animate([ // keyframes { opacity: '0' }, { opacity: '1' } ], { // timing options duration: 3500 }); } } const next = () => { fx.setText(phraseValues[counter]).then(() => { if (counter < phraseValues.length-1) setTimeout(next, 800) else { setTimeout(() => {next, animate(next, fx.update)()}, 800) } }) counter = (counter + 1) % phraseValues.length } next()
 html, body { font-family: 'Roboto Mono', monospace; background: #212121; height: 100%; } .container { height: 100%; width: 100%; justify-content: center; align-items: center; display: flex; } .text { font-weight: 100; font-size: 28px; color: #FAFAFA; } .dud { color: #757575; }
 <div class="container"> <div class="text"></div> </div>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM