separated some of the canvas-specific logic