public void zoomView(float factor) {
    float newScaling;

    if (scalingInterpolator.isActive()) {
      newScaling = scalingInterpolator.getEndValue() * factor;
    } else {
      newScaling = currentScaling * factor;
    }

    scalingInterpolator.setStartEndValues(currentScaling, newScaling);
    scalingInterpolator.startInterpolating();
  }
  public void translateView(float transX, float transY) {
    float newTransX;
    float newTransY;

    if (transX != 0.0f) {
      if (translationXInterpolator.isActive()) {
        newTransX = translationXInterpolator.getEndValue() + transX;
      } else {
        newTransX = currentTranslation[0] + transX;
      }
      translationXInterpolator.setStartEndValues(currentTranslation[0], newTransX);
      translationXInterpolator.startInterpolating();
    }

    if (transY != 0.0f) {
      if (translationYInterpolator.isActive()) {
        newTransY = translationYInterpolator.getEndValue() + transY;
      } else {
        newTransY = currentTranslation[1] + transY;
      }
      translationYInterpolator.setStartEndValues(currentTranslation[1], newTransY);
      translationYInterpolator.startInterpolating();
    }
  }
  @Override
  public void onDraw(Canvas canvas) {
    // zooming animation
    if (scalingInterpolator.isActive()) {
      setCurrentScaling(scalingInterpolator.getCurrentValue());
    }

    // translation animation
    if (translationXInterpolator.isActive() || translationYInterpolator.isActive()) {
      float transX = currentTranslation[0];
      float transY = currentTranslation[1];
      if (translationXInterpolator.isActive()) {
        transX = translationXInterpolator.getCurrentValue();
      }
      if (translationYInterpolator.isActive()) {
        transY = translationYInterpolator.getCurrentValue();
      }
      setCurrentTranslation(transX, transY);
    }

    // center rotation animation
    if (centerRotationInterpolator.isActive()) {
      setCurrentCenterRotation(centerRotationInterpolator.getCurrentValue());
    }

    // calculate current viewport matrix if necessary
    if (getAndClearViewportFlag()) {
      recalculateViewportTransformation();
      recalculateSizeScale();
    }

    // clear background
    canvas.drawColor(0xFF000000);

    // draw audio scene
    canvas.setMatrix(viewportTransformation);
    synchronized (GlobalData.audioScene) {
      GlobalData.audioScene.draw(canvas, currentInverseScaling);
    }

    // reset matrix
    canvas.setMatrix(null);

    // draw size scale
    sizeScalePicture.draw(canvas);
  }