Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions examples/transition_showcase.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,19 +45,19 @@ async def main(self):
async with t.gl_transitions_dot_com(label, fs=cross_warp):
label.text = 'iris'

await touch_down()
async with t.iris(duration=0.8, color=colormap['darkslategray']):
__, touch = await touch_down()
async with t.iris(color=colormap["darkslategray"], circle_center=touch.pos):
label.halign = 'center'
label.text = 'iris with a custom overlay'

await touch_down()
__, touch = await touch_down()
rect = Rectangle(size=Window.size, source='data/logo/kivy-icon-128.png')
texture = rect.texture
texture.wrap = 'repeat'
x_ratio = Window.width / texture.width
y_ratio = Window.height / texture.height
rect.tex_coords = (0, y_ratio, x_ratio, y_ratio, x_ratio, 0, 0, 0)
async with t.iris(overlay=rect, out_curve='linear', in_curve='linear'):
async with t.iris(overlay=rect, out_curve="linear", in_curve="linear", circle_center=touch.pos):
await ak.sleep(.3)
label.text = 'slide'
await ak.sleep(.3)
Expand Down
29 changes: 16 additions & 13 deletions src/asynckivy/transition.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,38 +131,41 @@ async def scale(target: Wow=Window, *, duration=1, out_curve='out_quad', in_curv
await anim_attrs(mat, d=half_d, t=in_curve, xyz=(1, 1, 1))


def _calc_enclosing_circle_radius(circle_center, rectangle_size, max=max, hypot=math.hypot, abs=abs):
def _calc_enclosing_circle_radius(circle_center, rect_pos, rect_size, max=max, hypot=math.hypot, abs=abs):
'''
Calculates the minimum radius required for a circle centered at the given position to fully
enclose a rectangle of the given size, assuming its bottom-left corner is at (0, 0).
enclose the rectangle defined by the given position and size.

.. code-block::

radius = _calc_enclosing_circle_radius(circle_center, rectangle_size)
radius = _calc_enclosing_circle_radius(circle_center, widget.pos, widget.size)
'''
w, h = rectangle_size
x, y = circle_center
return hypot(max(abs(x), abs(w - x)), max(abs(y), abs(h - y)))
cx, cy = circle_center
rx, ry = rect_pos
rw, rh = rect_size
return hypot(max(abs(cx - rx), abs(rx + rw - cx)), max(abs(cy - ry), abs(ry + rh - cy)))


@asynccontextmanager
async def iris(target: WindowBase=Window, *, duration=1, out_curve='in_cubic', in_curve='out_cubic',
async def iris(target: Wow=Window, *, duration=1, out_curve='in_cubic', in_curve='out_cubic',
color: Sequence[float]=colormap['white'], circle_center: Sequence[float]=None,
overlay: VertexInstruction=None):
'''
縮む円によって ``target`` が見える範囲を絞っていき、完全に見えなくなったらwithブロック内を実行し、その後円を広げて ``target`` を再び見せる。
Narrows the visible area of ``target`` with a shrinking circle, runs the code inside the with-block
once it becomes completely invisible, and then expands the circle to make ``target`` visible again.

.. versionadded:: 0.9.0
.. versionchanged:: 0.11.1
Added support for widget as target.
'''
if not isinstance(target, WindowBase):
raise TypeError(f"'target' must be a WindowBase instance, not {type(target).__name__}")
half_d = duration / 2
canvas = target.canvas
if circle_center is None:
circle_center = target.center
if overlay is None:
overlay = Rectangle(size=target.size)
radius = _calc_enclosing_circle_radius(circle_center, target.size)
target_pos = (0, 0) if isinstance(target, WindowBase) else target.pos
radius = _calc_enclosing_circle_radius(circle_center, target_pos, target.size)
diameter = radius * 2.
ellipse_start_pos = (circle_center[0] - radius, circle_center[1] - radius)
ellipse_start_size = (diameter, diameter)
Expand All @@ -180,7 +183,7 @@ async def iris(target: WindowBase=Window, *, duration=1, out_curve='in_cubic', i
ig_add(inner_ig)
ig_add(StencilPop())

canvas.add(ig)
canvas.after.add(ig)
try:
await anim_attrs(ellipse, d=half_d, t=out_curve, pos=circle_center, size=(0, 0))
# Setting the ellipse size to (0, 0) isn't enough to nullify the stencil effect for some reason,
Expand All @@ -190,7 +193,7 @@ async def iris(target: WindowBase=Window, *, duration=1, out_curve='in_cubic', i
inner_ig.add(ellipse)
await anim_attrs(ellipse, d=half_d, t=in_curve, pos=ellipse_start_pos, size=ellipse_start_size)
finally:
canvas.remove(ig)
canvas.after.remove(ig)


@asynccontextmanager
Expand Down