飴屋

開発日記

2018/7/29

iPhoneのMobile Safariでアニメーションが動いてない!という連絡を受けて、原因を推測して修正したときの話です。

そのWEBサイトでは、CSSの「animation」プロパティを使って画像が漂うような動きを指定していました。しかし、iPhoneで閲覧すると画像は静止したまま動いてくれませんでした。iPhoneだけで起こる問題に対処する作業は、過去に何度もありますが、CSSで規定した静的な指定が動作しないとなるとMobile Safari自体の欠陥なんじゃないかな~とかなんとか思いつつ、似たような事例を探してみることにします。特筆事項としては、閲覧中のページを一度別のタブに変更してから戻ってくると、アニメーションがちゃんと開始される、ということです。

@keyframes animImg {
50% {
transform: translate(-10%, 10%);
}
100% {
transform: translate(0);
}
}

原因はtransformプロパティにtranslate(平行移動)の指定を入れる際に「%」単位で移動量を指定することにあるようでした。推測になりますが、ブラウザの内部的に画面のサイズを計算し終わる前にアニメーションの移動量を「%」から別の描画単位に変換されてしまい、縦横の移動量が「0」になったために静止してるように見えたんじゃないかと思います。画面サイズの計算が終わった段階で、移動量も更新されてほしいところですが、未実装なんでしょうかね。

対策として、画面のサイズが計算し終わったタイミングでアニメーションが行われるように刺激を加えてみました。

//jQueryを使った例
$(document).ready(function(){
$('#mondaino img').css({'animation-play-state':'running'});
});

これで動いたのでよしとしました。

2018/6/20

ふいにレンタルサーバー上でmecabが動かしたいという衝動に駆られていろいろやってみたメモ。なお、レンタルサーバーはXserverです。

http://palmgate.co.jp/masato_kato/article.html&id=127

こちらを参考にmecabと辞書をインストールしました。レンタルサーバーなので、 /home/ACCOUNT-NAME/ 配下にインストールせざるを得ないという部分が特殊です。参考サイトに倣って /home/ACCOUNT-NAME/bin/mecab に配置しました。

続いて、perlが好きなのでperlのバインディング(ラッパーみたいなやつ)をインストールしてみます。perlのモジュールもレンタルサーバーなので勝手はできず /home/ACCOUNT-NAME/lib に配置しようと思います。

$ tar xvfz mecab-perl-0.996.tar.gz
$ cd mecab-perl-0.996
$ perl Makefile.PL
$ make
$ make install

通常なら↑こんな感じmecab-perl-0.996.tar.gzを展開して、Makefileを作って、makeすればいいそうですが、まずMakefileの作成に躓きます。Makefile.PLの中で呼び出す mecab-config にパスが通っていない模様。

use ExtUtils::MakeMaker;
WriteMakefile(
'NAME' => 'MeCab',
'CC' => `/home/ACCOUNT-NAME/bin/mecab-0.996/mecab-config --cxx`,
'LD' => `/home/ACCOUNT-NAME/bin/mecab-0.996/mecab-config --cxx`,
'INC' => `/home/ACCOUNT-NAME/bin/mecab-0.996/mecab-config --cflags`,
'LIBS' => `/home/ACCOUNT-NAME/bin/mecab-0.996/mecab-config --libs`,
'VERSION' => `/home/ACCOUNT-NAME/bin/mecab-0.996/mecab-config --version`,
'OBJECT' => 'MeCab_wrap.o'
);

↑こんな感じでmecab本体をインストールしたときの作業パスを加えてやるとMakefileができました。そのままインストールしようとすると、標準のモジュール置き場にインストールしようとして権限がなくて失敗するので、Makefileを直接、書き換えてみました。

INSTALLPRIVLIB = /home/ACCOUNT-NAME/lib
INSTALLSITELIB = /home/ACCOUNT-NAME/lib
INSTALLVENDORLIB = /home/ACCOUNT-NAME/lib
INSTALLARCHLIB = /home/ACCOUNT-NAME/lib
INSTALLSITEARCH = /home/ACCOUNT-NAME/lib
INSTALLVENDORARCH = /home/ACCOUNT-NAME/lib

正直、中身が把握できてないのでインストール先に関係ありそうな変数をいくつかいじってみたという感じです。これで設置はOKです。設置したパスを use lib で指定すれば、perlに必要なモジュールが読み込まれます。

$ perl test.pl

さっそくパッケージの中にあった test.plを実行してみます。が、動かない。mecab本体のライブラリ(shared object)が読み込めないとのこと。/home/ACCOUNT-NAME/bin/mecab/lib の中に必要なファイル libmecab.so.2 はあるのですが、shared objectの本来の置き場所にないので読み込めないようです。makeの際に同じ場所にある libmecab.a を静的にリンクしてみようとも思いましたが、リンカの知識が乏しいので断念しました。(-fPIC?なにそれ?)

