返回
图像不变形缩放显示的meetOrSlice算法详解
前端
2023-09-03 14:07:37
1. SVG中的viewport, viewBox和preserveAspectRatio
1.1 SVG中的viewport
SVG中的viewport是指SVG图像的显示区域,它是一个矩形区域,可以通过
1.2 SVG中的viewBox
SVG中的viewBox是指SVG图像的实际大小,它是一个矩形区域,可以通过
1.3 SVG中的preserveAspectRatio
SVG中的preserveAspectRatio属性是指SVG图像的缩放方式,它可以通过
- none :不缩放图像。
- meet :将图像缩放至刚好填满viewport,但不裁剪图像。
- slice :将图像缩放至刚好填满viewport,并裁剪图像。
- xMinYMin :将图像缩放至刚好填满viewport,但图像的最小x坐标和最小y坐标必须与viewport的最小x坐标和最小y坐标对齐。
- xMidYMin :将图像缩放至刚好填满viewport,但图像的中间x坐标和最小y坐标必须与viewport的中间x坐标和最小y坐标对齐。
- xMaxYMin :将图像缩放至刚好填满viewport,但图像的最大x坐标和最小y坐标必须与viewport的最大x坐标和最小y坐标对齐。
- xMinYMid :将图像缩放至刚好填满viewport,但图像的最小x坐标和中间y坐标必须与viewport的最小x坐标和中间y坐标对齐。
- xMidYMid :将图像缩放至刚好填满viewport,但图像的中间x坐标和中间y坐标必须与viewport的中间x坐标和中间y坐标对齐。
- xMaxYMid :将图像缩放至刚好填满viewport,但图像的最大x坐标和中间y坐标必须与viewport的最大x坐标和中间y坐标对齐。
- xMinYMax :将图像缩放至刚好填满viewport,但图像的最小x坐标和最大y坐标必须与viewport的最小x坐标和最大y坐标对齐。
- xMidYMax :将图像缩放至刚好填满viewport,但图像的中间x坐标和最大y坐标必须与viewport的中间x坐标和最大y坐标对齐。
- xMaxYMax :将图像缩放至刚好填满viewport,但图像的最大x坐标和最大y坐标必须与viewport的最大x坐标和最大y坐标对齐。
2. preserveAspectRatio中meetOrSlice算法
在preserveAspectRatio属性中,meetOrSlice算法是将图像缩放至刚好填满viewport,但不会裁剪图像。如果图像的宽高比与viewport的宽高比不同,则图像将被拉伸或压缩以适应viewport。
meetOrSlice算法的实现步骤如下:
- 计算图像的宽高比和viewport的宽高比。
- 如果图像的宽高比大于viewport的宽高比,则将图像的宽度缩放至viewport的宽度,并保持图像的高度不变。
- 如果图像的宽高比小于viewport的宽高比,则将图像的高度缩放至viewport的高度,并保持图像的宽度不变。
- 将图像平移至viewport的中心。
3. 代码实现
function meetOrSlice(svg, viewport, viewBox) {
// 计算图像的宽高比和viewport的宽高比。
const imageAspectRatio = viewBox.width / viewBox.height;
const viewportAspectRatio = viewport.width / viewport.height;
// 如果图像的宽高比大于viewport的宽高比,则将图像的宽度缩放至viewport的宽度,并保持图像的高度不变。
if (imageAspectRatio > viewportAspectRatio) {
const scale = viewport.width / viewBox.width;
svg.setAttribute("width", viewport.width);
svg.setAttribute("height", viewBox.height * scale);
}
// 如果图像的宽高比小于viewport的宽高比,则将图像的高度缩放至viewport的高度,并保持图像的宽度不变。
else {
const scale = viewport.height / viewBox.height;
svg.setAttribute("width", viewBox.width * scale);
svg.setAttribute("height", viewport.height);
}
// 将图像平移至viewport的中心。
svg.setAttribute("transform", "translate(" + (viewport.width - svg.width) / 2 + "," + (viewport.height - svg.height) / 2 + ")");
}