Posts Tagged ‘css3’

[CSS3|jQuery|Webkit]translate3d等のtransformで設定した現在値を取得したい


2011
09.26

皆さんご無沙汰しております、Web屋の中の人です。

手術やらリハビリやら、少々複雑なシステム開発案件等でお勉強の方を長期に渡り休止しておりましたが久々にやってみようと言う事でインターフェイスの調整やバグ取り、むしろソースの整理なんかをしているとタイトルの状況になりました。

iPhoneiPad 上でアニメーションしたい時は、jQuery.animate は原則使い物になりませんので CSS3transform を利用してグリグリします。

 

ちなみに今回はタイトルに記載している通り「webkit」ブラウザのみ対象としていますのでご注意ください。
※Safari、Chromeなどなど。

 

ありがちな例を挙げると、js でスライダーなんかを作っている時に「この要素の x 座標は今ナンボ程動いてますか」と言う状況です。
jQuery を使っているなら簡単ですよね、

1
alert($('#hoge').css("left"));

これでパパッと解っちゃう訳で、非常に便利です。

所が CSS3transform で設定する時は、

1
2
3
#hoge {
    -webkit-transform: translate3d(237px, 5px, 0px);
}

こんな感じなので、x 座標ってどうやって書けば取得出来るの?となった訳です。

1
alert($('#hoge').css("-webkit-transform"));

取りあえずこう書いてみると、下記のように出力されました。

matrix(1, 0, 0, 1, 237, 5)

うーん、4番目が x で5番目が y なんだろうな…じゃあ z はどこに出るんだろう。

 

ブラウザ限定の強み、と言う事で素直に WebKitCSSMatrix で分解する事にした。仕様書通り使うと

1
2
3
var obj = document.getElementById('hoge');
var m = new WebKitCSSMatrix(obj.style.webkitTransform);
alert(m.e);

こんな感じになりますが、折角 jQuery を使っているので…

1
2
var m = new WebKitCSSMatrix($('#hoge').css('-webkit-transform'));
alert(m.e);

こんな感じでも取得可能です、結構乱暴に使えますね。
取得出来る値はコチラの仕様書に網羅されています、かなり色々設定出来るだけに複雑ですね…単純な物は a〜f って覚えておくのが良さそうです。

 

 

それではまた。

 

 

[CSS3]transition-durationの時間を無視して途中で終わってしまう時のTips


2011
06.29

皆さんご無沙汰しております、どっぷりと新製品の開発に浸かっております。

そこそこ経験を積んでからのチャレンジだったので、それなりに順調なのですが…やっぱりハマるとこはハマりますね。

 

その中でもハマると厄介な部分の Tips を紹介したいと思います。

 

内容は件の通り、再現は確実に取れる訳ではないのですが javascript から要素の transition プロパティを設定して、すぐに値を変更させようとすると再現しやすいようです。

具体的には下記のような感じ。

 

1
2
3
4
5
6
7
8
9
// 検証環境は safari です
var hoge = function() {
    $('#foo').css('-webkit-transition', 'all 1000ms ease-in');
    $('#foo').css('-webkit-transform', 'rotate(360deg)');
}

$(function() {
    hoge();
});

 

こんな具合で実行すると、要素 #foo が1秒かけてぐるりと1回転するハズが少し傾いた直後に一瞬で「360度回転した」事になりアニメーションの最終結果まで飛ばされてしまう。

と言う現象が発生します。

ちなみに Line : 3〜4 をチェインさせても発生する時はしますし、はたまたこれで普通に動いちゃったりもするので何だか良く解りません。

先に fix してしまったので、それ以降発生せず原因が不明なままなんですよね。発生しないに越した事は無いけど。

 

取りあえず css の元ファイルの方でデフォルト状態を色々変更しつつ検証していたのですが、同じプロパティを持つ3つの要素があって、2つの要素は行けるけど、1つだけ駄目だったと言うケースもあったりなんかして云々。

結局 transition の設定を値変更処理が追い抜いてしまっているんじゃないかと言う推測に至りました。

 

と言う訳で困った時の setTimeout です、本当はコールバックを駆使するのが一番確実だと思うのですが、コールバックイベントとして用意されているのは webkitTransitionEnd と言うのしか見つけられませんでした。

このイベントは「値の変化が終了したら発生」するのでこの場合は約に経ちませんので、ここは setTimeout に頼る事にしました。

同期的な部分は上記のイベントでコールバックを蹴って取れば良いと思う、終わり良ければなんとやら。事後処理で手を打つのも悪く無い選択だと思います。

では fix 版のコードを書いてみます。

 

1
2
3
4
5
6
7
8
9
10
11
12
13
// 検証環境は safari です
var timer;
var hoge = function() {
    $('#foo').css('-webkit-transition', 'all 1000ms ease-in');
   
    timer = setTimeout(function() {
        $('#foo').css('-webkit-transform', 'rotate(360deg)');
    }, 0);
}

$(function() {
    hoge();
});

 

取りあえずこれで動いています、今の所は。

setTimeout の第2引数は最初100でやってたのですが、0でも問題無いようです。

すると遅延による処理追い越しとか単純な事じゃないのかもしれませんね、今回のように無名関数で実行する等のプロセスを分ける事に意味があるのかもしれない。

 

全部推測だけど

 

ActionScriptJavaScript を今までガッツリやってる方達からすると基本だろ!と言われそうですが、これ系のスクリプトが得意と言うのは「いかに同期を取らせるのが上手いか」なんだろうなと思いました。

 

それではまた。