2011-01-13 9 views
4

CSS3トランジションでアニメートできるプロパティのリストは、ブラウザ間で一貫性がなく、新しいブラウザのバージョンで変更される可能性があります。たとえば、-moz-transformはFF3.6では-moz-transitionでアニメーション化できませんが、FF4ではあります。プロパティがCSS3遷移によってアニメーション化可能かどうかを検出しますか?

特定のプロパティがアニメーション可能かどうかをJavaScriptで検出する方法はありますか?私は信頼できないのでユーザーエージェントのスニッフィングを使用したくありません。

ありがとうございます!

+2

@Mournerあなたが私の答えを受け入れることができず、ジョーダンを受け入れることができれば、この種のものをグーグルで探そうとするならば、 – Duopixel

答えて

3

編集:アニメーション可能なプロパティを検出する優れた手法については、Jordan's answerを参照してください。

プロパティがアニメーション可能かどうかを検出する簡単な方法はありません。しかし、プロパティはほとんどの場合一貫しています(私が遭遇した唯一の問題は、FF4トランジション+テキストシャドウ+トランスフォームによるものです)。

http://www.w3.org/TR/css3-transitions/#the-transition-property-property-#properties-from-css-

のFirefox 3.6は、CSSの移行をサポートしていない、あなたは、Modernizrなどのjsライブラリーでこれを検出することができます。

http://www.modernizr.com/

+0

ありがとう!私はアニメーション化された変換がないトランジションサポートがある安定版のFFがあると確信していましたが、これはFF4ベータの一部であったことが分かりました。 – Mourner

+0

私はこのことについて別のプロジェクトで考えていましたが、実際には可能です。下記を参照してください。 :) –

7

はい、方法があります。デモンストレーションは以下の通りです。 非常に重要な警告が含まれていますので、必ずお読みください。

次のコードは、ブラウザが2つの値をアニメーション化できるかどうかをテストします。

コード

jsFiddle demo。このため

必須の引数を使用する方法

/* 
@param property The property to test. 
@param from  A valid starting value for the animation. 
@param to  A valid ending value for the animation. 
@param [element] The element to test with. (Required for testing 
       properties with prerequisites, e.g. "top" requires 
       non-static position.) 
*/ 
function isAnimationSupported(property, from, to, element) { 
    var doc = document.documentElement, 
     style = doc.appendChild(document.createElement("style")), 
     rule = [ 
       'capTest{', 
        '0%{', property, ':', from, '}', 
        '100%{', property, ':', to, '}', 
       '}' 
       ].join(''), 
     propCamel = property.toCamelCase(), 
     prefixes = 'moz ms o webkit '.split(' '), // Unprefixed last, see comments. 
     prefixCount = prefixes.length, 
     canAnimate = false; 

    element = doc.appendChild((element) 
      ? element.cloneNode(false) 
      : document.createElement('div')); 

    // Detect invalid start value. (Webkit tries to use default.) 
    element.style[propCamel] = to; 

    // Iterate through supported prefixes. 
    for (var i = 0; i < prefixCount; i++) { 

     // Variations on current prefix. 
     var prefix = prefixes[i], 
      hPrefix = (prefix) ? '-' + prefix + '-' : '', 
      uPrefix = (prefix) ? prefix.toUpperCase() + '_' : ''; 

     // Test for support. 
     if (CSSRule[uPrefix + 'KEYFRAMES_RULE']) { 

      // Rule supported; add keyframe rule to test stylesheet. 
      style.sheet.insertRule('@'+ hPrefix + 'keyframes ' + rule, 0); 

      // Apply animation. 
      var animationProp = (hPrefix + 'animation').toCamelCase(); 
      element.style[animationProp] = 'capTest 1s 0s both'; 

      // Get initial computed style. 
      var before = getComputedStyle(element)[propCamel]; 

      // Skip to last frame of animation. 
      // BUG: Firefox doesn't support reverse or update node style while 
      // attached. 
      doc.removeChild(element); 
      element.style[animationProp] = 'capTest 1s -1s alternate both'; 
      doc.appendChild(element); 
      // BUG: Webkit doesn't update style when animation skipped ahead. 
      element.style[animationProp] = 'capTest 1s 0 reverse both'; 

      // Get final computed style. 
      var after = getComputedStyle(element)[propCamel]; 

      // If before and after are different, property and values are animable. 
      canAnimate = before !== after; 
      break; 
     } 
    } 

    // Clean up the test elements. 
    doc.removeChild(element); 
    doc.removeChild(style); 

    return canAnimate; 
} 

// Cribbed from Lea Verou's prefixfree. 
String.prototype.toCamelCase = function() { 
    return this.replace(/-([a-z])/g, function($0, $1) { return $1.toUpperCase(); }) 
       .replace('-',''); 
}; 

は、アニメーション化するプロパティと開始し、それが取るべき仕上げ値です。必要に応じて、他の初期スタイルが設定された要素を渡すこともできます(例: position: absolute。要素を渡さないと、アニメーションはdivでUAが適用するデフォルトスタイルでテストされます。それはfrom値とto値に設定された最終フレームに設定された初期フレームで、

キーフレームアニメーションのルールは、ダミーのスタイルシートに追加される仕組み

。このアニメーションは要素に適用されます。次に、アニメーションされたプロパティの計算されたスタイルを調べて、アニメーションが最初のフレームから開始したときと最後のフレームから開始するときのアニメーションが異なるかどうかを確認します。

この理由は、トランジションとキーフレームアニメーションの両方のアニメーション可能プロパティが同じで、プロパティがアニメーションをサポートしている場合にのみ、ブラウザがキーフレーム値を適用するためです。

注意事項(これらのいくつかは厄介です、使用する前に読んで!)

ブラウザがアニメーションを処理する方法にはいくつかの矛盾があります。これらの2つは、私ができるだけ将来的な方法で取り組んできました。しかし、そのうちのいくつかは扱いにくいです。

他のもの(WebkitやOperaなど)では静的な要素の値はtwyensの値(例:left)が最も重要です。実際にはは要素を移動しませんが、そのプロパティの値は更新されます。したがって、静的に配置されていない要素を渡さずに位置値をアニメートしようとすると、ブラウザ間で異なる結果が得られます。

CSSトランジションをサポートする主要なブラウザの最新バージョンでは、CSSキーフレームもサポートされていますが、一部の旧バージョンは前者をサポートしていますが後者はサポートしていません。

最後に、これをもっとうまくやっていたら、prefixfreeを使用して、直接使用する正しいプレフィックスを判断してください。私は現在、プレフィックスの配列に対して、プレフィックスのないバージョンから始めてテストしています。

+1

+1とてもクール!テストdivが完全に配置されていないため、「右上の左下」にfalseが表示されます。私はこれをどう扱うか分かりませんが、おそらくテスト区をオーバーライドする要素を渡すことができますか? – Duopixel

+0

良い点!オプションの要素パラメータを追加することは良い考えです。私のブロードバンドが死んでしまったとき、私は実際にフィドルを更新していました。私はオンラインに戻ったときに説明を更新します! :) –

+1

クール!別の良いテストは、失敗するはずのインライン要素のCSS変換をアニメーション化することです。 – Duopixel

関連する問題