How to Animate the Drawing of Text on a Web Page

How can I animate the drawing of text on a web page?

I want this word to be drawn with an animation, such that the page
"writes" the word out the same way that we would

Canvas version

This will draw single chars more like one would write by hand. It uses a long dash-pattern where the on/off order is swapped over time per char. It also has a speed parameter.

Snapshot
Example animation (see demo below)

To increase realism and the organic feel, I added random letter-spacing, an y delta offset, transparency, a very subtle rotation and finally using an already "handwritten" font. These can be wrapped up as dynamic parameters to provide a broad range of "writing styles".

For a even more realistic look the path data would be required which it isn't by default. But this is a short and efficient piece of code which approximates hand-written behavior, and easy to implement.

How it works

By defining a dash pattern we can create marching ants, dotted lines and so forth. Taking advantage of this by defining a very long dot for the "off" dot and gradually increase the "on" dot, it will give the illusion of drawing the line on when stroked while animating the dot length.

Since the off dot is so long the repeating pattern won't be visible (the length will vary with the size and characteristics of the typeface being used). The path of the letter will have a length so we need to make sure we are having each dot at least covering this length.

For letters that consists of more than one path (f.ex. O, R, P etc.) as one is for the outline, one is for the hollow part, the lines will appear to be drawn simultaneously. We can't do much about that with this technique as it would require access to each path segment to be stroked separately.

Compatibility

For browsers that don't support the canvas element an alternative way to show the text can be placed between the tags, for example a styled text:

<canvas ...>
<div class="txtStyle">STROKE-ON CANVAS</div>
</canvas>

Demo

This produces the live animated stroke-on (no dependencies) -