LD_LIBRARY_PATH=$HOME/bin/mecab/lib
export LD_LIBRARY_PATH

shared objectの置き場所のパスは環境変数LD_LIBRARY_PATHで規定されるとのことなので、.bash_profileにこんな設定を足してみたところ test.pl が無事実行されて、分かち書きされた文章が表示されました。
続いて、これをCGIとして呼び出したいと思ったのですが、これが茨の道でした。環境変数LD_LIBRARY_PATHさえ設定してやれば動くことはわかっているのですが、bashの設定がapacheのプロセスに引き継がれるわけもなく、.htaccessでmod_rewriteやmod_envを使って環境変数の書き換えを行おうとしてもうまくいかず(多分権限がない)、perlのスクリプト上でBEGIN節に環境変数の設定を書き加えても、タイミングが遅いので意味はありませんでした。バインディングを捨てて、自前でmecabの出力をparseしようかどうしようか、いろいろ悩んだ結果、最終的に子プロセスに投げるという方法で解決することにしました。

$ENV{LD_LIBRARY_PATH} = '/home/ACCOUNT-NAME/bin/mecab/lib';
system 'perl child.pl';

環境変数を書き換えた上でsystemコマンドでもなんでも子プロセスを呼べば、環境変数が親から引き継がれた状態で実行されるのでした。無駄に複雑になった気もしますが、動くには動きました。もっといい方法があれば知りたいです。

2018/6/13

cssのtransitionが設定通りに動いたり、動かなかったりした話。PC用のサイトで複数の画像を並べるページがありまして、最大5列、ウィンドウ幅に応じて列数が増減するというような内容でした。画像は条件を指定すると、AJAXで条件に応じた画像群を別途取得して、それに差し替え表示するような仕組みがついていました。画像を差し替える際に、画像の位置や増減を表現するためにtop,left,opacity,transformあたりのプロパティをアニメーションさせるように設定してあります。画像が3列や4列のときは意図した動作をするのですが、画像が5列のときだけはなぜかアニメーションが行われず、即時に各プロパティ値が書き換わってしまっているように見えました。

最初はウィンドウ幅毎に処理を変えている部分を疑ってみたのですが、どうもそれは関係なさそうでした。いろいろ試したあげく、アニメーション用の値を設定する前に0.1秒とか短時間、ディレイをつけると意図したアニメーションを確認できるようになりました。これはどうやらAJAXで画像情報を取得した後にそれをDOMに反映させた直後にはtransitionが効かないんじゃないかなって思いました。DOMに追加前のDocumentFragment状態でプロパティ値を変更して、それをDOMに加えてもtransitionによるアニメーションが起こらないことはわかっていたのですが、DOMに追加直後もアニメーションが行えるようになるまでタイムラグがあるのではないかと。

そのタイムラグがあるとして、アニメーションの準備が完了するタイミングを知る方法がわからないので、ちょっぴりディレイするしかないかなって思っていたのですが、今回の件では、アニメーションを発生させる前に画像の読み込みを完了させておく必要があったので、読み込みを待つ処理を追加したら、アニメーションもちゃんと起こるようになって、これでよしとなりました。

2018/3/22

perlのお話。トランザクションのあるデータベース(MyDQLのInnoDB)のハンドラを持っているDBという名前のクラスを作りました。そしてexitが呼ばれて処理が終了し、DBクラスのインスタンスが破棄されるタイミングでデータベース操作をcommitしようとしていました。破棄されるタイミングなので、

sub DESTROY {
# DESTROYの最初の引数には破棄されるインスタンスが渡されるらしい
$_[0]->{dbhandle}->commit();
}

↑こんな感じでいけるのかなと書いたのですが、いざ動かすとデータベースには変更が反映されませんでした。どうもDESTROYが呼ばれる時点でハンドラは既に消えてしまっている模様。
DBIクラス側できっと先に消し込んでいるのでしょう。データベースに接続(connect)する際に何かよいパラメーターを渡すと消されないのかなと思いつつ、都合のよさそうなパラメーターを見つけることができなかったので、

END {
$_->{dbhandle}->commit() foreach (@instanceCollection);
}

DBクラスのインスタンスのコレクションを持っていたので、exitの直前に呼ばれるENDの中で一つずつcommitするように書いたらうまくいきました。これまで意識する必要がなかったけど、ENDが先に呼ばれるんだぁって順番を覚えました。

Last-Modified