javascript - 我如何在網頁上動畫化文字的繪製?
我想要有一個網頁,上面有一個置中的單詞。
我希望這個單詞能用動畫的方式被描繪出來,使頁面像我們一樣“書寫”這個單詞,也就是說,它從一個點開始,隨著時間畫出線條和曲線,使最終結果成為一個字形。
我不在乎這是用 <canvas> 還是 DOM 完成的,也不在乎是用 JavaScript 還是 CSS 完成的。沒有 jQuery 會比較好,但不是必需的。
我該如何做這件事?我已經徹底搜尋過,但沒有任何結果。
答案#1
我希望這個單詞能以動畫方式呈現,使得頁面像我們一樣將單詞“寫出來”
畫布版本
這將使單個字元的繪製更像手寫。它使用一個長破折號模式,其中每個字元的開/關順序會隨時間交換。它還有一個速度參數。
範例動畫(見下方示範)
為了增加真實感和自然的感覺,我加入了隨機字母間距、任意的位移偏移、透明度、非常細微的旋轉,最後使用了已經具有「手寫」效果的字型。這些可以作為動態參數整合起來,以提供廣泛的「書寫風格」。
若要更逼真的外觀,則需要路徑數據,但預設情況下並不需要。但這是一段簡短且高效的程式碼,可以模擬手寫行為,且易於實現。
它如何運作
透過定義虛線的樣式,我們可以創建行進的螞蟻線、點線等等。利用這個方式,定義一個非常長的「關閉」點並逐漸增加「開啟」點,它將在筆畫動畫點長度時,給人一種正在畫線的錯覺。
由於間隔點太長,重複的圖案將無法被看見(長度會隨所使用字體的大小和特性而有所不同)。字母的路徑會有一定的長度,因此我們需要確保每個點至少覆蓋這個長度。
對於由多個路徑組成的字母(例如 O、R、P 等),其中一個是輪廓,另一個是空心部分,線條看起來會同時被繪製。使用這種技術我們無法對此做太多,因為這需要對每個路徑段分別進行描邊。
相容性
對於不支援 canvas 元素的瀏覽器,可以在標籤之間放置另一種顯示文字的方法,例如帶樣式的文字:
<canvas ...>
<div class="txtStyle">STROKE-ON CANVAS</div>
</canvas>
示範
這會產生即時動畫描邊效果(無需依賴) -
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>答案#2
編輯 2019
我創建了一個可以製作逼真動畫的 JavaScript 函式庫。它易於使用,並且需要一個作為字體的特殊 JSON 文件。
var vara = new Vara("#container", "https://rawcdn.githack.com/akzhy/Vara/ed6ab92fdf196596266ae76867c415fa659eb348/fonts/Satisfy/SatisfySL.json", [{
text: "Hello World!!",
fontSize: 48,
y:10
}, {
text: "Realistic Animations",
fontSize: 34,
color:"#f44336"
}], {
strokeWidth: 2,
textAlign:"center"
});#container {
padding: 30px;
}<script src="https://rawcdn.githack.com/akzhy/Vara/16e30acca2872212e28735cfdbaba696a355c780/src/vara.min.js"></script>
<div id="container"></div>查看 Github 頁面 以獲取文件和範例。以及 Codepen
先前的回答
以下範例使用 snap.js 動態創建 tspan 元素,然後對它們的 stroke-dashoffset 進行動畫處理。
var s = Snap('svg');
var text = 'Some Long Text'
var len = text.length;
var array = [];
for (var x = 0; x < len; x++) {
var t = text[x]
array.push(t);
}
var txt = s.text(50, 50, array)
$('tspan').css({
'font-size': 50,
fill: 'none',
stroke: 'red',
"stroke-width":2,
'stroke-dasharray': 300,
'stroke-dashoffset': 300
})
$('tspan').each(function(index) {
$(this).stop(true, true).delay(300 * index).animate({
'stroke-dashoffset': 0,
}, 300, function() {
$(this).css('fill', 'red')
})
})<script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.3.0/snap.svg-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<svg width="500" height="500">
</svg>先前的回答
你可以使用 SVG 的 stroke-dasharray 做類似這樣的事情
text {
stroke-dasharray: 1000;
stroke-dashoffset: 1000;
-webkit-animation: draw 8s forwards;
}
@-webkit-keyframes draw {
100% {
stroke-dashoffset: 0;
}
}
text {
stroke-dasharray: 1000;
stroke-dashoffset: 1000;
-webkit-animation: draw 8s forwards;
-moz-animation: draw 8s forwards;
-o-animation: draw 8s forwards;
-ms-animation: draw 8s forwards;
animation: draw 8s forwards;
}
@-webkit-keyframes draw {
100% {
stroke-dashoffset: 0;
}
}
@-moz-keyframes draw {
100% {
stroke-dashoffset: 0;
}
}
@-o-keyframes draw {
100% {
stroke-dashoffset: 0;
}
}
@-ms-keyframes draw {
100% {
stroke-dashoffset: 0;
}
}
@keyframes draw {
100% {
stroke-dashoffset: 0;
}
}<svg width="500" height="500">
<text x="100" y="80" fill="none" stroke="black" stroke-width="1" font-size="50">Some text</text>
</svg>沒有 keyframes 動畫,你可以做類似這樣的事情
<svg width="500" height="500">
<text x="100" y="80" fill="none" stroke="black" stroke-width="5" font-size="50" stroke-dasharray="1000"
stroke-dashoffset="1000">Some text
<animate attributeName="stroke-dashoffset"
from="1000"
to="0"
dur="8s"
fill="freeze">
</animate> </text>
</svg>而對於 IE 支援,你可以使用 jquery/javascript
$('text').animate({
'stroke-dashoffset':'0'
},8000)text {
stroke-dasharray: 1000;
stroke-dashoffset: 1000;
}<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<svg width="500" height="500">
<text x="100" y="80" fill="none" stroke="black" stroke-width="1" font-size="50"
>Some text
</text>
</svg>