SVG多分辨率、自适应缩放解决方案

白昼怎懂夜的黑 提交于 2019-12-07 23:51:48

SVG格式本身就是矢量图形格式,可以随意缩放。但是如果如果整个画面都是通过SVG进行搭建,同一个SVG图形嵌入在HTML中,要同时满足多个分辨率屏幕的查看,还是需要进行一些额外的设置,包括JS动态设置width、height等。

用户在设计SVG图形的初期,先要确定该SVG图形的大致画面比例和查看方向,比如:该画面是在手机上查看还是Pad上查看还是pc上;还有,允许该画面只是上下滑动查看(对于高度远大于宽度的情况),还是画面只是左右滑动查看等。

确定了以上的信息,要设计一个可以在多分辨率屏幕下自适应的SVG画面,有以下几个步骤

1.在SVG根标签中添加 preserveAspectRatio="xMinYMin meet" 属性
     该属性指定SVG图形在屏幕的最左上角开始显示,并且保持等比缩放。

2.在SVG跟标签中添加 viewBox 属性
     该属性来设置SVG画布的大小,但该大小是一个相对的大小,并不是绝对尺寸大小。比如设定一个viewBox="0,0,800,3000",可以认为将画布大小的宽分为800份,高分为3000份,然后所有SVG的元素都在800*3000所分割成的画布上摆放。这时候不用考虑屏幕实际高宽。再次提醒注意:viewBox将画布分为800*3000份的小格子,然后所有的元素在该画布上摆放。至于该格子的绝对大小,则根据我们后面所设定的width height单位来决定。

3.添加SVG元素。
     注意,各个SVG元素的高宽和xy坐标都按照800*3000的大小来设置,也就是说如果想要在最右下角放一个100*100的矩形,那么就应该写成
   
 <rect x="700" y="2900" width="100" height="100" fill="red" />
     我们上面已经说过,这时候不用关心实际屏幕的高宽,只按照viewBox画布大小进行设置。

4.调用JS函数动态设置svg元素的高宽,进行自适应调整。
     在这一步要确定如何查看该画面,对于该画面800*3000,我们设定为只能上下滑动查看,左右固定宽度的方式。
   
     <script type="text/javascript">
         $(function() {
             var svgRootDom = $("#sketchpad")[0];
             adjustToFreezeHeight(svgRootDom);
         });
    </script>


最终的HTML格式如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>FreezeWidth</title>
<link rel="stylesheet" href="screen.css">
<script type="text/javascript" src="../../js/jquery-2.1.0.js"></script>
<script type="text/javascript" src="./screen.js"></script>
<script type="text/javascript">
    $(function() {
        var svgRootDom = $("#sketchpad")[0];
        adjustToFreezeWidth(svgRootDom);
    });
    
</script>
</head>
<body style="background-color: black;">
<svg id="sketchpad" preserveAspectRatio="xMinYMin meet" viewBox="0,0,3000,3000">
    <rect x="0" y="0" width="100%" height="100%" fill="green"/>
    <rect x="10" y="10" width="100" height="100" fill="orange" />
    <rect x="200" y="300" width="90" height="90" fill="orange" />
    <circle cx="400" cy="1500" r="50" fill="gray" />
    <rect x=700 y="2900" width="100" height="100" fill="blue" />
    
</svg>
</body>
</html>

所封装的自适应函数 screen.js

function adjustToFreezeWidth(rootSvg) {
    var windowWidth = $(window).width();

    var viewBoxVal = rootSvg.getAttribute("viewBox");
    var viewBoxWidth = viewBoxVal.split(",")[2];
    var viewBoxHeight = viewBoxVal.split(",")[3];
    rootSvg.removeAttribute("width");
    rootSvg.removeAttribute("height");

    var setWidth = windowWidth;
    var setHeight = (setWidth * viewBoxHeight) / viewBoxWidth;
    rootSvg.setAttribute("width", setWidth);
    rootSvg.setAttribute("height", setHeight);
}

function adjustToNone(rootSvg) {

    var viewBoxVal = rootSvg.getAttribute("viewBox");
    var viewBoxWidth = viewBoxVal.split(",")[2];
    var viewBoxHeight = viewBoxVal.split(",")[3];
    rootSvg.removeAttribute("width");
    rootSvg.removeAttribute("height");

    rootSvg.setAttribute("width", viewBoxWidth);
    rootSvg.setAttribute("height", viewBoxHeight);

}

function adjustToFreezeHeight(rootSvg) {

    var windowHeight = $(window).height();

    var viewBoxVal = rootSvg.getAttribute("viewBox");
    var viewBoxWidth = viewBoxVal.split(",")[2];
    var viewBoxHeight = viewBoxVal.split(",")[3];
    rootSvg.removeAttribute("width");
    rootSvg.removeAttribute("height");

    var setHeight = windowHeight;
    var setWidth = (setHeight * viewBoxWidth)/viewBoxHeight;
    rootSvg.setAttribute("width", setWidth);
    rootSvg.setAttribute("height", setHeight);
}

function adjustToFreezeAll() {

    var windowHeight = $(window).height();
    var windowWidth = $(window).width();
    
    rootSvg.removeAttribute("width");
    rootSvg.removeAttribute("height");

    rootSvg.setAttribute("width", windowWidth);
    rootSvg.setAttribute("height", windowHeight);

}



小结:通过以上的函数计算和SVG设置,可以实现SVG图形在多分辨率屏幕下实现自适应的缩放。尤其对于安卓系统,多种分辨率的情况,只需要设置一个SVG图形,便可以满足绝大多数情况。

需要注意的是,

1.目前该方案适用的是SVG图形铺满全屏的情况下,如果SVG图形并没有铺满全屏,那么需要修改adjust***函数中的windowHeight和windowWidth为实际的SVG高宽。

2.该方案需要用户提前设定是按照哪种方式查看,再调用对应的调整函数。大多数情况下,我们设计的SVG图形只要满足大致的高宽比就可以,不至于那给PC设计的SVG放在手机上查看,那么效果可能不好(当然也可以在手机上设置为高度锁定,左右滑动查看,也可以)。但需要注意的是,如果把一个原来设计的高大于宽的图形非要显示在宽大于高的设备上,那么效果可能会不同。
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!