1、背景
在網頁展示圖片是一個很常見的需求,大多數情況下,展示區域的大小是固定的,原圖片的大小也是固定的
如果展示區域的寬高和原圖片的寬高不等比例,那么在默認情況下很可能會壓縮或拉伸圖片以適應區域大小
下面我們用兩張圖片做一個對比實驗,假設展示區域的寬高都是 300px
橫向圖片的寬高分別是 722px 和 88px,縱向圖片的寬高分別是 80px 和 525px
<!DOCTYPE html>
<html>
<head>
<style>
.image {
width: 300px;
height: 300px;
}
</style>
</head>
<body>
<img class="image" src="test.png">
</body>
</html>
2、設置 CSS
很顯然,這並不是我們想要的,因為它會導致圖片變形壓縮,我們需要找到一種辦法,能讓圖片等比例縮放
最簡單的方法莫過於設置 CSS,使得圖片可以自動適應展示區域的大小,代碼非常簡單
<!DOCTYPE html>
<html>
<head>
<style>
.image-box {
width: 300px;
height: 300px;
}
.image {
width: auto;
height: auto;
max-width: 100%;
max-height: 100%;
}
</style>
</head>
<body>
<div class="image-box">
<img class="image" src="test.png">
</div>
</body>
</html>
3、使用 canvas
設置 CSS 樣式之后,圖片會按照最小邊進行等比例縮放,這種解決辦法已經可以滿足大多數的使用場景
但有的時候我們會希望展示區域被占滿,魚和熊掌不可兼得,這時我們不得不裁剪圖片能夠等比例縮放的最大區域
實際上就是用一個與展示區域等比例的矩形截取圖片,並要求截取出來的圖片盡可能大且位於原圖片的中心位置
<!DOCTYPE html>
<html>
<head>
<script>
window.onload = function() {
let cvs = document.querySelector('#image')
let ctx = cvs.getContext('2d')
let img = new Image()
img.src = 'test.png'
img.onload = () => {
let adaptedImage = adaptImage(0, 0, img.width, img.height, 0, 0, cvs.width, cvs.height)
ctx.drawImage(img, ...adaptedImage)
}
}
function adaptImage(imgX, imgY, imgW, imgH, cvsX, cvsY, cvsW, cvsH) {
let idealW = imgW
let idealH = cvsH + (imgW - cvsW) * (cvsH / cvsW)
if (idealH <= imgH) {
return [0, imgH / 2 - idealH / 2, idealW, idealH, cvsX, cvsY, cvsW, cvsH]
} else {
idealH = imgH
idealW = cvsW + (imgH - cvsH) * (cvsW / cvsH)
return [imgW / 2 - idealW / 2, 0, idealW, idealH, cvsX, cvsY, cvsW, cvsH]
}
}
</script>
</head>
<body>
<canvas id="image" width="300" height="300">
</body>
</html>
【 閱讀更多 CSS 系列文章,請看 CSS學習筆記 】