Проблемы с добавлением атрибута clip-path SVG через JavaScript

В настоящее время я пытаюсь получить что-то вроде конического градиента на диаграмме Google Gauge. Вы можете увидеть мои попытки в этой скрипте: https://jsfiddle.net/fqt8pjuw/

Я добавляю калибровочную диаграмму и конический градиент на холсте HTML. Затем я добавляю элемент пути в SVG-clipPath:

Эти элементы пути получают путь от красной полосы на диаграмме датчика.

Наконец, я создаю элемент изображения и добавляю все элементы к указанному элементу в svg.

Но, к сожалению, clip-path не работает должным образом. Я получаю не путь, как ожидалось, а все изображение.

Могут быть некоторые конфликты с использованием правильных пространств имен для определенных функций. Буду рад, если кто-нибудь проверит.

google.charts.load('current', {'packages':['gauge']});
      google.charts.setOnLoadCallback(drawChart);
      function drawChart() {

        var data = google.visualization.arrayToDataTable([
          ['Label', 'Value'],
          ['Test1', 80],
          ['Test2', 80],
        ]);

        var options = {
          width: 400, height: 120,
          redFrom: 0, redTo: 100,
          minorTicks: 5
        };

        chart = new google.visualization.Gauge(document.getElementById('chart_div'));

        chart.draw(data, options);


        canvas = document.createElement('canvas'),
            d = canvas.width = canvas.height = 200,
            ctx = canvas.getContext('2d');

        //document.body.appendChild(canvas);

        ctx.translate(d/2, d/2);
        ctx.rotate(-Math.PI/2-Math.PI/8-Math.PI/16);
        ctx.scale(-1,1);
        ctx.lineWidth = 2;
        ctx.lineCap = 'round';

        for(var i=0; i<=360; i++) {
            ctx.save();

            ctx.rotate(Math.PI * i/180);
            ctx.translate(-ctx.lineWidth/2, ctx.lineWidth/2);

            ctx.beginPath();
            ctx.moveTo(0, 0);
            ctx.strokeStyle = 'hsl(' + i + ',100%,50%)';

            ctx.lineTo(0, d);
            ctx.stroke();
            ctx.closePath();

            ctx.restore();
        }

        svgEl=chart.ga.getElementsByTagName("svg");
        pathEl=svgEl[0].getElementsByTagName("path")[0];
        clipPath=pathEl.getAttribute("d");

        xmlns = "http://www.w3.org/2000/svg";

        cp=document.createElementNS(xmlns,"clipPath");
        cp.setAttribute("id", "cp1");
        cp.setAttributeNS(xmlns, "clipPathUnits","userSpaceOnUse");

        p=document.createElementNS(xmlns, "path");
        p.setAttributeNS(xmlns, "d", clipPath);
        //p.setAttribute("transform","translate(40,40)");
        //p.setAttribute("style", "opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:3;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1");

        cp.appendChild(p);

        img=document.createElementNS(xmlns, "image");
        img.setAttributeNS('http://www.w3.org/1999/xlink', 'href', canvas.toDataURL()+" ");
        img.setAttributeNS(xmlns, "clip-path","url(#cp1)");
        img.setAttribute("width", 200);
        img.setAttribute("height",200);
        img.setAttribute("x", 0);
        img.setAttribute("y",0);
        img.setAttribute("transform","translate(-40,-40)");

        svgEl[0].getElementsByTagName("defs")[0].appendChild(cp);


        svgEl[0].childNodes[1].insertBefore(img, svgEl[0].childNodes[1].childNodes[3]);
      }
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div" style="width: 400px; height: 120px;"></div>


person svennergr    schedule 28.09.2016    source источник


Ответы (1)


В пространстве имен SVG (http://www.w3.org/2000/svg) в SVG нет атрибутов. Только элементы находятся в пространстве имен SVG.

Таким образом, для настройки атрибута в целом вам нужен setAttribute, за исключением xlink:href (SVG 1.1) и редко используемого атрибута xml:space (также SVG 1.1). SVG 2 избавится от обоих этих исключений, так что все атрибуты можно будет установить с помощью setAttribute.

person Robert Longson    schedule 28.09.2016
comment
Спасибо Роберт! Просто чтобы показать, чего я хотел достичь: jsfiddle.net/fqt8pjuw/4, возможно, это поможет кто-то. - person svennergr; 29.09.2016