code: def on_mouse_move(self, event):
      if event.is_dragging and not event.modifiers:
          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._pz.pan
          zoom_x, zoom_y = self._pz.zoom
  
          if button == 1:
              self._pz.pan = (pan_x + dx / zoom_x, pan_y + dy / zoom_y)
          elif button == 2:
              zoom_x_new, zoom_y_new = (
                  zoom_x * math.exp(2.5 * dx),
                  zoom_y * math.exp(2.5 * dy),
              )
              self._pz.zoom = (zoom_x_new, zoom_y_new)
              self._pz.pan = (
                  pan_x - x0 * (1.0 / zoom_x - 1.0 / zoom_x_new),
                  pan_y + y0 * (1.0 / zoom_y - 1.0 / zoom_y_new),
              )
          self.update()
  
imports: import numpy
  import math
  from vispy import gloo, app, scene
  from vispy.visuals import Visual
  from vispy.visuals.shaders import Function, Variable
  from vispy.visuals.transforms import TransformSystem, BaseTransform
  from vispy.util.profiler import Profiler
label_desc: Use image node_id 5 for calling the PanZoomCanvas obj's underlying member method code with example usage: obj.on_mouse_move(event) without return types