🐈‍⬛

Python + Kivy で作ってみた【Ⅶ】

2023/07/07に公開

ズーム機能

フッター部分にスライダーコントロールを設置しズーミングを行う
ズーミングの中心点は、ゲージ線のボックス部分の中心とする

ズーム率

kvファイルにおいて、FooterWidgetにスライダーコントロールを追加する

FooterWidget:
    FloatLayout:
        pos:            self.parent.pos
        size:           self.parent.size

        Slider:
            canvas.before:
                Color:
                    rgba:           0.9, 0.9, 0.9, 1

                Rectangle:
                    pos:            self.pos
                    size:           self.size

            id:                 view_size
            max:                5
            min:                0.1
            step:               0.1
            value:              1
            value_track:        True
            value_track_color:  [ 1, 0, 0.8, 1 ]
            value_track_height: 20
            cursor_size:        20, 20
            orientation:        "horizontal"
            size:               self.parent.width * 0.4, self.parent.height
            size_hint:          None, None
            pos:                self.parent.x + self.parent.width * 0.5, self.parent.y
            on_value:           viewer.image_resize( self.value )

ズーム率は0.1 ~ 5とし、0.1刻みで指定できるようにした
デフォルトではカーソルが大きすぎるので、小ぶりに設定した

ズーミング

ViewAreaWidgetクラスにimage_resizeメソッドを追加し、
スライダーコントロールのカーソルを移動した時に呼び出す

class ViewAreaBase( Widget ) :
    ...
    ...
    ...
    def image_resize( self, ratio ) :
        root_ids    = self.parent.parent.ids

        scope   = root_ids[ Gauges.Scope.f_name ]

        pin_x   = scope.x + scope.width / 2
        pin_y   = scope.y + scope.height / 2

        delta_x = self.image_texture.width * ratio / self.image_width
        delta_y = self.image_texture.height * ratio / self.image_height

        self.image_x        *= delta_x
        self.image_x        += pin_x * ( 1 - delta_x )

        self.image_y        *= delta_y
        self.image_y        += pin_y * ( 1 - delta_y )

        self.image_width    *= delta_x
        self.image_height   *= delta_y

まず、ゲージ線のボックス部分の中心を求めるために
ゲージ線のボックス部分のGaugeWidgetのインスタンスを拾う

ViewAreaWidgetはルートWidget(CtrlPanelWidget)のFloatLayoutにぶら下がっている
ゆえに、親の親に有効なidsプロパティがある
(本質的には、順次親を遡ってidsプロパティが有効かどうか判別するべきかも…)

辞書型のidsプロパティにGauges.Scope.f_nameを指定すると
ゲージ線のボックス部分のGaugeWidgetのインスタンスが求められる

引数のratioにスライダーコントロールのValue値が渡されているので、
ratioを使ってズーミング後のPDF画像の大きさを求める

ゲージ線のボックス部分をズーミングの中心点となるように
ズーミング後のPDF画像の位置を求める

これで、ズーム機能が実装が終わり
簡易的なPDFビューワーアプリとしてまとまった∩(´∀`)∩
PDFビューワーアプリ

やってみたいネタはあるので、まとまったら記事にしていきたい

Discussion