【问题标题】:How to make SVG larger on hover?如何在悬停时使 SVG 更大?
【发布时间】:2016-01-31 16:10:13
【问题描述】:

如何在悬停时使每个 SVG 部分变大。我正在尝试复制此交互式地图的方式:http://goo.gl/orvyYI

我在这里创建了一个基本的交互式地图进行测试:

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="800px"
     height="600px" viewBox="0 0 800 600" style="enable-background:new 0 0 800 600;" xml:space="preserve">
<style type="text/css">
    .st0{fill:#C1C1C0;}
    .st1{fill:#0FB5CB;}
    .st2{fill:#46B649;}
</style>
<g id="Layer_1">
    <polygon class="st0" points="76.6,96.1 745.6,96.1 745.6,543.7 188.3,543.7   "/>
</g>
<g id="landmarks-test">
    <rect id="1" x="495.2" y="130.6" class="section" width="233.1" height="83.4"/>
    <rect id="2" x="495.2" y="235.4" class="section" width="233.1" height="95.9"/>
    <rect id="3" x="495.2" y="345.8" class="section" width="233.1" height="84.1"/>
</g>
</svg>

我尝试过使用transform: matrix() 实现他们的方式,也尝试过transform: scale(),但没有成功。

CODEPEN DEMO

【问题讨论】:

  • 你的意思是this
  • @Harry - 有点,如果它可以像这些那样工作会很好:tinyurl.com/ppydvfr - 所以当你将鼠标悬停在该部分上时,如果这有意义的话,它会从中心向外增长.. .

标签: html css svg css-transforms


【解决方案1】:

您可以实现如下 - https://codepen.io/jsomai/pen/GRNNvYV

这里 SVG 在悬停时展开


// SVG HTML
<svg id="right">
  <path d="M0.5 9.35772H20.9956L14.2001 2.29941L16.4134 0L27 11L16.4134 22L14.2001 19.7006L20.9956 12.6423H0.5V9.35772Z" fill="#000"></path>
</svg>

// SCSS
svg {
  height: 22px;
  width: 60px;
  opacity: 0.5;
  transition: 250ms all ease;
  cursor: pointer;
  display:flex;
  align-items:center;
  path {
    transition: 250ms all ease;
    height:100%;
  }
  &:hover {
    opacity: 1;
  }
}
svg#left{
  transform:rotate(180deg);
}
svg#left:hover path {
 d: path(
    "M0 9.35772H50.9956L44.2001 2.29941L46.4134 0L57 11L46.4134 22L44.2001 19.7006L50.9956 12.6423H0V9.35772Z"
  );
  d: "M0 9.35772H50.9956L44.2001 2.29941L46.4134 0L57 11L46.4134 22L44.2001 19.7006L50.9956 12.6423H0V9.35772Z";
}
svg#right:hover path {
  d: path(
    "M0 9.35772H50.9956L44.2001 2.29941L46.4134 0L57 11L46.4134 22L44.2001 19.7006L50.9956 12.6423H0V9.35772Z"
  );
  d: "M0 9.35772H50.9956L44.2001 2.29941L46.4134 0L57 11L46.4134 22L44.2001 19.7006L50.9956 12.6423H0V9.35772Z";
}

