Код, созданный javascript, не работает - PullRequest
0 голосов
/ 07 августа 2020

Я немного застрял.

У меня есть код, который работает в коде , и если я вставлю его в открытое окно F12, он будет работать нормально, так что все в порядке.

Идея этого svg-кода заключалась в том, что я могу навести курсор не совсем на path, а где-то рядом, чтобы он изменил цвет.

Но мне нужно сгенерировать точно такой же код с помощью javascipt, я написал 2 класса, использовал их, теперь они генерируют тот же код, что и в ссылке codepen, я вижу это в окне разработчика F12, но это не работает.

Мой javascript код:

class Polyline {

    // https://codepen.io/francoisromain/pen/dzoZZj
    
    constructor(points, smoothing, fill, color) {
        this.points = points;
        this.smoothing = (smoothing === undefined) ? 0.2 : smoothing;
        this.fill = fill;
        this.color = color;
    }

    line (pointA, pointB) {
        const lengthX = pointB[0] - pointA[0];
        const lengthY = pointB[1] - pointA[1];
        return {
            length: Math.sqrt(Math.pow(lengthX, 2) + Math.pow(lengthY, 2)),
            angle: Math.atan2(lengthY, lengthX)
        }
    }

    controlPoint (current, previous, next, reverse) {
        const p = previous || current;
        const n = next || current;
        const o = this.line(p, n);
        const angle = o.angle + (reverse ? Math.PI : 0);
        const length = o.length * this.smoothing;
      
        const x = current[0] + Math.cos(angle) * length;
        const y = current[1] + Math.sin(angle) * length;
        return [x, y];
    }

    bezierCommand(point, i, a) {
        const cps = this.controlPoint(a[i - 1], a[i - 2], point);
        const cpe = this.controlPoint(point, a[i - 1], a[i + 1], true);
        return `C ${cps[0]},${cps[1]} ${cpe[0]},${cpe[1]} ${point[0]},${point[1]}`;
    }

    svgPath(points, svg) {
        const d = points.reduce((acc, point, i, a) => i === 0
          ? `M ${point[0]},${point[1]}`
          : `${acc} ${this.bezierCommand(point, i, a)}`
        , '');
        
        const defs = document.createElement( 'defs' );
        defs.innerHTML = "<path id='poly-1' d='" + d + "' fill=" + this.fill + "></path>";

        svg.appendChild(defs);

        const g = document.createElement( 'g' );
        g.setAttribute("id", "group");
        svg.appendChild(g);

        const use1 = document.createElement( 'use' );
        use1.setAttribute("xlink:href", "#poly-1");
        use1.setAttribute("stroke-width", "15");
        use1.setAttribute("pointer-events", "stroke");
        g.appendChild(use1);

        const use2 = document.createElement( 'use' );
        use2.setAttribute("class", "use");
        use2.setAttribute("xlink:href", "#poly-1");
        g.appendChild(use2);

    }

    draw() {
        const svg = document.getElementById("chart-main-canvas");
        this.svgPath(this.points, svg);
    }

}


class Canvas {
    
    constructor(w, h, color) {
        this.width = w;
        this.height = h;
        this.color = color;
        // this.scale = 1;
    }

    canvas() {
        return `<svg width="${this.width}" height="${this.height}" id="chart-main-canvas"  style="background-color: ${this.color}; z-index:5000;" ></svg>`;
    }

    draw() {
        const c = document.getElementById("lifespan-chart-content");
        c.innerHTML = this.canvas();
    }

}


window.addEventListener('load', function() {
    c1 = new Canvas(1000, 500, "bisque");
    c1.draw();

    var smoothing = 0.2;
    var fill = "green";
    var color = "red";

    const points = [
        [5, 10],
        [100, 400],
        [200, 400],
        [355, 50],
        [500, 500]
    ]

    p1 = new Polyline(points, smoothing, fill, color);
    p1.draw();

});

Почему и как я могу это исправить?

Еще одна дополнительная ссылка на рабочий пример svg: ссылка

PS Я почти уверен, что метод проблемы svgPath в Polyline классе

редактировать 1

редактируемая функция:

    svgPath(points, svg) {
        const d = points.reduce((acc, point, i, a) => i === 0
        ? `M ${point[0]},${point[1]}`
        : `${acc} ${this.bezierCommand(point, i, a)}`
        , '');

        const defs = document.createElementNS("http://www.w3.org/2000/svg", 'defs' );
        defs.innerHTML = "<path id='poly-1' d='" + d + "' fill=" + this.fill + "></path>";

        svg.appendChild(defs);

        const g = document.createElementNS("http://www.w3.org/2000/svg", 'g' );
        g.setAttribute("id", "group");
        svg.appendChild(g);

        const use1 = document.createElementNS("http://www.w3.org/2000/svg",'use' );
        use1.setAttribute("xlink:href", "#poly-1");
        use1.setAttribute("stroke-width", "15");
        use1.setAttribute("pointer-events", "stroke");
        g.appendChild(use1);

        const use2 = document.createElementNS("http://www.w3.org/2000/svg", 'use' );
        use2.setAttribute("class", "use");
        use2.setAttribute("xlink:href", "#poly-1");
        g.appendChild(use2);

    }

все еще не работает

1 Ответ

1 голос
/ 07 августа 2020

Вы также можете использовать эту технику для рисования SVG, потому что не так просто просто innerHTML их

// Your SVG code (formed as you wish)
const svgFromJS = `<svg width="1000" height="500" id="chart-main-canvas" style="background-color: bisque; z-index:5000;">
  <defs>
    <path id="poly-1" d="M 5,10 C 24,88 60.99999999999998,322 100,400 C 139,478 149,470 200,400 C 251,330 295,30.000000000000007 355,50 C 415,70 470.99999999999994,410 500,500" fill="none"></path>
    </defs>
  <g id="group">
    <use xlink:href="#poly-1" stroke-width="15" pointer-events="stroke"></use>
    <use class="use" xlink:href="#poly-1"></use>
  </g>
</svg>`;

// Create a tmp container
const c = document.createElement('div');

// Add SVG to tmp container
c.innerHTML = '' + svgFromJS;

// Move childs of the SVG inside tmp container to target SVG at the body
Array.prototype.slice.call(c.childNodes[0].childNodes).forEach(function(el) { 
  document.getElementById('swgtodraw').appendChild(el);
});
#group .use{
  stroke:red
} 
#group:hover .use{
  stroke: green; 
}
<svg id="swgtodraw" width="1000" height="500" style="background-color: bisque; z-index:5000;"></svg>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...