【问题标题】:Is it possible to have the translate function be affected by the angle of an element?是否可以让翻译功能受到元素角度的影响?
【发布时间】:2021-11-23 07:15:41
【问题描述】:

我有一个六弧形的 SVG,形成一个圆。我正在使用 CSS,这样每当我悬停弧线时,它的位置就会使用 translate 函数在 y 轴上略微移动。问题是当我将鼠标悬停在一个元素上时,它会在 y 轴上移动,但不考虑元素的角度。

考虑到元素与 CSS 和 JS 的角度,有没有办法让段在 y 轴上向上平移?

这里是codepen 以查看代码和 SVG。

#arc:hover {
        transform: translate(0, 10px);
        transition: all 0.2s;
      }
    
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="index.css">
        <title>Document</title>
    </head>
    <body>
        <svg width="439" height="439" viewBox="0 0 439 439" fill="none" xmlns="http://www.w3.org/2000/svg" >
            <g> 
                <g id='arc'>
                    <path d="M379.92 219.08C379.976 247.277 372.603 274.992 358.544 299.435C344.484 323.877 324.234 344.185 299.832 358.315L219.396 219.397L379.92 219.08Z" fill="#668dcc"/>
                </g>   
                
                <g id='arc'>
                    <path d="M139.409 358.779C114.961 344.728 94.6461 324.485 80.5079 300.088C66.3697 275.691 58.9075 248 58.8723 219.802L219.397 219.602L139.409 358.779Z" fill="#6e085c"/>
                </g>
    
                <g id='arc'>
                    <path d="M299.933 358.256C275.541 372.403 247.852 379.875 219.655 379.92C191.457 379.966 163.745 372.583 139.307 358.514L219.396 219.396L299.933 358.256Z" fill="#3e9596"/>         
                </g>
    
                <g id='arc'>
                    <path d="M379.921 219.491C379.866 191.293 372.383 163.608 358.227 139.221C344.071 114.834 323.741 94.6063 299.283 80.5734L219.397 219.808L379.921 219.491Z" fill="#d69304"/>
                </g>
    
                <g id='arc'>
                    <path d="M138.86 80.7425C114.468 94.8895 94.2326 115.212 80.1909 139.665C66.1492 164.118 58.7964 191.838 58.8726 220.036L219.397 219.602L138.86 80.7425Z" fill="#0323b2"/>
                </g>
                <g id='arc'>
                    <path d="M299.384 80.6315C274.937 66.5809 247.219 59.2181 219.021 59.284C190.824 59.35 163.141 66.8424 138.759 81.0073L219.397 219.808L299.384 80.6315Z" fill="#5e2da3"/>
                </g>  
            </g>
        </svg>   
    </body>
    </html>


    

【问题讨论】:

  • 在这种情况下您不应该使用class 而不是id 吗?
  • 所有弧都没有指定“角度”。不幸的是,如果您打算将每个变量移动不同的数量,则无法在 CSS 中很好地使用变量。 (请参阅stackoverflow.com/questions/20490704/…)您需要唯一标识每条弧线并根据需要应用平移量。另一种选择是 Javascript。
  • 是否总是每 60 度 6 片?如果是这样,数学相当简单,CSS 可以通过设置一些变量来完成。顺便说一句,您的 svg 需要注意,因为 id 必须是唯一的。
  • @AHaworth 是的,它总是 6 片,每片 60 度。那么弧的每个角度会有六个 CSS 变量?我只是不明白有角度如何让我影响弧线的移动。
  • @SamridhTuladhar 你是对的。我相应地更新了我的帖子和我的代码笔。

标签: javascript html css


【解决方案1】:

我们需要一点几何来决定对元素应用什么平移。

这个 sn-p 使用 30 度的 sin 和 cos 以及一个变量 --d 计算每个段在 x 和 y 方向上的移动量,该变量表示您希望切片在径向上远离多少中心。

<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="index.css">
  <title>Document</title>
  <style>
    .arc {
      --cos30: 0.8660254037;
      --sin30: 0.5;
      --d: 10px;
      /* the delta amount you want a hovered slice to move away from the center */
    }
    
    .arc:nth-child(1) {
      --x: var(--cos30);
      --y: var(--sin30);
    }
    
    .arc:nth-child(2) {
      --x: calc(-1 * var(--cos30));
      --y: var(--sin30);
    }
    
    .arc:nth-child(3) {
      --x: 0;
      --y: 1;
    }
    
    .arc:nth-child(4) {
      --x: var(--cos30);
      --y: calc(-1 * var(--sin30));
    }
    
    .arc:nth-child(5) {
      --x: calc(-1 * var(--cos30));
      --y: calc(-1 * var(--sin30));
    }
    
    .arc:nth-child(6) {
      --x: 0;
      --y: -1;
    }
    
    .arc:hover {
      transform: translate(calc(var(--d) * var(--x)), calc(var(--d) * var(--y)));
      transition: all 0.2s;
    }
  </style>
