JavaScript How to bound image pan when zooming (HTML Canvas)

I'm trying to limit boundaries and I'm running into issues. I'm upscaling an image from another canvas and then implementing zoom and pan. My issue (code below) is with limiting/capping the offsetx/y so that you never see the whitespace; only parts of the image.

Pardon the mess! Any help is appreciated! :P

var zoomIntensity = 0.2;

var canvas = document.getElementById("canvas");
var canvas2 = document.getElementById("canvas2");
var context = canvas.getContext("2d");
var context2 = canvas2.getContext("2d");
var width = 200;
var height = 200;

var scale = 1;
var originx = 0;
var originy = 0;

var offset = {x:0, y:0};

//fill smaller canvas with random pixels
for(var x = 0; x < 100; x++)
for(var y = 0; y < 100; y++)
{
  var rando = function(){return Math.floor(Math.random() * 9)};
  var val = rando();
  context2.fillStyle = "#" + val + val + val;
  context2.fillRect(x,y,1,1);
}

//draw the larger canvas
function draw()
{
		context.imageSmoothingEnabled = false;
    
    // Clear screen to white.
    context.fillStyle = "white";
    context.fillRect(originx - offset.x, originy - offset.y, width/scale, height/scale);
		context.drawImage(canvas2, 0,0, width, height);
}

// Draw loop at 60FPS.
setInterval(draw, 1000/60);

canvas.onmousewheel = function (event){
    event.preventDefault();
    
    // Get mouse offset.
    var mousex = event.clientX - canvas.offsetLeft;
    var mousey = event.clientY - canvas.offsetTop;
    
    // Normalize wheel to +1 or -1.
    var wheel = event.wheelDelta/120;

    // Compute zoom factor.
    var zoom = Math.exp(wheel*zoomIntensity);
    
    // Translate so the visible origin is at the context's origin.
    context.translate(originx - offset.x, originy - offset.y); //offset is panning
    
    //make sure we don't zoom out further than normal scale
    var resultingScale = scale * zoom;
    if(resultingScale < 1)
    	zoom = 1/scale;
  
    // Compute the new visible origin. Originally the mouse is at a
    // distance mouse/scale from the corner, we want the point under
    // the mouse to remain in the same place after the zoom, but this
    // is at mouse/new_scale away from the corner. Therefore we need to
    // shift the origin (coordinates of the corner) to account for this.
    originx -= mousex/(scale*zoom) - mousex/scale;
    originy -= mousey/(scale*zoom) - mousey/scale;
    
    // Scale it (centered around the origin due to the trasnslate above).
    context.scale(zoom, zoom);
    
    // Offset the visible origin to it's proper position.
    context.translate(-originx + offset.x, -originy + offset.y); //offset is panning

    // Update scale and others.
    scale *= zoom;
}

document.onkeydown = function (evt)
{
	var offsetx = 0;
  var offsety = 0;
  
	switch(evt.which)
	{
      case 37: //left
        offsetx = 1;
        break;
      case 38: //up
        offsety = 1;
        break;
      case 39: //right
        offsetx = -1
        break;
      case 40: //down
        offsety = -1;
        break;
  }
  
  offsetx /= scale;
  offsety /= scale;
  
  offset.x += offsetx;
  offset.y += offsety;
  
 	context.translate(offsetx,offsety);
}
<canvas id="canvas" width="200" height="200"></canvas>
<canvas id="canvas2" width="100" height="100"></canvas>
Answer:1

Within an ng-repeat block I have textboxes. To detect when the content differs from the original, the original data is stored in a variable. <tr data-ng-repeat="p in products"> <td> ...

Within an ng-repeat block I have textboxes. To detect when the content differs from the original, the original data is stored in a variable. <tr data-ng-repeat="p in products"> <td> ...

  1. angular best practice file structure
  2. angular best practice error handling
  3. angular best practice
  4. angular best practice structure
  5. angular best practice folder structure
  6. angular best practices guidelines for project structure
  7. angular best practice service
  8. angular best practice for app structure (public)
  9. angular best practice modules
  10. angular best practice interface
  11. angular best practice documentation
  12. angular best practice routing
  13. angular best practices directory structure
  14. angular best practice crud
  15. angular best practice medium
  16. angular best practices 2019
  17. angular best practices 2018
  18. angular best practices github
  19. angular best practices architecture
  20. angular best practices pdf

I tried document.links and document.anchors in the dev console on a page, and there were 162 links but 255 anchors. However, they are all <a> elements. Up until now, I thought that links and ...

I tried document.links and document.anchors in the dev console on a page, and there were 162 links but 255 anchors. However, they are all <a> elements. Up until now, I thought that links and ...

  1. what is a national emergency
  2. whatsapp
  3. whataburger
  4. what time is it
  5. what is my ip
  6. what song is this
  7. what is a state of emergency
  8. what is a dry cough
  9. what happens in a national emergency
  10. what is the stafford act
  11. what is a bear market
  12. what does ���� mean
  13. what to watch
  14. what stocks to buy today
  15. whataburger menu
  16. what is the weather
  17. what is rsv
  18. what is gluten
  19. what is pv
  20. what is a boomer

I have a plot with many svg rects in my block. Most I were able to plot and fill just fine, however the initial rect is not blue like it is in my color map: var colorMap = { 0: "blue", 1: "red", ...

I have a plot with many svg rects in my block. Most I were able to plot and fill just fine, however the initial rect is not blue like it is in my color map: var colorMap = { 0: "blue", 1: "red", ...

I'm having struggle accomplishing this : I want jQuery to grab class name of each icon and write it in each p element HTML <html> <head> <meta charset="utf-8"> <meta ...

I'm having struggle accomplishing this : I want jQuery to grab class name of each icon and write it in each p element HTML <html> <head> <meta charset="utf-8"> <meta ...

  1. set attribute value jquery
  2. set attribute value javascript
  3. set attribute value
  4. set attribute value in lightning component
  5. set attribute value js
  6. set attribute value dynamically c#
  7. set attribute value in selenium
  8. set attribute value using jquery
  9. set attribute value selenium python
  10. set attribute value c#
  11. set attribute value in lightning controller
  12. set attribute value javascript selenium
  13. set attribute value input javascript
  14. set attribute value using javascript
  15. set attribute value typescript
  16. set attribute value selenium java
  17. set attribute value javascript dynamics crm
  18. set attribute value input jquery
  19. set attribute value in angular 6
  20. set attribute value in oaf