首页 > 解决方案 > SVG Polyline Manipulation in TypeScript

问题描述

I am working with TypeScript 3.1.1 in VS Code with an Aurelia project. I need to manipulate an SVG Polyline in TypeScript code. I am having trouble creating a new SVGPoint object. My initial HTML looks like this:

<svg class="distance-polyline-svg" width="100%" height="100%" ref="distancePolylineSvg">
    <polyline points="100,100 300,100 200,300 500,300" style="stroke: rgba(6, 28, 129, 0.3); stroke-width: 5; fill: transparent" ref="distancePolyline" />
</svg>

distancePolylineSvg is declared as SVGElement distancePolyline is declared as SVGPolylineElement

I can access a point using:

this.distancePolyline.points.getItem(i); But when I try to create a new point to use in this.distancePolyline.points.replaceItem or this.distancePolyline.points.appendItem I am having no success. I've tried new SVGPoint() and get a bad constructor error. I've tried new DOMPoint(), which works but when using it in replaceItem I get an error stating it is expecting a parameter of type SVGPoint. Casting doesn't work. Neither SVGElement nor SVGPolygonElement have a createSVGPoint method and document.rootElement.createSVGPoint doesn't work because rootElement is null.

How do I create a new SVGPoint to pass to the SVGPointList methods?

标签: typescriptsvgaurelia

解决方案


我已经用打字更新了 gist.run。https://gist.run/?id=040775f06aba5e955afd362ee60863aa

正如罗伯特所提到的,您需要将<svg>元素键入为 SVGSVGElement。

SVG DOM API 规范目前缺少从 HTML DOM 元素中获取准确类型的 SVG 元素的方法,这在 TypeScript 中有所体现。但是,从 DOM API 返回的实际对象实际上是 SVG DOM 元素。因此,您需要对 HTML DOM 查询使用强制转换,然后手动将它们键入为 SVG DOM 元素。

let svg: SVGSVGElement = <any>document.getElementById('svg');
let polyline: SVGPolylineElement = <any>svg.getElementById('polyline');
let point: SVGPoint = svg.createSVGPoint();
point.x = 0;
point.y = 0;
polyline.points.appendItem(point);

使用 Aureliaelement.ref会让这看起来更干净一些,尽管它基本上为您做同样的事情。

看法

<template>
  <svg element.ref="svg">
    <polyline element.ref="polyline"></polyline>
  </svg>
</template>

视图模型

export class SVGViewModel {
  svg: SVGSVGElement;
  polyline: SVGPolylineElement;
  addPoint(x: number, y: number) {
    const point: SVGPoint = this.svg.createSVGPoint();
    point.x = x
    point.y = y;
    this.polyline.points.appendItem(point)
  }
}

推荐阅读