</head>

<body>
  <button onclick="document.querySelector('svg').style.transform = 'rotate(49deg)';">Rotate</button>
  <svg width="439" height="439" viewBox="0 0 439 439" fill="none" xmlns="http://www.w3.org/2000/svg">
        <g> 
          
            <g class='arc'>
                <path d="M379.92 219.08C379.976 247.277 372.603 274.992 358.544 299.435C344.484 323.877 324.234 344.185 299.832 358.315L219.396 219.397L379.92 219.08Z" fill="#668dcc"/>
            </g>   
            
            <g class='arc'>
                <path d="M139.409 358.779C114.961 344.728 94.6461 324.485 80.5079 300.088C66.3697 275.691 58.9075 248 58.8723 219.802L219.397 219.602L139.409 358.779Z" fill="#6e085c"/>
            </g>

            <g class='arc'>
                <path d="M299.933 358.256C275.541 372.403 247.852 379.875 219.655 379.92C191.457 379.966 163.745 372.583 139.307 358.514L219.396 219.396L299.933 358.256Z" fill="#3e9596"/>         
            </g>

            <g class='arc'>
                <path d="M379.921 219.491C379.866 191.293 372.383 163.608 358.227 139.221C344.071 114.834 323.741 94.6063 299.283 80.5734L219.397 219.808L379.921 219.491Z" fill="#d69304"/>


            </g>

            <g class='arc'>
                <path d="M138.86 80.7425C114.468 94.8895 94.2326 115.212 80.1909 139.665C66.1492 164.118 58.7964 191.838 58.8726 220.036L219.397 219.602L138.86 80.7425Z" fill="#0323b2"/>
            </g>
            <g class='arc'>
                <path d="M299.384 80.6315C274.937 66.5809 247.219 59.2181 219.021 59.284C190.824 59.35 163.141 66.8424 138.759 81.0073L219.397 219.808L299.384 80.6315Z" fill="#5e2da3"/>
            </g>

            
        </g>
    </svg>
</body>

</html>

请注意,每个切片元素中的 id="arc" 已更改为 class="arc",因为 id 必须是唯一的。

旋转按钮只是将整个 SVG 旋转 49 度,因此您可以看到悬停效果仍然有效。这是因为悬停切片位置的计算是相对于元素而不是相对于窗口进行的。

