Firefox 4:-moz-elementを使用してカスタム要素を背景としてレンダリングする

Paul Rouger:これはゲストのMarcus Stangeのブログ投稿です。 Marcusは通常、Mac用のFirefoxテーマの実装に取り​​組んでいますが、今回は-moz-elementを実装してGeckoプロトタイプエンジンを少し歩き回りました。


新しいFirefoxの4番目のベータでは background-imageの CSSプロパティの新しい拡張機能、つまり-moz-element(#elementID)を使用して任意の要素を背景として描画する機能を紹介します。
<p id = "myBackground1" style = "背景:darkorange;色:白;幅:300px;高さ:40px;">

この要素は背景として使用されます。

<!-この要素は背景として機能します。 ->

</ p>

<p style = "background:-moz-element(#myBackground1); padding:20px 10px; font-weight:bold;">

このボックスは、背景として#myBackground1を使用します!

<!-この長方形は、背景として#myBackground1を使用します! ->

</ p>
[ ]



-moz-element()画像は、通常のurl()画像と同じように機能します。 これは、背景のすべての通常のプロパティであるbackground-positionbackground-repeat 、さらにbackground-sizeによって制御されることを意味します



background-sizeを使用すると、背景として使用される要素のサムネイルを作成できます-以下に例を示します。
<ul id = "サムネイル">

<li style = "background-image:-moz-element(#slide-0)"> </ li>

<li style = "background-image:-moz-element(#slide-1)"> </ li>

<li style = "background-image:-moz-element(#slide-2)"> </ li>

<li style = "background-image:-moz-element(#slide-3)"> </ li>

</ ul>
#thumbnails li {

幅:160px;

高さ:120px;

background-repeat:繰り返しなし;

background-size:含む;

}
[ ]



-moz-element に関する 3つのことを念頭に置いてください:
  1. 背景は生きています-moz-elementプロパティで指定された要素で何が起こっても、背景はその変更を反映します。 また、カーソルの強調表示、テキストカーソルの点滅なども表示されます。
  2. 背景は単なる可視性です。 クリックしてプライマリ画像要素に到達することはできません。 それが仕組みです。
  3. 背景には、 任意の HTML要素を作成できます。 偶数 <iframe>



    [ ]



    でも<video>



    [ ]



    キャンバス<canvas>でも



    [ ]
背景としてキャンバスを使用すると、多くのアプリケーションで役立ちます。 たとえば、セピアのブラウザーでCSS背景画像の色変更する場合、URI "data:"を取得して、キャンバスで処理された画像を追加で再エンコードする必要はありません。 代わりに、キャンバス自体を背景画像にすることができます。



背景画像としてcanvasを使用すると、 -webkit-canvas()を介してWebkitもサポートされます。



ループをレンダリングする



再帰リンクに関する簡単なメモ: この方法で-moz-elementを使用してそれ自体がレンダリングされる要素レンダリングしようとすると 、レンダリングループが検出され、防止されます。 そのため、 シェルピンスキーカーペットを描きたい場合は、別の方法を考え出す必要があります。



ソース要素の隠蔽



元の要素を表示したくない場合がありますが、 -moz-elementバックグラウンドのみが見えます。 そして、あなたは何をしなければなりませんか? ソース要素に「 display:none 」または「 visibility:hidden 」を設定するだけでは機能しません。その場合、 -moz-elementの背景に描画するものがないため、透明になります。



代わりに、要素を直接非表示にせずに画面にレンダリングしないようにする必要があります。 考えられる方法の1つは、この要素を別の要素の内側に配置し、この別の「 height:0; オーバーフロー:非表示; 「CSSで。



このルールの例外は、画像、キャンバス、ビデオの3つのタイプの要素です。 これらのタイプの要素は、「 display:none 」プロパティ持つこと許可 引き続き -moz-elementで使用さ ます 。 さらに、それらはメイン文書のDOMにさえ含まれないかもしれません。



新しいDOM API:

