1 回答

TA貢獻1815條經(jīng)驗 獲得超10個贊
找到了在不添加散點小部件的情況下實現(xiàn)捏合縮放的方法,因為散點不會更新數(shù)據(jù)的寬度和高度,因此滾動尺寸也不會更新。下面是沒有分散的實現(xiàn)??s放適用于觸摸錨點。這并不理想,因為動畫不流暢。
from kivy.app import App
from kivy.uix.image import Image
from kivy.uix.recycleview import RecycleView
from kivy.core.window import Window
from kivy.uix.floatlayout import FloatLayout
from kivy.lang import Builder
from kivy.metrics import sp, dp
from kivy.animation import Animation
from kivy.uix.widget import Widget
from PIL import Image as PILImage
from kivy.properties import NumericProperty
from kivy.graphics.transformation import Matrix
from kivy.vector import Vector
from kivy.graphics.context_instructions import PopMatrix, PushMatrix, Translate
MY_APP_KV_LANG = """
#:import ScrollEffect kivy.effects.scroll.ScrollEffect
<RootLayout>:
size_hint: 1, 1
canvas.before:
Color:
rgba: (0, 0, 0, 1)
Rectangle:
size: self.size
pos: self.pos
DocumentWidget:
id: rv
viewclass: 'Image'
key_size: 'size'
effect_cls: ScrollEffect
scroll_type: ['content']
bar_width: 0
cols: 1
RecycleBoxLayout:
id: rvbox
spacing: dp(10)
padding: dp(10)
cols: rv.cols
orientation: 'vertical'
size_hint: None, None
height: self.minimum_height
width: self.minimum_width
default_size_hint: 1, None
"""
class RootLayout(FloatLayout):
pass
class DocumentWidget(RecycleView):
scale = NumericProperty(1.)
scroll_y1 = NumericProperty(0.)
scroll_y2 = NumericProperty(0.)
delta_scy = NumericProperty(0.)
def __init__(self, **kwargs):
super(DocumentWidget, self).__init__(**kwargs)
pil_image = PILImage.open('test3.jpg')
self.data = [{'source': 'test3.jpg', 'width': Window.size[0] - dp(20), 'height': (Window.size[0] - dp(20)) * pil_image.size[1] / pil_image.size[0], 'size_hint_x': None, 'size_hint_y': None, 'allow_stretch': True, 'keep_ratio': True} for x in range(3)]
self.data_initial = [{'width': Window.size[0] - dp(20), 'height': (Window.size[0] - dp(20)) * pil_image.size[1] / pil_image.size[0]} for x in range(3)]
self.bind(on_scale = self.on_scale)
def on_touch_up(self, touch):
if self.collide_point(*touch.pos):
if touch.is_double_tap:
if 1.0 >= self.scale >= 0.99:
self.scroll_y1 = self.scroll_y
self.delta_scy = Window.size[1] - touch.pos[1] - dp(10)
def _prg(*args):
self.scroll_x = (touch.pos[0] * self.scale) / (self.data[0]["width"] + dp(20))
self.scroll_y = self.scroll_y1 - self.scroll_y1 * self.delta_scy * (self.scale - 1) / (self.layout_manager.size[1] - Window.size[1])
self.scroll_y2 = self.scroll_y
anim = Animation(scale=2, duration=0.2, transition='in_quad')
anim.bind(on_progress=_prg)
anim.start(self)
else:
def _prg(*args):
self.scroll_y = (self.scroll_y2 - self.scroll_y1) * self.scale + 2 * self.scroll_y1 - self.scroll_y2
anim = Animation(scale=1, duration=0.2, transition='out_quad')
anim.bind(on_progress=_prg)
anim.start(self)
return super(DocumentWidget, self).on_touch_up(touch)
def on_scale(self, *args):
for x in range(3):
self.data[x]["height"] = self.data_initial[x]["height"] * self.scale
self.data[x]["width"] = self.data_initial[x]["width"] * self.scale
self.refresh_from_data()
class MyApp(App):
def build(self):
self.root = Builder.load_string(MY_APP_KV_LANG)
return RootLayout()
if __name__ == "__main__":
MyApp().run()
添加回答
舉報