これにJavaScriptを使用しても問題ない場合は、canvas
要素を使用して実行できます
アイデアは、テキストを含む要素とcanvas
要素が重なり合っているということです。要素にテキストを保持します (テキストでは不可能なテキスト選択を可能にするためcanvas
) が、完全に透明にしrgba(0,0,0,0)
ます (IE8 以前でテキストを表示するために、それはRGBa
サポートがないためです)。 canvas
IE8 以前ではサポートされていません)。
次に、要素内のテキストを読み取り、同じフォント プロパティを使用してキャンバスに書き込みます。これにより、キャンバスに書き込む各文字が、テキストを含む要素内の対応する文字の上に表示されます。
このcanvas
要素は複数行のテキストをサポートしていないため、テキストを単語に分割し、テスト行に単語を追加し続けて測定する必要があります。テスト行の幅が行の最大許容幅よりも大きい場合 (要素の計算された幅をテキストで読み取ることにより、その最大許容幅を取得します)、それをキャンバスに書き込みます。最後の単語が追加されたら、テスト行をその最後の単語になるようにリセットし、次の行を書き込む y 座標を 1 行の高さで増やします (これは、テキストを含む要素の計算されたスタイルからも得られます)。書く行ごとに、適切なステップでテキストの不透明度も減らします (このステップは、1 行あたりの平均文字数に反比例します)。
この場合簡単にできないことは、テキストを正当化することです。それは可能ですが、もう少し複雑になります。つまり、各ステップの幅を計算し、行ごとではなく単語ごとにテキストを記述する必要があります。
また、ウィンドウのサイズを変更するときにテキスト コンテナの幅が変わる場合は、キャンバスをクリアして、サイズを変更するたびにテキストを再描画する必要があることに注意してください。
OK、コード:
HTML :
<article>
<h1>Interacting Spiral Galaxies NGC 2207/ IC 2163</h1>
<em class='timestamp'>February 4, 2004 09:00 AM</em>
<section class='article-content' id='art-cntnt'>
<canvas id='c' class='c'></canvas>In the direction of the <!--and so on-->
</section>
</article>
CSS :
html {
background: url(moving.jpg) 0 0;
background-size: 200%;
font: 100%/1.3 Verdana, sans-serif;
animation: ani 4s infinite linear;
}
article {
width: 50em; /* tweak this ;) */
padding: .5em;
margin: 0 auto;
}
.article-content {
position: relative;
color: rgba(0,0,0,0);
/* add slash at the end to check they superimpose *
color: rgba(255,0,0,.5);/**/
}
.c {
position: absolute;
z-index: -1;
top: 0; left: 0;
}
@keyframes ani { to { background-position: 100% 0; } }
JavaScript:
var wrapText = function(ctxt, s, x, y, maxWidth, lineHeight) {
var words = s.split(' '), line = '',
testLine, metrics, testWidth, alpha = 1,
step = .8*maxWidth/ctxt.measureText(s).width;
for(var n = 0; n < words.length; n++) {
testLine = line + words[n] + ' ';
metrics = ctxt.measureText(testLine);
testWidth = metrics.width;
if(testWidth > maxWidth) {
ctxt.fillStyle = 'rgba(0,0,0,'+alpha+')';
alpha -= step;
ctxt.fillText(line, x, y);
line = words[n] + ' ';
y += lineHeight;
}
else line = testLine;
}
ctxt.fillStyle = 'rgba(0,0,0,'+alpha+')';
alpha -= step;
ctxt.fillText(line, x, y);
return y + lineHeight;
}
window.onload = function() {
var c = document.getElementById('c'),
ac = document.getElementById('art-cntnt'),
/* use currentStyle for IE9 */
styles = window.getComputedStyle(ac),
ctxt = c.getContext('2d'),
w = parseInt(styles.width.split('px')[0], 10),
h = parseInt(styles.height.split('px')[0], 10),
maxWidth = w,
lineHeight = parseInt(styles.lineHeight.split('px')[0], 10),
x = 0,
y = parseInt(styles.fontSize.split('px')[0], 10),
text = ac.innerHTML.split('</canvas>')[1];
c.width = w;
c.height = h;
ctxt.font = '1em Verdana, sans-serif';
wrapText(ctxt, text, x, y, maxWidth, lineHeight);
};