Displaying sprites on the Canvas

In [ ]:
from random import choice, randint, uniform
from math import pi

from PIL import Image as PILImage

import numpy as np

from ipywidgets import Image

from ipycanvas import Canvas, hold_canvas

Drawing a sprite from an Image widget

In [ ]:
sprite1 = Image.from_file('sprites/smoke_texture0.png')
sprite2 = Image.from_file('sprites/smoke_texture1.png')

canvas1 = Canvas(width=300, height=300)
canvas1.fill_style = '#a9cafc'
canvas1.fill_rect(0, 0, 300, 300)
canvas1.draw_image(sprite1, 50, 50)

canvas1
In [ ]:
canvas1.draw_image(sprite2, 100, 100)

Drawing from another Canvas

In [ ]:
canvas2 = Canvas(width=600, height=300)
canvas2.draw_image(canvas1, 0, 0)

canvas2
In [ ]:
canvas2.draw_image(canvas1, 300, 0)

Drawing from a NumPy array

In [ ]:
sprite3 = np.array(PILImage.open('sprites/smoke_texture2.png'))
In [ ]:
canvas2.put_image_data(sprite3, 250, 150)

Drawing thousands of sprites, the more optimized solution is to first "cache" your images in other Canvas instances

In [ ]:
# The fastest solution is drawing from another canvas
canvas_sprite1 = Canvas(width=100, height=100)
canvas_sprite1.draw_image(sprite1, 0, 0)
canvas_sprite1
In [ ]:
canvas_sprite2 = Canvas(width=100, height=100)
canvas_sprite2.draw_image(sprite2, 0, 0)
canvas_sprite2
In [ ]:
canvas_sprite3 = Canvas(width=100, height=100)
canvas_sprite3.draw_image(Image.from_file('sprites/smoke_texture2.png'), 0, 0)
canvas_sprite3
In [ ]:
canvas3 = Canvas(width=800, height=600)

sprites = [canvas_sprite1, canvas_sprite2, canvas_sprite3]

with hold_canvas(canvas3):
    for _ in range(2_000):
        canvas3.save()

        # Choose a random sprite texture
        sprite = sprites[choice(range(3))]

        # Choose a random sprite position
        pos_x = randint(0, canvas3.size[0] - 50)
        pos_y = randint(0, canvas3.size[1] - 50)

        # Choose a random rotation angle (but first set the rotation center with `translate`)
        canvas3.translate(pos_x, pos_y)
        canvas3.rotate(uniform(0., pi))

        # Choose a random sprite size
        scale = uniform(0.2, 1.)
        canvas3.scale(scale)

        # Restore the canvas center
        canvas3.translate(- pos_x, - pos_y)

        # Draw the sprite
        canvas3.draw_image(sprite, pos_x, pos_y)

        canvas3.restore()

canvas3
In [ ]: