import numpy as np
import math
from vispy import app, gloo, visuals
from vispy.visuals.transforms import STTransform
# Number of displayed lines
x_size = 50
# window size
canvas_size = (800, 600)
# launch app
app.Application(backend_name='PyQt5')
# define texture
tex = np.c_[(np.ones(shape=(1, x_size, 1)),np.zeros(shape=(1, x_size, 1)),np.zeros(shape=(1, x_size, 1)),np.random.uniform(size=(1, x_size, 1)))]
class Canvas(app.Canvas):
def __init__(self):
# housekeeping
app.Canvas.__init__(self, title='Use your wheel to zoom!', keys='interactive', vsync=True, autoswap=True)
gloo.set_viewport(0, 0, *self.physical_size)
# translate to full screen
self.heatmap = visuals.ImageVisual(data=tex, method='subdivide',interpolation='nearest')
s = (1 / (self.size[0]*self.heatmap.size[0] / (self.size[0]*2)), 100)
self.heatmap.transform = STTransform(scale=s, translate=(-1,-1))
self.scale = (1., 1.)
self.zoom_pos = 0.0
# track time
self._timer = app.Timer('auto', connect=self.on_timer, start=True)
# housekeeping
gloo.set_state(clear_color='black', blend=True, blend_func=('src_alpha', 'one_minus_src_alpha'))
self.show()
def on_mouse_wheel(self, event):
print(event.pos) #800, 600
dx = np.sign(event.delta[1]) * 0.05
scale_x, scale_y = self.scale
scale_x_new, scale_y_new = (
scale_x * math.exp(1.0 * dx),
scale_y * math.exp(1.0 * dx)
)
self.scale = (max(1, scale_x_new), max(1, scale_y_new))
# ????????????????????????????? #
# How to update this correctly? #
# ????????????????????????????? #
self.zoom_pos = self._normalize(event.pos)[0]
def on_resize(self, event):
vp = (0, 0, event.physical_size[0], event.physical_size[1])
self.context.set_viewport(*vp)
def on_timer(self, event):
scale_x, scale_y = self.scale
s = (scale_x / (self.size[0] * self.heatmap.size[0] / (self.size[0] * 2)), 100)
self.heatmap.transform = STTransform(scale=s, translate=(self.zoom_pos, -1))*STTransform(scale=None, translate=(-(self.zoom_pos + 1) / 2 * x_size,0))
self.update()
def on_draw(self, event):
gloo.clear(color='black', depth=True)
self.heatmap.draw()
def _normalize(self, x_y):
x, y = x_y
w, h = float(self.size[0]), float(self.size[1])
return x / (w / 2.) - 1., y / (h / 2.) - 1.
if __name__ == '__main__':
c = Canvas()
app.run()