This is the 15th day of my participation in the First Challenge 2022

Hi, I’m the watermelon guy. Today we will learn to use Canvas technology to achieve a picture viewer to master a knowledge point.

If we need to load and display a photo in a container of a specific size, how can we display the image by default?

contain

Contain, contain, contain, contain, contain, contain

The advantage is that you can see the whole image at once, while the disadvantage is that you can’t fill the entire container, thus creating “black edges.”

Here we assume that the canvas is 400 x 200 wide and the image is 80 x 80 high.

Take a look at the template code for the example.

const canvas = document.querySelector('canvas');
canvas.width = 400;
canvas.height = 200;
const ctx = canvas.getContext('2d');

ctx.fillRect(0.0, canvas.width, canvas.height); // Fill the background with black

const img = new Image();
img.src = './watermelon.jpg'; // The image size is 80x80
img.onload = showImg;

function showImg() {
  // contain the folder
  const scale = calcContainScale(img.width, img.height, canvas.width, canvas.height);
  const w = img.width * scale; // The width of the image after scaling
  const h = img.height * scale; // The height of the image after scaling
  const {x, y} = calcPos(w, h, canvas.width, canvas.height) // Center the image
  ctx.drawImage(img, x, y, w, h);
}

// Calculate the x, y required to center the image
function calcPos(w, h, cw, ch) {
  return {
    x: (cw - w) / 2.y: (ch - h) / 2
  };
}

Copy the code

Our calcContainScale() method is implemented as:

/** * contain mode *@param {number} W Picture width *@param {number} H Image height *@param {number} Cw container width *@param {number} Ch container height *@returns {number} Zoom ratio * /
function calcContainScale(w, h, cw, ch) {
  const scaleW = cw / w;
  const scaleH = ch / h;
  const scale = Math.min(scaleW, scaleH); / / of little value
  return scale;
}
Copy the code

The algorithm is simple: figure out how much you need to scale the image to the size of the container, and then take the smaller of the two.

The reason is simple, if you take a large one, it will inevitably result in another one that is longer than the container size, and the image will not fit.

cover

Cover, the image maintains an aspect ratio and fills the container as much as possible. Either the width of the image is scaled to the width of the container, or the height of the image is scaled to the width of the container, and then the excess content is truncated.

The advantage is that you can fill all of the container with the smallest zoom ratio. The disadvantage is that you can’t show all of the image.

function calcCoverScale(w, h, cw, ch) {
  const scaleW = cw / w;
  const scaleH = ch / h;
  const scale = Math.max(scaleW, scaleH); / / of great value
  return scale;
}
Copy the code

Contrary to contain, scale the size of the image to the size of the container and contain the largest value.

Because we want to fill the container as much as possible, if the other edge goes out of the container, we cut it off.

fill

Fill, the image completely fills the container, does not require to maintain the aspect ratio, the image can be stretched.

Very rarely used as it will stretch the image and make it very ugly.

In practice, just set the width and height of the image to the width and height of the container, and no calculation is required.

ctx.drawImage(img, 0.0, canvas.width, canvas.height);
Copy the code

none

None, the image remains the original size and is displayed unzoomed.

ctx.drawImage(img, x, y, img.width, img.height);
Copy the code

scale-down

Scale-down, include a small image and none.

The hope is that images smaller than the container will remain in full scale and not be magnified and distorted.

function calcScaleDownScale(w, h, cw, ch) {
  const scaleW = cw / w;
  const scaleH = ch / h;
  const scale = Math.min(scaleW, scaleH, 1); // The ratio cannot be less than 1
  return scale;
}
Copy the code

The image size is much smaller than the container, so none is selected.

conclusion

Let me summarize these 5 ways images can fill containers:

  1. Contain: no more, no less
  2. Cover: Fill a container, but keep the size small;
  3. Fill: directly stretch the filling container without maintaining the width to height ratio;
  4. None: Keep the image as it was originally;
  5. Scale-down: if it can be put into the container without enlarging, put it directly (none); If it can’t contain, enlarge it so that it just contains it.