【讨论】:

    【解决方案2】:

    您可以使用 CSS 以 class='section' 定位单个 SVG 元素,并对其应用所需的缩放变换。给元素添加transition,可以让它平滑增长。

    transform-origin 设置对整个片段至关重要,因为它指定了应该用作变换原点的点。

    .section:hover {
      transform: scale(1.2);
    }
    .section {
      transition: all 1s;
      transform-origin: 50% 50%;
    }
    

    $(document).ready(function() {
      $('.section').on('click', function(event) {
        var sectionID = $(this).attr('id');
        // Select the relevant popup window that has the same ID as the sectionID
        var popupWindow = $('.popup-window.lot-' + sectionID);
        $('.popup-window').not(popupWindow).hide();
        var leftPos = $(this).position().left;
        var topPos = $(this).position().top;
        popupWindow.css('top', topPos - 200).css('left', leftPos - 100).show();
      });
    
      $('.close-button').click(function(event) {
        $('.popup-window').hide();
      });
    
    });
    body {
      position: relative;
      margin: 0, padding: 0;
    }
    .section:hover {
      fill: yellow;
    }
    .popup-window {
      width: 400px;
      height: 200px;
      background: #accee2;
      display: none;
      position: absolute;
      z-index: 100;
      top: 0;
      border: 1px solid #ccc;
      border: 1px solid rgba(0, 0, 0, .2);
      border-radius: 6px;
      -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
      box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
      padding: 20px;
    }
    .section:hover {
      transform: scale(1.2);
    }
    .section {
      transition: all 1s;
      transform-origin: 50% 50%;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div class="popup-window lot-1">
      <a href="/for-sale/show/1">Lot Number: 1</a>
      <h5>Section Size: 500</h5>
      <button class="close-button">Close</button>
    </div>
    
    <div class="popup-window lot-2">
      <a href="/for-sale/show/2">Lot Number: 2</a>
      <h5>Section Size: 600</h5>
      <button class="close-button">Close</button>
    </div>
    
    <div class="popup-window lot-3">
      <a href="/for-sale/show/3">Lot Number: 3</a>
      <h5>Section Size: 450</h5>
      <button class="close-button">Close</button>
    </div>
    
    <?xml version="1.0" encoding="utf-8" ?>
    <!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
    <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="800px" height="600px" viewBox="0 0 800 600" style="enable-background:new 0 0 800 600;" xml:space="preserve">
      <style type="text/css">
        .st0 {
          fill: #C1C1C0;
        }
        .st1 {
          fill: #0FB5CB;
        }
        .st2 {
          fill: #46B649;
        }
      </style>
      <g id="Layer_1">
        <polygon class="st0" points="76.6,96.1 745.6,96.1 745.6,543.7 188.3,543.7 	" />
      </g>
      <g id="landmarks-test">
        <rect id="1" x="495.2" y="130.6" class="section" width="233.1" height="83.4" />
        <rect id="2" x="495.2" y="235.4" class="section" width="233.1" height="95.9" />
        <rect id="3" x="495.2" y="345.8" class="section" width="233.1" height="84.1" />
      </g>
    </svg>

    在您链接的网站中看到的效果有点复杂,因为最后有一个混蛋,它需要一个三次贝塞尔曲线来表示 transition-timing-function(或)关键帧 animation

    transition-timing-function: cubic-bezier(.87,1,.6,.19);
    

    $(document).ready(function() {
      $('.section').on('click', function(event) {
        var sectionID = $(this).attr('id');
        // Select the relevant popup window that has the same ID as the sectionID
        var popupWindow = $('.popup-window.lot-' + sectionID);
        $('.popup-window').not(popupWindow).hide();
        var leftPos = $(this).position().left;
        var topPos = $(this).position().top;
        popupWindow.css('top', topPos - 200).css('left', leftPos - 100).show();
      });
    
      $('.close-button').click(function(event) {
        $('.popup-window').hide();
      });
    
    });
    body {
      position: relative;
      margin: 0, padding: 0;
    }
    .section:hover {
      fill: yellow;
    }
    .popup-window {
      width: 400px;
      height: 200px;
      background: #accee2;
      display: none;
      position: absolute;
      z-index: 100;
      top: 0;
      border: 1px solid #ccc;
      border: 1px solid rgba(0, 0, 0, .2);
      border-radius: 6px;
      -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
      box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
      padding: 20px;
    }
    .section:hover {
      transform: scale(1.2);
    }
    .section {
      transition: all 1s;
      transition-timing-function: cubic-bezier(.87,1,.6,.19);
      transform-origin: 50% 50%;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div class="popup-window lot-1">
      <a href="/for-sale/show/1">Lot Number: 1</a>
      <h5>Section Size: 500</h5>
      <button class="close-button">Close</button>
    </div>
    
    <div class="popup-window lot-2">
      <a href="/for-sale/show/2">Lot Number: 2</a>
      <h5>Section Size: 600</h5>
      <button class="close-button">Close</button>
    </div>
    
    <div class="popup-window lot-3">
      <a href="/for-sale/show/3">Lot Number: 3</a>
      <h5>Section Size: 450</h5>
      <button class="close-button">Close</button>
    </div>
    
    <?xml version="1.0" encoding="utf-8" ?>
    <!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
    <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="800px" height="600px" viewBox="0 0 800 600" style="enable-background:new 0 0 800 600;" xml:space="preserve">
      <style type="text/css">
        .st0 {
          fill: #C1C1C0;
        }
        .st1 {
          fill: #0FB5CB;
        }
        .st2 {
          fill: #46B649;
        }
      </style>
      <g id="Layer_1">
        <polygon class="st0" points="76.6,96.1 745.6,96.1 745.6,543.7 188.3,543.7 	" />
      </g>
      <g id="landmarks-test">
        <rect id="1" x="495.2" y="130.6" class="section" width="233.1" height="83.4" />
        <rect id="2" x="495.2" y="235.4" class="section" width="233.1" height="95.9" />
        <rect id="3" x="495.2" y="345.8" class="section" width="233.1" height="84.1" />
      </g>
    </svg>

    当给定一个百分比值时,Firefox 似乎不尊重transform-origin 设置,因此我们必须为每个孩子使用特定的像素值。各个值计算为x position + width/2 和 y position + height/2。

    .section:nth-child(1){
      transform-origin: 612px  172px;
    }
    .section:nth-child(2){
      transform-origin: 612px  283px;
    }
    .section:nth-child(3){
      transform-origin: 612px  388px;
    }
    

    $(document).ready(function() {
      $('.section').on('click', function(event) {
        var sectionID = $(this).attr('id');
        // Select the relevant popup window that has the same ID as the sectionID
        var popupWindow = $('.popup-window.lot-' + sectionID);
        $('.popup-window').not(popupWindow).hide();
        var leftPos = $(this).position().left;
        var topPos = $(this).position().top;
        popupWindow.css('top', topPos - 200).css('left', leftPos - 100).show();
      });
    
      $('.close-button').click(function(event) {
        $('.popup-window').hide();
      });
    
    });
    body {
      position: relative;
      margin: 0, padding: 0;
    }
    .section:hover {
      fill: yellow;
    }
    .popup-window {
      width: 400px;
      height: 200px;
      background: #accee2;
      display: none;
      position: absolute;
      z-index: 100;
      top: 0;
      border: 1px solid #ccc;
      border: 1px solid rgba(0, 0, 0, .2);
      border-radius: 6px;
      -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
      box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
      padding: 20px;
    }
    .section:hover {
      transform: scale(1.2);
    }
    .section {
      transition: all 1s;
      transition-timing-function: cubic-bezier(.87, 1, .6, .19);
    }
    .section:nth-child(1) {
      transform-origin: 612px 172px;
    }
    .section:nth-child(2) {
      transform-origin: 612px 283px;
    }
    .section:nth-child(3) {
      transform-origin: 612px 388px;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div class="popup-window lot-1">
      <a href="/for-sale/show/1">Lot Number: 1</a>
      <h5>Section Size: 500</h5>
      <button class="close-button">Close</button>
    </div>
    
    <div class="popup-window lot-2">
      <a href="/for-sale/show/2">Lot Number: 2</a>
      <h5>Section Size: 600</h5>
      <button class="close-button">Close</button>
    </div>
    
    <div class="popup-window lot-3">
      <a href="/for-sale/show/3">Lot Number: 3</a>
      <h5>Section Size: 450</h5>
      <button class="close-button">Close</button>
    </div>
    
    <?xml version="1.0" encoding="utf-8" ?>
    <!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
    <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="800px" height="600px" viewBox="0 0 800 600" style="enable-background:new 0 0 800 600;" xml:space="preserve">
      <style type="text/css">
        .st0 {
          fill: #C1C1C0;
        }
        .st1 {
          fill: #0FB5CB;
        }
        .st2 {
          fill: #46B649;
        }
      </style>
      <g id="Layer_1">
        <polygon class="st0" points="76.6,96.1 745.6,96.1 745.6,543.7 188.3,543.7 	" />
      </g>
      <g id="landmarks-test">
        <rect id="1" x="495.2" y="130.6" class="section" width="233.1" height="83.4" />
        <rect id="2" x="495.2" y="235.4" class="section" width="233.1" height="95.9" />
        <rect id="3" x="495.2" y="345.8" class="section" width="233.1" height="84.1" />
      </g>
    </svg>

    另外需要注意的是,如this CodePen Article by Ana Tudor 中所述,SVG 元素上的 CSS 转换在 IE 中不起作用。


    transform: scale(1.2)transform-origin 设置的matrix 等效项如下:(Logic is explained here)

    .section:nth-child(1):hover {
      transform: matrix(1.2, 0, 0, 1.2, -122.4, -34.46);
    }
    .section:nth-child(2):hover {
      transform: matrix(1.2, 0, 0, 1.2, -122.4, -56.67);
    }
    .section:nth-child(3):hover {
      transform: matrix(1.2, 0, 0, 1.2, -122.4, -77.57);
    }
    

    $(document).ready(function() {
      $('.section').on('click', function(event) {
        var sectionID = $(this).attr('id');
        // Select the relevant popup window that has the same ID as the sectionID
        var popupWindow = $('.popup-window.lot-' + sectionID);
        $('.popup-window').not(popupWindow).hide();
        var leftPos = $(this).position().left;
        var topPos = $(this).position().top;
        popupWindow.css('top', topPos - 200).css('left', leftPos - 100).show();
      });
    
      $('.close-button').click(function(event) {
        $('.popup-window').hide();
      });
    
    });
    body {
      position: relative;
      margin: 0, padding: 0;
    }
    .section:hover {
      fill: yellow;
    }
    .popup-window {
      width: 400px;
      height: 200px;
      background: #accee2;
      display: none;
      position: absolute;
      z-index: 100;
      top: 0;
      border: 1px solid #ccc;
      border: 1px solid rgba(0, 0, 0, .2);
      border-radius: 6px;
      -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
      box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
      padding: 20px;
    }
    .section {
      transition: all 1s;
      transition-timing-function: cubic-bezier(.87, 1, .6, .19);
    }
    .section:nth-child(1):hover {
      transform: matrix(1.2, 0, 0, 1.2, -122.4, -34.46);
    }
    .section:nth-child(2):hover {
      transform: matrix(1.2, 0, 0, 1.2, -122.4, -56.67);
    }
    .section:nth-child(3):hover {
      transform: matrix(1.2, 0, 0, 1.2, -122.4, -77.57);
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div class="popup-window lot-1">
      <a href="/for-sale/show/1">Lot Number: 1</a>
      <h5>Section Size: 500</h5>
      <button class="close-button">Close</button>
    </div>
    
    <div class="popup-window lot-2">
      <a href="/for-sale/show/2">Lot Number: 2</a>
      <h5>Section Size: 600</h5>
      <button class="close-button">Close</button>
    </div>
    
    <div class="popup-window lot-3">
      <a href="/for-sale/show/3">Lot Number: 3</a>
      <h5>Section Size: 450</h5>
      <button class="close-button">Close</button>
    </div>
    
    <?xml version="1.0" encoding="utf-8" ?>
    <!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
    <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="800px" height="600px" viewBox="0 0 800 600" style="enable-background:new 0 0 800 600;" xml:space="preserve">
      <style type="text/css">
        .st0 {
          fill: #C1C1C0;
        }
        .st1 {
          fill: #0FB5CB;
        }
        .st2 {
          fill: #46B649;
        }
      </style>
      <g id="Layer_1">
        <polygon class="st0" points="76.6,96.1 745.6,96.1 745.6,543.7 188.3,543.7 	" />
      </g>
      <g id="landmarks-test">
        <rect id="1" x="495.2" y="130.6" class="section" width="233.1" height="83.4" />
        <rect id="2" x="495.2" y="235.4" class="section" width="233.1" height="95.9" />
        <rect id="3" x="495.2" y="345.8" class="section" width="233.1" height="84.1" />
      </g>
    </svg>

    【讨论】:

    • 漂亮,正是我想要的。谢谢你:)
    • 备注:transform-origin 在 Firefox 中不受尊重,当鼠标悬停在当前解决方案中时,矩形会向右滑动。
    • 干得好@harry。太糟糕了 Firefox 强制使用这种不雅的解决方案:/
    • @Harry - 很棒的工作!所以看起来transform: matrix() 在 Chrome 和 Firefox 上都可以正常工作,并且是更简洁的方式。再次感谢您:)
    • @ifusion:似乎 SVG 动画(不是 CSS 动画)在 IE 11 和 Edge 中也不起作用。因此,使用它们并不是真的更好。我创建了this sample 进行验证。 (它没有完全调整,因为我创建它只是为了验证)。
    猜你喜欢
    • 1970-01-01
    • 2021-12-24
    • 2017-06-22
    • 1970-01-01
    • 1970-01-01
    • 2021-05-10
    • 2018-03-03
    • 2021-06-08
    • 2019-10-30
    相关资源
    最近更新 更多