code: def on_mouse_move(self, event):
      if event.is_dragging:
          x0, y0 = self._normalize(event.press_event.pos)
          x1, y1 = self._normalize(event.last_event.pos)
          x, y = self._normalize(event.pos)
          dx, dy = x - x1, -(y - y1)
          button = event.press_event.button
  
          pan_x, pan_y = self.program["u_pan"]
          scale_x, scale_y = self.program["u_scale"]
  
          if button == 1:
              self.program["u_pan"] = (
                  pan_x + dx / scale_x,
                  pan_y + dy / scale_y,
              )
          elif button == 2:
              scale_x_new, scale_y_new = (
                  scale_x * math.exp(2.5 * dx),
                  scale_y * math.exp(2.5 * dy),
              )
              self.program["u_scale"] = (scale_x_new, scale_y_new)
              self.program["u_pan"] = (
                  pan_x - x0 * (1.0 / scale_x - 1.0 / scale_x_new),
                  pan_y + y0 * (1.0 / scale_y - 1.0 / scale_y_new),
              )
          self.update()
  
file_path: vispy/examples/demo/gloo/signals.py
imports: from vispy import gloo
  from vispy import app
  import numpy
  import math
label_desc: Use image node_id 5 for calling the Canvas obj's underlying member method code with example usage: obj.on_mouse_move(event) without return types