QML(Qt)でパラパラ漫画をする

セル絵のアニメーション的なやつを実装してみます。

ちょっと入用だったのでどうやって実装するかなーと考えてて、この方法が無難じゃないか的な話ももらったので紹介します。

/// ポイント ///
・Repeaterを使って画像をあらかじめ読み込んでおく
・配置はRowを使って画面の表示エリアを超えて並べておく
・表示するフレームはRowのx座標で調節
・画像が全部ロードできたら上位へのお知らせシグナルも用意(今後のため

補足
・画面をクリックすると再生と停止をトグル
・画像は適当に用意してください
 最後のonCompletedで読み込んでます


/// 画像とウインドウの位置関係 ///
こんな感じに配置しておいてタイマーでx座標を移動させればパラパラ漫画になると。
こおやってみるとなんか映画のフィルムみたいな感じ。Columnにしとくべきだったか(笑
 


/// サンプル ///
import QtQuick 1.1

Rectangle {
    id: _root
    width: 720 * 0.5
    height: 1280 * 0.5

    property variant path: []    //ファイルのリストを指定する

    property int loadedCount: 0 //ロードした枚数を数える
    property int pictCount: 0   //画像の枚数

    signal loaded()             //これで上位に対してお知らせ

    //再生
    function start(){
        if(_timer.running === true){
            _timer.restart();
        }else{
            _timer.start();
        }
    }
    //停止
    function stop(){
        _timer.stop();
        _area.x = 0;
    }

    onPathChanged: {
        //消す
        _bootanimation.model.clear();
        //内容を登録
        loadedCount = 0;
        pictCount = path.length;
        for(var i=0; i<path.length; i++){
            _bootanimation.model.append({"_item": path[i]});
        }
    }
    onLoadedCountChanged: {
        if(loadedCount >= pictCount){
            //ロード完了
            loaded();
        }
    }

    Row{
        id: _area
        x:0
        y:0
        //繰り返し配置
        Repeater{
            id: _bootanimation
            model:ListModel{}
            画像を繰り返す
            Image{
                source: _item
                width: _root.width
                height: _root.height
                smooth: true
                fillMode: Image.PreserveAspectFit
                onStatusChanged: {
                    //ロード完了したら済みカウントを数える
                    if(status === Image.Ready){
                        loadedCount++;
                    }
                }
            }
        }
    }
    Timer{
        id: _timer
        running: false
        interval: 33        //大体30fps
        repeat: true
        onTriggered:{
            //位置を調節
            if((_area.x - _root.width + _area.width) <= 0){
                _area.x = 0;
            }else{
                _area.x -= _root.width;
            }
        }
    }

    Component.onCompleted: {
        //画像を登録
        var temp = [];
        for(var i=0; i<76; i++){
            if(i<10){
                temp.push("part0/f000" + i + ".jpg");
            }else{
                temp.push("part0/f00" + i + ".jpg");
            }
        }
        path = temp;
    }

    MouseArea {
        anchors.fill: parent
        onClicked: {
            //クリックしたら再生と停止
            if(_timer.running === true){
                _root.stop();
            }else{
                _root.start();
            }
        }
    }
}