var ctx = document.querySelector("canvas").getContext("2d"),    dashLen = 220, dashOffset = dashLen, speed = 5,    txt = "STROKE-ON CANVAS", x = 30, i = 0;
ctx.font = "50px Comic Sans MS, cursive, TSCu_Comic, sans-serif"; ctx.lineWidth = 5; ctx.lineJoin = "round"; ctx.globalAlpha = 2/3;ctx.strokeStyle = ctx.fillStyle = "#1f2f90";
(function loop() { ctx.clearRect(x, 0, 60, 150); ctx.setLineDash([dashLen - dashOffset, dashOffset - speed]); // create a long dash mask dashOffset -= speed; // reduce dash length ctx.strokeText(txt[i], x, 90); // stroke letter
if (dashOffset > 0) requestAnimationFrame(loop); // animate else { ctx.fillText(txt[i], x, 90); // fill final letter dashOffset = dashLen; // prep next char x += ctx.measureText(txt[i++]).width + ctx.lineWidth * Math.random(); ctx.setTransform(1, 0, 0, 1, 0, 3 * Math.random()); // random y-delta ctx.rotate(Math.random() * 0.005); // random rotation if (i < txt.length) requestAnimationFrame(loop); }})();
canvas {background:url(http://i.imgur.com/5RIXWIE.png)}
<canvas width=630></canvas>

How to animate handwriting text on the web page using SVG?

How the Se7ensky animation works is that it uses the standard dash animation technique, but clips the animated stroke with an outline representing the hand-drawn look of the logo.

So the standard dash animation technique works as follows. You take a standard line:

<svg>  <path d="M 10,75 L 290,75" stroke="red" stroke-width="50"/></svg>

Canvas text with animate bg

You can use canvas’s context.globalCompositeOperation to overwrite text with the an image.

Then you can get the movement effect you want by animating the image’s x-offset.

This code will draw text on the canvas and then overwrite just the text with the image.

// first draw the text on the canvas
ctx.beginPath();
ctx.font="144pt Verdana";
ctx.fillText("See",30,200);
ctx.fill();

// use compositing to draw the background image
// only where the text has been drawn
ctx.beginPath();
ctx.globalCompositeOperation="source-in";
ctx.drawImage(img,-x,0);

Of course you'll want to stylize with your own text font, background image and animation pattern.

Here is code and a Fiddle: http://jsfiddle.net/m1erickson/MrVJB/

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
body{ padding:20px; }
canvas{border:1px solid red; position:absolute}
</style>

<script>
$(function(){

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");

var xOffset=100; // image offset
var fps=60;

var img=document.createElement("img");
img.onload=function(){
animate();
}
img.src="http://images4.fanpop.com/image/photos/23400000/water-water-23444632-2048-1277.jpg";

function draw(x){

ctx.save();
ctx.beginPath();

// put text on canvas
ctx.font="144pt Verdana";
ctx.fillText("See",30,200);
ctx.fill();
ctx.beginPath();

// use compositing to draw the background image
// only where the text has been drawn
ctx.globalCompositeOperation="source-in";
ctx.drawImage(img,-x,0);
ctx.restore();
}

function animate() {

// change the background image offset
xOffset+=3;
if(xOffset>=img.width){xOffset=0;}

// draw the text and background image
draw(xOffset);

// request another frame using fps intervals
setTimeout(function() {
requestAnimationFrame(animate);
// Drawing code goes here
}, 1000 / fps);
}

}); // end $(function(){});
</script>

</head>

<body>
<canvas id="canvas" width=400 height=300></canvas>
</body>
</html>

CSS Handwriting Animation

I've created a JSFiddle of it, that will do the trick for you.

And for effect like this, using HTML5 is really good option as you've being suggested to use canvas.

Here you can change height & width of canvas and your CSS as per your need.

Source: Handwriting Effect.

How to reveal one letter at a time?

Here's a snippet for something that you are looking for.

p{  color: Pink;   font-family: "Courier";  font-size: 20px;  margin: 10px 0 0 10px;  white-space: nowrap;  overflow: hidden;  width: 30em;  animation: type 4s steps(60, end); }
@keyframes type{ from { width: 0; } }
<p>Hi folks, this is typing animation using CSS</p>

Text and animation together on HTML5 canvas

The answer to this question lies in the laying of two canvas layers. First Canvas layer will have the background image and the animation effect. Second layer on top of it will draw the Text.
Note : Credit to @DBS for finding the solution.

JavaScript:

script type="text/javascript">
var ctx;
var ctx2
var imgBg;
var imgDrops;
var x = 0;
var y = 0;
var noOfDrops = 20;
var fallingDrops = [];
var intV;
fontVar ="36px Verdana";
fillColour="yellow";
strokeColour="green";

imgBg = new Image();
imgBg.src = "image.jpg";
var canvas = document.getElementById('myCanvas');
ctx = canvas.getContext('2d');
ctx.drawImage(imgBg,0,0,600,400); //Background

var canvas2 = document.getElementById('drawText');
ctx2 = canvas2.getContext('2d');

function drawing(){
ctx.drawImage(imgBg,0,0,600,400); //Background
}

function draw() {
ctx.drawImage(imgBg, 0, 0,600,400); //Background
for (var i=0; i< noOfDrops; i++)
{

ctx.drawImage (fallingDrops[i].image, fallingDrops[i].x, fallingDrops[i].y,35,35); //The rain drop

fallingDrops[i].y += fallingDrops[i].speed;
fallingDrops[i+7].x += fallingDrops[i].speed-1;//Set the falling speed
if (fallingDrops[i].y > 400) { //Repeat the raindrop when it falls out of view
fallingDrops[i].y = -120; //Account for the image size
fallingDrops[i].x = Math.random() * 600; //Make it appear randomly along the width
}
}
}

function setup() {

intV = setInterval(function(){draw()}, 36);
for (var i = 0; i < noOfDrops; i++) {
var fallingDr = new Object();
fallingDr["image"] = new Image();
fallingDr.image.src = "Rain.svg";
fallingDr["x"] = Math.random() * 600;
fallingDr["y"] = Math.random() * 5;
fallingDr["speed"] = 3 + Math.random() * 5;
fallingDrops.push(fallingDr);

}
}
function start(){
setup();
}

function stop(){
clearInterval(intV);
}

function clicked(){
z=document.getElementById("form_val");
ctx2.clearRect(0,0,600,400);
ctx2.font=fontVar;
ctx2.fillStyle=fillColour;
ctx2.strokeStyle=strokeColour;
ctx2.lineWidth=2;
ctx2.strokeText(z.value,200,200);
ctx2.fillText(z.value,200,200);
}

</script>

HTML

<div class="wrapper">
<canvas id="myCanvas" width="600" height="400" style="margin:1px;"></canvas>
<canvas id="drawText" width="600" height="400" onmouseover="start()" onmouseout="stop()</canvas>
</div>
<br>
Greeting Message: <input type="text" name="fname" size="50" id="form_val">
<button id="submit" onclick="clicked()">Add this message</button>
</div>

CSS

How can I stack two same-sized canvas on top of each other?



Related Topics



Leave a reply



Submit