【问题标题】:How to scale SVG path to fit the window size?如何缩放 SVG 路径以适应窗口大小?
【发布时间】:2017-08-29 17:42:00
【问题描述】:

我无法缩放 SVG 以适应窗口大小。

在这个例子中,我有一个波浪路径和一个文本元素,我在这里要实现的是沿着波浪路径从左到右移动文本元素(由 GSAP 完成)并在中途停止初始负载中的路径;当用户开始滚动时,它会移动到最后。

我的问题是,SVG创建的波浪路径太长了,一半的路径都会离开窗口,我尝试使用viewBox缩小波浪路径,失败了;使用 css width: 100vw,失败。

我还使用了 css transform 属性,它确实缩小了波浪路径,但这是一个固定大小,我想让它尽可能响应,这意味着无论窗口宽度,文本元素总是停止首先在屏幕中间(波浪路径的一半),然后移动到屏幕的右侧。使用内联 SVG 元素时这可能吗?如果是这样,请指出正确的方向。

提前谢谢你!

(请以全页模式查看示例,这将完美解释我的问题,但滚动功能将被禁用,因为该模式下的高度为100vh,没有滚动空间)

document.getElementById("MyPath").setAttribute("d", document.getElementById("Path").getAttribute("d"));
var tl = new TimelineMax({
  repeat: 0,
  delay: 1
});
tl.to("#Text", 3, {
  attr: {
    startOffset: '50%',
    opacity: 1
  }
});


