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.
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
How to Call a Js Function Using Onclick Event
How to Optimize Website for Touch Devices
Modify Element :Before CSS Rules Programmatically in React
How to Check Element's Visibility via JavaScript
Transforms Are Added...Endlessly
Is There a Link to the "Latest" Jquery Library on Google APIs
What Limitations Apply to Opaque Responses
No 'Access-Control-Allow-Origin' Header Is Present on the Requested Resource Error
Passing Arguments Forward to Another JavaScript Function
What Does the ^ (Caret) Symbol Do in JavaScript
How to Resize HTML Canvas Element
Using CSS Modules How to Define More Than One Style Name
Restart a Gif Animation Without Reloading the File
Jquery Draggable with Zoom Problem
Changing Background Color of Div on Scroll
Angularjs:Difference Between the $Observe and $Watch Methods