I'm trying to make an effect of replacing one string with another, but without completely erasing the contents of the first one. As if it were a special effect, each letter of a string is transformed into another word. At first I'm trying to do it like a typewriter, but later I want to do it randomly. However, I can't get it to work, it looks like it's a bug.
let title1 = "Your sales place";
let title2 = "Software Hub";
var k = 0;
var speed = 150;
function typeWriter() {
if (k < title1.length) {
if (k >= title2.length) {
title2 += title1.charAt(k);
}
title2 = title2.replace(title2.charAt(k), title1.charAt(k));
document.getElementById("demo").innerHTML = title2;
k += 1;
setTimeout(typeWriter, speed);
}
}
typeWriter();
<div id="demo"></div>
output:
YO AESRL SUPLACE
replace
replaces the first occurrence of the character, which is not necessarily the one at index k
.
Instead of mutating title2
, I would recommend to simply do
….innerHTML = title2.slice(0, k) + title1.slice(k);
This is the correct code for what i'm waiting. Sorry for the mistake.
import { onMount } from "svelte";
let title1 = "Your sales place";
let title2 = "Software Hub";
var part = "";
var k = 0;
var speed = 150;
onMount(() => {
typeWriter();
});
function sliceReplace(origin, final, k) {
part = part.slice(0,k);
part += final.charAt(k) + origin.slice(k+1);
return part;
}
function typeWriter() {
if (k < title1.length) {
if (k >= title2.length) {
title2 += title1.charAt(k);
}
document.getElementById("demo").innerHTML = sliceReplace(title2, title1, k);
k += 1;
setTimeout(typeWriter, speed);
}
}
This is your solution with the least modification.
The problem with your code is using String.prototype.charAt
to find and replace your character, and it finds the first occurrence of a character. So when a character is repeated in your string, charAt will find and replace the first occurrence, not the other ones.
So you can define a function like replaceAt
below, to replace a character at a specific position, and use that.
let title1 = "Your sales place";
let title2 = "Software Hub";
String.prototype.replaceAt = function(index, replacement) {
return this.substr(0, index) + replacement + this.substr(index + replacement.length);
}
var k = 0;
var speed = 150;
function typeWriter() {
if (k < title1.length) {
if (k >= title2.length) {
title2 += title1[k];
} else {
title2 = title2.replaceAt(k, title1[k]);
}
document.getElementById("demo").innerHTML = title2;
k += 1;
setTimeout(typeWriter, speed);
}
}
typeWriter();
<div id="demo"></div>
However, I would recommend that you do not use global variables as counters when recursively calling a function, instead, pass that variable to your function:
let title1 = "Your sales place";
let title2 = "Software Hub";
var speed = 150;
String.prototype.replaceAt = function(index, replacement) {
return this.substr(0, index) + replacement + this.substr(index + replacement.length);
}
function typeWriter(k) {
if (k < title1.length) {
let title = document.getElementById("demo").innerHTML
if (k >= title.length) {
title += title1[k];
} else {
title = title.replaceAt(k, title1[k]);
}
document.getElementById("demo").innerHTML = title;
setTimeout(() => {typeWriter(k+1)}, speed);
}
}
document.getElementById("demo").innerHTML = title2;
setTimeout(() => {typeWriter(0);}, speed)
<div id="demo"></div>