window.addEventListener('scroll', function() {
  tl.to("#Text", 3, {
    attr: {
      startOffset: '100%',
      opacity: 0
    }
  });
}, true);
@import url(https://fonts.googleapis.com/css?family=Oswald);
body {
  background-color: #222;
}

svg {
  overflow: visible;
  width: 100%;
  height: 100%;
  background-color: #fff;
  left: 0;
  top: 0;
  position: absolute;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.17.0/plugins/TextPlugin.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/gsap/1.17.0/TweenMax.min.js"></script>
<svg xml:space="preserve">
<defs><path id="MyPath"/></defs>
<path id="Path" fill="none" stroke="#000" stroke-miterlimit="10" d="M0,188.2c186.2,84,261.8,84.9,440,66.4s295.2-130,535.2-129.4c240,0.6,357,144.3,591.1,144.3
	s450.1-141.2,651.1-141.2c271.7,0,354.2,141.2,612.1,141.2c240,0,423-141.2,669.1-141.2c119.1,0,202.3,33.8,281,68.7"/>
<text font-size="7em" >
  <textPath id="Text" fill='#88CE02' font-family=Oswald xlink:href="#MyPath" opacity=0 startOffset="0%" letter-spacing="5px">Love the little things.</textPath>
  </text>
</svg>

【问题讨论】:

    标签: css svg


    【解决方案1】:

    如果您希望 SVG 缩放以适应屏幕(或任何父容器),它需要具有 viewBox 属性。该属性告诉浏览器 SVG 内容的尺寸。没有它,浏览器就知道需要缩放多少。

    你的路径大约是 3780 宽,底部是 y=144。所以viewBox 的合理值是:

    viewBox="0 0 3780 150"
    

    document.getElementById("MyPath").setAttribute("d", document.getElementById("Path").getAttribute("d"));
    var tl = new TimelineMax({
      repeat: 0,
      delay: 1
    });
    tl.to("#Text", 3, {
      attr: {
        startOffset: '50%',
        opacity: 1
      }
    });
    
    
    window.addEventListener('scroll', function() {
      tl.to("#Text", 3, {
        attr: {
          startOffset: '100%',
          opacity: 0
        }
      });
    }, true);
    @import url(https://fonts.googleapis.com/css?family=Oswald);
    body {
      background-color: #222;
    }
    
    svg {
      overflow: visible;
      width: 100%;
      height: 100%;
      background-color: #fff;
      left: 0;
      top: 0;
      position: absolute;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.17.0/plugins/TextPlugin.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/gsap/1.17.0/TweenMax.min.js"></script>
    <svg viewBox="0 0 3780 150" xml:space="preserve">
    <defs><path id="MyPath"/></defs>
    <path id="Path" fill="none" stroke="#000" stroke-miterlimit="10" d="M0,188.2c186.2,84,261.8,84.9,440,66.4s295.2-130,535.2-129.4c240,0.6,357,144.3,591.1,144.3
    	s450.1-141.2,651.1-141.2c271.7,0,354.2,141.2,612.1,141.2c240,0,423-141.2,669.1-141.2c119.1,0,202.3,33.8,281,68.7"/>
    <text font-size="7em" >
      <textPath id="Text" fill='#88CE02' font-family=Oswald xlink:href="#MyPath" opacity=0 startOffset="0%" letter-spacing="5px">Love the little things.</textPath>
      </text>
    </svg>

    【讨论】:

    • 我尝试使用viewBox来解决这个问题,但是我并没有完全理解它的用法,显然我用错了。谢谢。
    • 第一次我几乎明白 viewBox 的作用 - 谢谢!
    【解决方案2】:

    您可以执行以下操作:添加定义所需宽度的媒体查询,然后为 svg 元素内的 textpath 元素分别应用以下样式:

    text {
      font-size: 2em;
    }  
    
    path {
      -webkit-transform: scale(.3);
      -ms-transform: scale(.3);
      transform: scale(.3);
    }
    

    参见下面的 sn-p:

    document.getElementById("MyPath").setAttribute("d", document.getElementById("Path").getAttribute("d"));
    var tl = new TimelineMax({
      repeat: 0,
      delay: 1
    });
    tl.to("#Text", 3, {
      attr: {
        startOffset: '50%',
        opacity: 1
      }
    });
    
    
    window.addEventListener('scroll', function() {
      tl.to("#Text", 3, {
        attr: {
          startOffset: '100%',
          opacity: 0
        }
      });
    }, true);
    @import url(https://fonts.googleapis.com/css?family=Oswald);
    body {
      background-color: #222;
    }
    
    svg {
      overflow: visible;
      width: 100%;
      height: 100%;
      background-color: #fff;
      left: 0;
      top: 0;
      position: absolute;
    }
    
    @media only screen and (max-width: 500px) {
    
      text {
        font-size: 2em;
      }  
      
      path {
        -webkit-transform: scale(.3);
        -ms-transform: scale(.3);
        transform: scale(.3);
      }
      
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.17.0/plugins/TextPlugin.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/gsap/1.17.0/TweenMax.min.js"></script>
    <svg xml:space="preserve">
    <defs><path id="MyPath"/></defs>
    <path id="Path" fill="none" stroke="#000" stroke-miterlimit="10" d="M0,188.2c186.2,84,261.8,84.9,440,66.4s295.2-130,535.2-129.4c240,0.6,357,144.3,591.1,144.3
    	s450.1-141.2,651.1-141.2c271.7,0,354.2,141.2,612.1,141.2c240,0,423-141.2,669.1-141.2c119.1,0,202.3,33.8,281,68.7"/>
    <text font-size="7em" >
      <textPath id="Text" fill='#88CE02' font-family=Oswald xlink:href="#MyPath" opacity=0 startOffset="0%" letter-spacing="5px">Love the little things.</textPath>
      </text>
    </svg>

    希望对你有帮助!

    【讨论】:

    • 感谢您的回复。理想情况下,我想避免使用这种方法,因为transform: scale() 会返回一个固定的尺寸,它不够灵活,无法适应不同的屏幕尺寸。我正在寻找类似 @​​987654328@ 的内联 SVG 元素,我对内联 SVG 的了解非常有限,所以我不知道这是否可以实现。
    • 当然是王赫,我自己也一直在找这个。我认为使用内联 SVG 时实现它的唯一方法是通过修改媒体查询中的值。 @Paul LeBeau 的解决方案很棒,他解决了,谢谢!
    猜你喜欢
    • 2021-12-23
    • 2021-10-28
    • 1970-01-01
    • 2020-09-09
    • 2017-05-08
    • 1970-01-01
    • 1970-01-01
    • 2017-09-13
    • 1970-01-01
    相关资源
    最近更新 更多