前言
平常,我们在查看图片的时候,都有放大缩小的功能。如下图👇
那么,我们如何在网页中,对图像进行缩放呢?
本文,我们来讲讲如何使用 JavaScript
实现图片的缩放。当然,我们可以类比到其他的元素,比如视频的缩放。
更改宽度
是的,很符合第一直觉逻辑的一种实现方式。电脑上查看相片也是使用的这种模式 - 直接保持外侧容器的框高不变,等比例地更改图片的尺寸。
我们来简单举个例子:
上面代码中,我们设定了外部容器的尺寸是 400 * 300 px
,内部的图像的宽度等同外部尺寸。当点击图片之后,图像的宽度变为 400 * 4 / 3 px
,外部的容器没有发生更改。
那么,我们这种直接更改宽度的方法,在全屏的模式下,生效?
也就是通过上面的代码进入到浏览器的全屏模式 gotoFullscreen(document.getElementsByClassName("container")[0])
。
然而,无论我们怎么设定图像的宽度,比如 document.getElementById("image").style.width = "200%"
,都不会生效的。
我们是否还有其他进行缩放的方法在全屏模式下也能够实现呢?
更改 Scale
我们可以保持图片的实际的宽高是不变的,然后更改其 scaleX
和 scaleY
来实现。
很明显,与 更改宽度
小节,唯一不同的点就是 imageDom.style.transform = scale(4/3, 4/3)
;,我们在点击图片的时候,使用 transform
属性值 scale(x, y)
对其 x
轴和 y
轴进行缩放。
而且,在全屏的模式下,该方法依旧能够实现对图片的缩放。因为图片的宽度不变。
取舍
两种方案:更改宽度
和 更改 Scale
。我们应该选择 更改 Scale
来对图像进行缩放。因为:
- 更改
Scale
涉及的场景比 更改宽度 要广 - 更改
Scale
性能比更改宽度性能优越。因为更改宽度是对dom
进行操作,会造成回流和重排,而更改Scale
是利用图形处理器(GPU)
来实现。感兴趣的读者可以看看这篇文章 从浏览器渲染原理谈动画性能优化
更改偏移位置
我们以方案二 - 更改 Scale
为基础。
当我们希望查看点击点的图片。我们需要对其进行放大,并将点击点放在外容器的中心点的位置。那么,我们就需要对图像的位置进行处理。
我们可以使用 position: absolute; top: *px; left: *px;
来实现,但是通过我们上面取舍小节的对比。我们有更好的替代方案 - 使用 translate(x, y) 来实现
。
这里我们使用 typescript
结合 angular
来实现:
对应的 javascript
如下:
上面的案例中,我们只是进行放大功能的展示。
引入鼠标滚轮
下面,我们通过引入鼠标滚动,修改下 amplifyVideoPortion
方法来对图像放大或缩小。
我们监听外部容器选中,滚轮滚动,当正向滚动的时候,我们对图片进行局部放大,当反向滚动的时候,我们对图片进行局部缩小。我们这里还引入了 rxjs
中的节流方法 throttleTime
来优化滚轮触发事件的时机。
对应的 amplifyImagePortion
方法我们更改如下👇
multipleStep
是放大的倍数,1 / multipleStep
是缩小的倍数。因为宽度变,我们需要对translate
的x
轴和y
轴的偏移进行合理计算,见上面两份代码。
扩展
当然,我们还可以图片缩放的功能进行扩展,比如,对图片进行区域的框选进行缩放;比如,另起一个 canvas
对图片进行绘制缩放等。