中心的な単語が1つあるWebページが欲しい。
この単語をアニメーションで描画して、ページが同じように単語を「書き出す」ようにします。つまり、ある時点から始まり、最終的な結果がグリフになるように時間とともに線と曲線を描画します。
これが<canvas>
DOMで行われるかどうかは気にせず、JavaScriptとCSSのどちらで行われるかは気にしません。jQueryがないことは良いことですが、必須ではありません。
これどうやってするの?私は運が悪くて徹底的に検索しました。
中心的な単語が1つあるWebページが欲しい。
この単語をアニメーションで描画して、ページが同じように単語を「書き出す」ようにします。つまり、ある時点から始まり、最終的な結果がグリフになるように時間とともに線と曲線を描画します。
これが<canvas>
DOMで行われるかどうかは気にせず、JavaScriptとCSSのどちらで行われるかは気にしません。jQueryがないことは良いことですが、必須ではありません。
これどうやってするの?私は運が悪くて徹底的に検索しました。
回答:
この単語がアニメーションで描かれるようにして、ページが単語を「書く」のと同じように書き出す
これは、手書きで書くように単一の文字を描画します。時間ごとにオン/オフの順序が文字ごとに入れ替わる長いダッシュパターンを使用します。また、速度パラメータもあります。
アニメーションの例(下のデモを参照)
リアリズムと有機的な感触を高めるために、ランダムな文字間隔、yデルタオフセット、透明度、非常に微妙な回転を追加し、最後にすでに「手書き」のフォントを使用しました。これらを動的パラメーターとしてラップして、幅広い「ライティングスタイル」を提供できます。
さらにリアルな外観を得るには、デフォルトではないパスデータが必要になります。しかし、これは手書きの動作に似た短く効率的なコードであり、実装は簡単です。
ダッシュパターンを定義することで、マーチングアリや点線などを作成できます。これを利用して、「オフ」のドットに非常に長いドットを定義し、「オン」のドットを徐々に増やしていくと、ドットの長さをアニメートしながらストロークしたときに線が引かれているように見えます。
オフドットは非常に長いため、繰り返しパターンは表示されません(長さは、使用する書体のサイズと特性によって異なります)。文字のパスには長さがあるため、各ドットが少なくともこの長さをカバーしていることを確認する必要があります。
1つはアウトライン用、もう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>
リアルなアニメーションを作成できる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
ます。
前の回答
あなたはsvgを使ってこのようなことをすることができます stroke-dasharray
keyframes
アニメーションがなければ、このようなことができます
IEのサポートには、jquery / javascriptを使用できます
$(this).css('fill', 'red')
アニメーションへのコールバックとして追加することによって行われます
CSSのみ:
@keyframes fadein_left {
from {
left: 0;
}
to {
left: 100%;
}
}
#start:before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0%;
opacity: 0.7;
height: 25px;
background: #fff;
animation: fadein_left 3s;
}
<div id="start">
some text some text some text some text some text
</div>
多くのテストに続いて、ここにいくつかの注意事項があります。目標は、ユーザーの操作を必要とするDOMの重いページで、ブロックの少ない方法で高速テキストデータを表示することです。
もちろん、同じことを達成する方法はたくさんあります。この例では、違いは明らかではないかもしれませんが、実際には複雑なインターフェースに適用されます。
最も遅い:innerHTML
インラインスタイル。DOMは反復ごとに再計算されます。ブラウザは列車を維持するために一生懸命働いています。それはすぐに失敗し、メモリリークとフリーズを引き起こします:
setInterval(function(){
out.innerHTML = `<span style="position:fixed;top:${~~(Math.random() * 220)}px">${Math.random() * 1000}<span>`
},1)
<h1 id="out"></h1>
より良い方法:textContent
、requestAnimationFrame
およびWebアニメーションAPIを使用する。これはよりスムーズに進み、DOMの重いページでは明白です。ユーザー操作は再描画をブロックしません。インターフェイスの応答性を維持するために、一部の再描画はスキップされる場合があります。
let job
const paint = () => {
job = requestAnimationFrame(paint)
out.textContent = Math.random() * 1000
out.animate([{top: ~~(Math.random() * 220)+"px"},{top:0}],{duration: 1,iterations: 1})
}
/* Start looping -----------------------------------------*/
requestAnimationFrame(paint)
#out{
position: fixed}
<h1 id="out"></h1>
上記の例では、テキストオーバーフローのためにDOMがまだ再計算されています。デバッガが激しく点滅しているのがわかります。これはカスケード要素で本当に重要です!これにより、JavaScriptとユーザーのスクロールが遅くなる可能性があります。
フルパワー:cssを単独で使用して、css content
ルールとcss変数でデータを更新できます。その後、テキストは選択できなくなります。
let job
const paint = () => {
job = requestAnimationFrame(paint)
out.setAttribute('data-before', Math.random() * 1000)
out.animate([{top: ~~(Math.random() * 220)+"px"},{top:0}],{duration: 1,iterations: 1})
}
/* Start looping -----------------------------------------*/
requestAnimationFrame(paint)
#out{
position: fixed
}
#out:before {
content: attr(data-before)
}
<h1 id="out"></h1>
私のテストでは、大幅な改善が見られました。JavaScriptエンジンは、他のタスクをすばやくスキップしています。場合によっては、上記の例よりも少し遅く起動することがあります。しかし、それに加えて、これはユーザーのスクロールをブロックせず、デバッガーも好みで、ジャンプする必要はありません。