I am trying to get a backwards typing effect with my code. So the <P>
will say "Coming Soon" then type backwards. Then type forwards into "SeaDogs.com.eu.as"
This is what I have so far, for some reason it type coming soon backwards twice??? Which is my first hurtle I'm trying to overcome. And trying to delay it so it shows the word "Coming soon" for a few seconds.
var str = 'Coming Soon';
var remove = false;
var i = str.length;
var isTag;
var text;
(function type() {
if (!remove) {
text = str.slice(0, --i);
if (text === str) return;
}
if (!isTag) {
document.getElementById("demo").innerHTML = text;
}
setTimeout(type, 520);
}());
<p id="demo"></p>
CodePudding user response:
It's much cleaner to code the logic directly with async/await rather than to fiddle with timeouts:
function delay(time) {
return new Promise(r =>
setTimeout(r, time))
}
async function typeAnimation(div, rtl, text, time) {
for (let i = 1; i <= text.length; i ) {
div.innerText = text.slice(0, rtl ? -i : i)
await delay(time)
}
}
async function main() {
let div = document.querySelector('h1')
await typeAnimation(div, true, 'Coming soon...', 100)
await typeAnimation(div, false, 'and here it comes!', 100)
}
main()
<h1></h1>
CodePudding user response:
I would create two functions with a promise
const demo = document.querySelector('#demo')
const initial = "Coming Soon"
const later = "SeaDogs.com.eu.as"
remove(initial).then(() => add(later))
function remove(text) {
let i = text.length
return new Promise(r => {
removeCharacter()
function removeCharacter() {
if (i < 0) {
r()
return
}
const copy = text.slice(0, i)
demo.textContent = copy
setTimeout(removeCharacter, 100)
i -= 1
}
})
}
function add(text) {
let i = 0
return new Promise(r => {
removeCharacter()
function removeCharacter() {
if (i > text.length) {
r()
return
}
const copy = text.slice(0, i)
demo.textContent = copy
setTimeout(removeCharacter, 100)
i = 1
}
})
}
<p id="demo"></p>
CodePudding user response:
Your exit clause is incorrect - you check if substring of str == str - which it never will.
You get it twice because of the way .slice
works with a negative index
.slice(0, 8)
-> start to 8th character.slice(0, -2)
-> start to 2 characters from the end
You can change the exit clause from if (text === str) return
to
if (text === "") return;
or
if (i === 0) return;
Depending on when you want it to end - as your exit clause is before the output, this will leave the last character, so instead:
if (i<0) return;
var str = 'Coming Soon';
var remove = false;
var i = str.length;
var isTag;
var text;
(function type() {
if (!remove) {
text = str.slice(0, --i);
//console.log(i, text)
if (i < 0) return;
}
if (!isTag) {
document.getElementById("demo").innerHTML = text;
}
setTimeout(type, 150);
}());
<p id="demo"></p>
However, I expect there's some mix up between remove
and !remove
as you have not-remove (ie add) with --i. So when adding, you do need to check text==str
CodePudding user response:
Here is a modified version of your code that should achieve the desired effect:
var str = 'Coming Soon';
var delay = 5000; // delay in milliseconds before typing backwards
var remove = false;
var i = str.length;
var isTag;
var text;
(function type() {
if (!remove) {
text = str.slice(0, --i);
if (text === str) {
// wait for the delay before typing backwards
setTimeout(function() {
remove = true;
i = 0;
}, delay);
return;
}
} else {
text = str.slice(0, i);
if (text === str) {
// typing forwards is done, append the rest of the text
document.getElementById("demo").innerHTML = ".com.eu.as";
return;
}
}
if (!isTag) {
document.getElementById("demo").innerHTML = text;
}
setTimeout(type, 520);
}());
<p id="demo"></p>