【讨论】:

    【解决方案2】:

    我找到了一个接近你想要的解决方案。

    我没有移动元素,而是放大了它。通过将锚点设置在元素的中心,它会在悬停时“弹出”。

    .arc {
      transform-origin: center;
    }
    .arc:hover {
        transform:scale(1.1);
        transition: all 0.2s;
      }
    <svg width="439" height="439" viewBox="0 0 439 439" fill="none" xmlns="http://www.w3.org/2000/svg" >
            <g> 
              
                <g class='arc'>
                    <path d="M379.92 219.08C379.976 247.277 372.603 274.992 358.544 299.435C344.484 323.877 324.234 344.185 299.832 358.315L219.396 219.397L379.92 219.08Z" fill="#668dcc"/>
                </g>   
                
                <g class='arc'>
                    <path d="M139.409 358.779C114.961 344.728 94.6461 324.485 80.5079 300.088C66.3697 275.691 58.9075 248 58.8723 219.802L219.397 219.602L139.409 358.779Z" fill="#6e085c"/>
                </g>
    
                <g class='arc'>
                    <path d="M299.933 358.256C275.541 372.403 247.852 379.875 219.655 379.92C191.457 379.966 163.745 372.583 139.307 358.514L219.396 219.396L299.933 358.256Z" fill="#3e9596"/>         
                </g>
    
                <g class='arc'>
                    <path d="M379.921 219.491C379.866 191.293 372.383 163.608 358.227 139.221C344.071 114.834 323.741 94.6063 299.283 80.5734L219.397 219.808L379.921 219.491Z" fill="#d69304"/>
                </g>
    
                <g class='arc'>
                    <path d="M138.86 80.7425C114.468 94.8895 94.2326 115.212 80.1909 139.665C66.1492 164.118 58.7964 191.838 58.8726 220.036L219.397 219.602L138.86 80.7425Z" fill="#0323b2"/>
                </g>
                <g class='arc'>
                    <path d="M299.384 80.6315C274.937 66.5809 247.219 59.2181 219.021 59.284C190.824 59.35 163.141 66.8424 138.759 81.0073L219.397 219.808L299.384 80.6315Z" fill="#5e2da3"/>
                </g>
    
                
            </g>
        </svg>

    【讨论】:

      【解决方案3】:

      由于您有一个固定的集合,您可以简单地设置一个类并使用它。我使用了颜色,但命名象限也可能有用。

      .arc:hover {
        transition: all 0.2s;
      }
      
      .arc.green:hover {
        transform: translate(0px, 10px);
      }
      
      .arc.purple:hover {
        transform: translate(0, -10px);
      }
      
      .arc.orange:hover {
        transform: translate(10px, -5px);
      }
      
      .arc.darkblue:hover {
        transform: translate(-10px, -5px);
      }
      
      .arc.blue:hover {
        transform: translate(10px, 5px);
      }
      
      .arc.maroon:hover {
        transform: translate(-10px, 5px);
      }
      <html lang="en">
      
      <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="index.css">
        <title>Document</title>
      </head>
      
      <body>
        <svg width="439" height="439" viewBox="0 0 439 439" fill="none" xmlns="http://www.w3.org/2000/svg">
                  <g> 
                      <g class='arc blue'>
                          <path d="M379.92 219.08C379.976 247.277 372.603 274.992 358.544 299.435C344.484 323.877 324.234 344.185 299.832 358.315L219.396 219.397L379.92 219.08Z" fill="#668dcc"/>
                      </g>   
                      
                      <g class='arc maroon'>
                          <path d="M139.409 358.779C114.961 344.728 94.6461 324.485 80.5079 300.088C66.3697 275.691 58.9075 248 58.8723 219.802L219.397 219.602L139.409 358.779Z" fill="#6e085c"/>
                      </g>
          
                      <g class='arc green'>
                          <path d="M299.933 358.256C275.541 372.403 247.852 379.875 219.655 379.92C191.457 379.966 163.745 372.583 139.307 358.514L219.396 219.396L299.933 358.256Z" fill="#3e9596"/>         
                      </g>
          
                      <g class='arc orange'>
                          <path d="M379.921 219.491C379.866 191.293 372.383 163.608 358.227 139.221C344.071 114.834 323.741 94.6063 299.283 80.5734L219.397 219.808L379.921 219.491Z" fill="#d69304"/>
                      </g>
          
                      <g class='arc darkblue'>
                          <path d="M138.86 80.7425C114.468 94.8895 94.2326 115.212 80.1909 139.665C66.1492 164.118 58.7964 191.838 58.8726 220.036L219.397 219.602L138.86 80.7425Z" fill="#0323b2"/>
                      </g>
                      <g class='arc purple'>
                          <path d="M299.384 80.6315C274.937 66.5809 247.219 59.2181 219.021 59.284C190.824 59.35 163.141 66.8424 138.759 81.0073L219.397 219.808L299.384 80.6315Z" fill="#5e2da3"/>
                      </g>  
                  </g>
              </svg>
      </body>
      
      </html>

      【讨论】:

      • 我计划让圆旋转或“旋转”改变圆的位置。我将如何在旋转中使用此解决方案?
      • 我认为最简单的方法是稍微不同,我会留下这个并创建另一个稍微不同的答案,当我有时间写出来时
      【解决方案4】:

      我将 CSS 转换变成了 &lt;animateTransform&gt;。在这种情况下,它看起来更容易控制。

      更新

      它也可以旋转。

      document.querySelector('button').addEventListener('click', e => {
        document.querySelector('#container').style.rotate = `${1000}deg`;
      });
      #container {
        translate: 50px 50px;
        rotate: -15deg;
        transition: rotate 1s;
      }
      <button>Rotate</button><br/>
      <svg viewBox="0 0 100 100" width="200">
        <defs>
        <mask id="m1">
          <circle cx="0" cy="0" r="40" fill="white" />
        </mask>
        <g id="r1" mask="url(#m1)">
          <animateTransform attributeName="transform" type="translate"
            from="0 0" to="5 5" begin="mouseenter" dur="200ms" fill="freeze" />
          <animateTransform attributeName="transform" type="translate"
            from="5 5" to="0 0" begin="mouseleave" dur="200ms" fill="freeze" />
          <rect width="50" height="50" transform="skewX(15) skewY(15)"/>
        </g>
        </defs>
        <g id="container">
          <use href="#r1" transform="rotate(0)" fill="#668dcc" />
          <use href="#r1" transform="rotate(60)" fill="#6e085c" />
          <use href="#r1" transform="rotate(120)" fill="#3e9596" />
          <use href="#r1" transform="rotate(180)" fill="#d69304" />
          <use href="#r1" transform="rotate(240)" fill="#0323b2" />
          <use href="#r1" transform="rotate(300)" fill="#5e2da3" />
        </g>
      </svg>

      【讨论】:

        猜你喜欢
        • 2012-06-11
        • 2015-09-03
        • 1970-01-01
        • 1970-01-01
        • 2015-09-04
        • 2013-08-17
        • 1970-01-01
        • 2022-07-26
        • 2021-12-29
        相关资源
        最近更新 更多