【问题标题】:Ordering the svg elements visually直观地对 svg 元素进行排序
【发布时间】:2021-10-17 12:39:19
【问题描述】:

我在订购 SVG 元素时遇到了麻烦。我编写了一个脚本,它将数组中每个数字的比率与其中数字的总和相结合,并针对这些数字创建一个饼图。现在,我正在尝试添加一些动画,但本质上,当我尝试扩大切片的大小时,它似乎在以下路径后面。

我已尝试添加 z-index,但显然该属性不适用于 SVG 元素。我曾尝试使用 3D 变换,但我了解到这也不适用于 SVG。我该如何克服这个问题?

我的代码:

var radius = 100
        var slices = [3,4,3]
        var sumSlices = slices.reduce((last,num) => last + num)
        var degrees = Array.from(slices, num => (360*num)/sumSlices)
        var colorPalet = ["#e668a0", "#53e1a0", "#53a7e1", "#f8a1c8", "#95f2c7", "#94caf0"]
        var pie
        var obj = new Array
        var t, f1, f2, g1, g2
        t = 0
        degrees.forEach((degree, i) => {

            obj[i] = new Object
            
            f1 = radius * Math.cos((Math.PI/180)*t)
            g1 = -(radius * Math.sin((Math.PI/180) * t))
            
            obj[i]["lGo"] = f1 + " " + g1
            t = degree + t
            f2 = (radius * Math.cos((Math.PI/180) * t)) - f1
            g2 = -(g1 + (radius * Math.sin((Math.PI/180) * t)))
            if(degree < 180) obj[i]["aGo"] = radius + " " + radius + " 0 0 0" + f2 + " " + g2
            else obj[i]["aGo"] = radius + " " + radius + " 0 1 0" + f2 + " " + g2
            
        })

        var tags = new Array
        obj.forEach((sl, i) => {
            
            tags[i] = '<path d="M'+ radius + " " + radius +' l'+ sl["lGo"] +' a'+ sl["aGo"] +' Z" fill="'+ colorPalet[i] +'" />'
        })

        document.getElementById("dd").innerHTML = tags.reduce((a, b) => a + " " + b)
        
        body {margin:0}

        .con {
            position: absolute;
            top:50%;
            left:50%
        }

        .conIn {
            position: absolute;
            transform: translate(-50%, -50%);
        }

        svg {
            overflow: initial;
        }

        path {
            transition: 1s;
            position: relative;
            z-index: 1;
            transform-origin: center
        }

        path:hover {
            transform:scale(1.4);
            
        }
    <div class="con">
        <div class="conIn">
            <svg id="dd" width="100" height="100" >
               
            </svg>
        </div>
    </div>

【问题讨论】:

    标签: javascript css svg charts


    【解决方案1】:

    不幸的是,正如您所注意到的,SVG 不支持 z-index。此功能是 proposed 并最终被拒绝。 &lt;svg&gt; 标签使用单个渲染/堆叠上下文,并在较早的孩子之上绘制较晚的孩子。

    这里有一些解决方法:

    1. 使用 JavaScript 对商品进行动态重新排序。您可以添加一个mouseenter 事件处理程序,将元素移动到堆栈的末尾:

      document.getElementById("dd").childNodes.forEach((path) =>
        path.addEventListener('mouseenter', (e) =>
          path.parentNode.appendChild(path)
        )
      );
      
    2. 更改您的过渡动画,使其不会导致重叠。执行此操作的自然方法是手动设置元素的.style.transitionOrigin,以便它们从条形图的中心缩放。见transform-origin。这将需要一些计算,但鉴于您已经在计算所有坐标,应该不会太难。

    3. 创建单独的&lt;svg&gt; 对象。然后你可以使用z-index,我相信。但我认为,相对于彼此定位它们会非常困难。

    顺便说一句,如果您不组装 HTML 字符串并设置innerHTML,而是使用document.createElement 创建元素,然后使用document.getElementById("dd").appendChild 添加这些元素,那么您的代码会更容易以这些方式使用子元素。

    【讨论】:

    • 这段代码似乎解决了我的问题,谢谢。我还有一个问题要问你。 HTML5 Canvas 和 SVG 是相互选择的,还是它们有不同的使用领域?
    • 在您的设置中,SVG 最有意义:您基本上拥有矢量图形,并且想要平滑缩放和使用过渡效果。画布非常适合渲染光栅对象和高性能,包括视频游戏之类的东西(尽管 SVG 也可以制作好的视频游戏)。例如,请参阅HTML5 Canvas vs. SVG vs. div
    猜你喜欢
    • 1970-01-01
    • 2020-06-24
    • 2015-08-23
    • 1970-01-01
    • 2016-04-13
    • 2012-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多