document.mozSetImageElement





ドキュメントオブジェクトに新しいメソッドdocument.mozSetImageElement( element_IDelementを追加しました。



次の2行のコードを検討してください。
var slide5 = document.getElementById( "slide-5");

document.mozSetImageElement( "current-slide"、slide5);
background-imageプロパティを備えたすべての要素 -moz-element(#current-slide)は、 ID slide-5を持つ要素を表示します-ID current-slideを持つ要素があっても



document.mozSetImageElement( "current-slide"、null)を呼び出すと、現在のオーバーライドがキャンセルされます。



このようなAPIは、さまざまな実際の状況で役立ちます。 前のサブセクションでそれらの1つを間接的に言及しました。mozSetImageElementを使用すると、DOMツリーの一部ではないキャンバスと画像を使用できます。
var img = new Image();

img.src = "my_image.png";

document.mozSetImageElement( "image"、img);



var canvas = document.createElement( "canvas");

canvas.width = canvas.height = 100;

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

// ... ctxを介して描画...

document.mozSetImageElement(「キャンバス」、キャンバス);
例を示す



mozSetImageElementの呼び出しが役立つ別の状況は、javascript関数のライブラリを作成することです。 たとえば、次の機能があります。
var runningNumber = 0;

関数addReflectionToElement(reflectedElement){

var referenceID = "reflected-element-" + runningNumber ++;

var reflection = document.createElement( "div");

reflection.className = "reflection";

reflection.style.backgroundImage =

"-moz-element(#" + referenceID + ")";

document.mozSetImageElement(referenceID、reflectedElement);

// ...そして、DOMに反射を挿入します...

}
このパスに従うことにより、ライブラリ関数を使用する副作用を減らすことができます。渡される要素のIDを操作する必要はありません。



最後に、 mozSetImageElementでは、他のドキュメントの要素を参照することもできます(たとえば、<iframe>内)。 この場合、もちろん、ドキュメントの相互作用(発信元の統一)の通常の要件が適用されます。



SVGレンダリングサーバーの-moz-element



:パターンとグラデーション



SVGを手動で記述したことがある場合は、おそらくペイントサーバーの概念に精通しているでしょう:これらは、モノフォニックの塗りつぶしが適切でない場合に塗りつぶし またはストローク属性で指定する必要がある要素、パターン、 および/またはグラデーションです。 -moz-elementを使用して、HTML要素の背景でも使用できるようになりました
<p style = "background:-moz-element(#pattern)、

-moz-element(#gradient);

パディング:10px; 色:白 ">

この要素には、両方のタイプのSVGペイントサーバーがあります

背景:パターンとグラデーション。

<!-この要素の背景は両方のタイプを使用します

SVGレンダリングサーバー:パターンとグラデーションの両方。 ->

</ p>



<svg height = "0">

<linearGradient id = "gradient" x2 = "0" y2 = "1">

<stop stop-color = "black" offset = "0%" />

<stop stop-color = "red" offset = "100%" />

</ linearGradient>

<pattern id = "pattern" patternUnits = "userSpaceOnUse"

幅= "60"高さ= "60">

<circle fill = "black" fill-opacity = "0.5"

cx = "30" cy = "30" r = "10" />

</パターン>

</ svg>
[ ]



新しいHTML5パーサーのおかげで、埋め込みSVGコードを機能させるためにXHTMLを使用する必要がないことに注意してください。



上記の機能は、 CSSグラデーションとSVGイラストの既存の機能を複製しますが、一部の状況(アニメーションなど)でも非常に便利です。 次のようなアニメーショングラデーションを備えたプロセスインジケータを作成する必要があるとします。



[プロセスインジケータ]



CSSグラデーションとbackground-positionプロパティを定期的に更新するJavaScriptを使用して、目的を達成できます。 ただし、SMILを使用してアニメーション化されたSVGグラデーションを使用することもできます。そのため、javascriptをまったく必要としません。
<div

style = "background:-moz-element(#animated-gradient);">

</ div>



<svg height = "0">



<linearGradient id = "アニメーショングラデーション" spreadMethod = "反映"

gradientUnits = "userSpaceOnUse"

x1 = "16" x2 = "24" y2 = "0">

<animate attributeName = "x1" values = "16; 0" dur = "350ms"

repeatCount = "indefinite" />

<animate attributeName = "x2" values = "24; 8" dur = "350ms"

repeatCount = "indefinite" />



<stop stop-color = "#0F0" offset = "0" />

<stop stop-color = "#0D0" offset = "100%" />

</ linearGradient>



</ svg>
例を示す



CSSアニメーションでも同じことが実現できますが、Geckoで実装されていない限り、上記のパスをたどることができます。



CSSバックグラウンドとしてのSVG画像のサポート( バグ276431 )も近日中に利用可能になります。



そして、もう1つの例があります。CSSとSVGのPacmanです。



用途



-moz-elementを使用するための提案がいくつかあります



反射



反射とは何ですか?
#reflection {

/ * Reflectionは元の要素のコピーです... * /

背景:-moz-element(#反射要素)

左下の繰り返しなし。



/ * ...上から下に反映されます... * /

-moz-transform:scaleY(-1);



/ * ...そして、上から下へと徐々に暗くなります。 * /

mask:url(#reflection-mask);

}
[ ]



反射に任意のスタイルを適用できるため、水面上のアニメーション円のような効果を生成できます。



スライド間のゴージャスな移行



このデモでは、前のスライドの上半分が折り返され、その下の次のスライドを開くように見える、隣接するスライド間のこのような壮大な移行を実現したいと思います。
Mozilla Hacksブログのこの時点で、<video>要素で接続されたビデオがあるため、Habrahabrで表示することはできません。
このアイデアをどのように実装しますか? 間違いなく、 何らかの変換が必要になりますが、どの特定の要素の変換が必要でしょうか? スライドの上半分には下とは異なる変換が必要なので、スライド全体に変換を適用するだけでは機能しません。



最後に、4つの新しい要素(#previousUpper、#previousLower、#nextUpper、および#nextLower)を作成し、それらを別のコンテナー(#transitionと呼ばれる)に配置しました。これは、スライドからスライドへの遷移中にのみ表示されます。 次に、それらに正しいサイズを割り当て、 background-image:-moz-element(#previous / nextSlide)background-positionプロパティの正しい値を使用して、前または次のスライドの画像の対応する部分をオーバーレイします。 そして、これらの補助要素に目的の変換を追加します。



ただし、この例のコードは非常に複雑です...-したがって、最終的なデモを紹介します。



もっと?



これで-moz-elementの例の意図は終了しましたが、もちろん、このプロパティを使用してさらに多くのことができます。 次はあなたの番です!



謝辞



このテーマに関する感謝の大部分は、2008年に最初の 実装を準備したRobert O'Callahanに値します。 しかし、彼の最初の実験の後、彼はより重要な問題に密接に取り組む必要があったため、(2009年4月に) ニュースグループで適切なAPIがどうあるべきかについて議論を始めるまで、彼のパッチはほぼ1年間非アクティブでした。 すぐ後に、川口亮はロバートの著作を復活させ、 Mozillaでのインターンシップの最後の数週間を彼らに捧げました。 1年後、私はこのパッチをレビュー(レビュー)のために準備し、Firefoxをコードに含めるまでの最終段階に導きました。



最後に、 mozRequestAnimationFrameが関係する同じ警告を表示します。 - moz -element document.mozSetImageElement両方とも実験的なAPIです。 私たちは彼らの無限のサポートを保証しませんし、彼らの使用を支持しません。 人々がそれらを実験できるように実装し、フィードバックを受け取りました。 これらのAPIを標準として提供します(ただし、「moz」プレフィックスはもちろん使用しません)。実装に関するフィードバックは、将来の標準の改善に役立ちます。



All Articles