Can I animate text change using plain old Vanilla or CSS?

Can I animate text change using plain old Vanilla or CSS?
0.0 0

#1

We all know we can animate things upon changing some characteristics either using Plain CSS or the DOM, Like changing background gives us smooth .5s transition if we wanted to, But can we apply it to texts as well like if i change element.textContent = “Changed!” can i transition it smoothly rather than flicking or something?


#2

I’m going to just brainstorm because a quick look on google didn’t reveal anything spectacular.

I’m assuming you mean that you have an element with text like:

<div id="textbox">Some Text</div>

Upon changing the text via Javascript you want it to be animated and gradual (in some fashion) rather than instant. Tell me if I’m wrong.

Thought 1: Use CSS (and a little JS to changed CSS classes)

  • use transition for opacity
  • change opacity to 0
  • when opacity is 0, change the text
  • bring the opacity back up to 1
  • this might be weird in a situation like this where you change the text in the span because it will shift things around a lot and might look weird:
<div>
Here is some text <span id="change-this">and even MORE text!</span> 
and then some more, in case you wanted more.
</div>
  • If I change or just take the text away in the “change-this” span, the later half of the text will shift somewhat.

Thought 2: Use JS

  • delete one letter at a time of the old text (like pressing backspace) slowly but not too slow
  • then add one letter at a time of the new text slowly (like it’s being typed in)… again slowly but not too slow.
  • (my thought on this is that it might be nice for a small amount of text, maybe not nice for like a paragraph. Although adjusting the speed based on length may be good)

My guess is there is probably some JS library for doing some cool stuff. Let’s see if someone has other suggestions.


#3

I don’t know this is the right one you looking for the animation.
But this is what I have done with my Wikipedia challenged.
Only the selector is used by Jquery but the effects are in CSS.
https://codepen.io/NaphongManyart/full/PezYvQ/


#4

I was thinking about that Though1 of yours as well, but i really feel it isnt the right thing to do it… But I tried it and yeah its cool but the transition is very complex to control, well not so but, compared to css transition property, it is!

Thought 2 was certainly not clear for me! But thanks and i agree! Lets wait for more replies


#5

@naphong Yeah! That topic text? is that opacity! Yeah I think its a good idea if youre switching the text from 0 to 1 and 1 to 0… my case is that onClick, the text will change alternately! and upon shifting, i want a smooth, not so smooth but fairly smooth transition!

Edit*** i mean shifting betweeen two words or sets of texts when i said alternately


#6

Something like this? @lagdave

https://jsfiddle.net/dcookdesign/j91ohpoy/5/


#7

@lagdave I was curious so tried it myself for this… (the Thought 2 approach)
Take a look. It’s like a typewriter. I don’t think this is necessarily the best way to implement this (a lot of it is hardcoded so the functions are one-offs). But anyway, it’s just the concept.

https://jsfiddle.net/dcookdesign/x7fyy7rp/3/


#8

Im sorry but my provider does not allow me to visit several sites, unfortunately including jsfiddle.net


#10

@lagdave are you able to use codepen?


#11

Yep! Can you make me one, if you dont mind


#12

Okay here we go with codepen @lagdave :

Thought 1: Using opacity

Thought 2: Kind of Typewriter effect


#13

I think I see what you’re asking. Yes opacity is one trick to hide the alpha of elements. You might want to set display to none, or position to absolute after you finish a transition though because opacity will only change an elements alpha, it will still take up space on the page.

@lagdave you can go about this several ways as you are seeing. If you want to utilize JS as you first thought, you would have to update the innerText property of an element one character at a time to imitate typing. Because text content is a property, not a method, and strings are immutable objects (meaning you cannot update only one character of a string individually), you would have to do something like:


let oldText = document.querySelector("someSelector").innerText;
let text = "";
let newStr = "New Text";

for( let i = 0; i < newStr.length; i++ ){
  console.log(text); // To see the typing take place
  // or
  alert(text); // To see the typing take place (more annoying)
  text = text + newStr[i];
}
// or...if you want to write on top of existing text
for( let i = 0; i < newStr.length; i++ ){
  oldText = newStr[i] + oldText.slice(i);
}

Using the typing method you can imitate typing more by using a window.setTimeout(callback(), int) to pause inbetween each loop execution. You can even randomize the timeout timestamp if you want to imitate realistic typing even more by making it a bit more inconsistent.

Here is a codepen where I demonstrate this technique


#14

The thought one is what im looking for! now, I think “new text” that is currently displayed should display “some text” again when the button is clicked once more !


#15

Yeah! This is fairly the same with @dcookwebdev’s thought#2


#16

The function I use on that codepen is called typeIt(). All you do is pass in the new string, and the target element. Target element should be blank string, you can modify it to overrite if you want.


function typeIt( string, target ) {
    var hold = [];
    var step = 1;
    var tick = setInterval(function() {
        if(step == string.length) { clearInterval(tick) };
        hold.push(string.slice(step - 1, step));
        step += 1;
       target.innerHTML = hold.join('');
		 // document.getElementById('box').innerHTML = hold.join('');
    }, 50);
}

String Prototype Method

I also have a String prototype which would let you use the method on any string, just passing in your target element. Still requires some testing. this reference doesn’t seem to be working. Feel free to modify.

String.prototype.typeInto = function( elementNode ){
    let typedString = [];
    let step = 1;

    let tick = window.setInterval(function() {
        if( step == this.length ){
            clearInterval(tick);
        }

        typedString.push( this.slice(step - 1, step) );
        step += 1;
        elementNode.innerHTML = typedString.join('');
    }, 50);
}

#17

I see @Emgo-Dev … Im going to study your codes for the meantime


#18

@Emgo-Dev has much better function than mine! :slight_smile:


#19

@dcookwebdev Can I ping you up since i badly need support, i just cant ask and ask here, if you dont mind


#20

Maybe this will help, maybe for other occasion.
http://www.theappguruz.com/tag-tools/web/CSSAnimations/
http://cssanimate.com/


#21

Good use of recursion though. If we combined we’d be unstoppable!