5

I have difficulties importing svg.js with it's plugins using typescript in an Angular 5 project.

With npm I installed:

In ticket.component.ts: Imported svg.js as Svg type and this way I can draw a rectangle, this code works:

import * as Svg from 'svg.js'
...
export class TicketComponent implements OnInit {

  ngOnInit() {
    let draw = Svg('ticket-svg').size(1000, 500);
    let rect = draw.rect(800, 300).attr({fill: '#fff', stroke: '#000', 'stroke-width': 1});
  }
...
}

But I cannot use functions from the svg.draggable plugin, because it's not imported:

rect.draggable()
// TS2339: Property 'draggable' does not exist on type 'Rect'.

I want something like this:

import * as Svg from {'svg.js', 'svg.draggable.js', 'svg.whatever.js'}

In the GitHub example code of svg.draggable.js they just add these two lines in the html and that's all:

<script src="svg.js"></script>
<script src="svg.draggable.js"></script>

In angular with typescript, this is completely different because I need the import in the ticket.component.ts file, not in the html.

So how to import svg.js with multiple plugins from node_modules as Svg type?

Update 1:

I read a recommendation to import the typings for these 3rd party js libraries, so I installed:

"@types/svg.js": "^2.3.1",
"@types/svgjs.draggable": "0.0.30"

Update 2:

Tried to merge the two js file into one file and import the merged version, but for some reason this hacky way does not work either...

Thanks in advance!

Melchia
  • 22,578
  • 22
  • 103
  • 117
balazs630
  • 3,421
  • 29
  • 46

2 Answers2

11

Unfortunately svgjs.draggable.js doesn't have a definition type file so you can't import it with the ES6 import/export like svg.js. the definition type file is the file that has the extension d.ts which you can find in the root of the library.

Also in our case svgjs.draggable extends svg.js. So we need to import svgjs.draggable after svg.js. So how to do that? The solution is to import them both either from index.html or using angular-cli.json. I'll choose the latter one.

First install both libraries:

$ npm i svg.js -s
$ npm i svg.draggable.js -s

Add to angular-cli.json

  "scripts": [
     ...
    "../node_modules/svg.js/dist/svg.min.js",
    "../node_modules/svg.draggable.js/dist/svg.draggable.min.js"
     ...
],

Next tell typescript to stop complaining

We'll do this by using the following syntax declare const which tells typescript that the import does really exist but you just can't know it because you didn't find the definition types file. So in a component I did a small demo.

import { Component, OnInit } from '@angular/core';
declare const SVG:any;

    @Component({
      selector: 'app-root',
      template: `<div id="canvas"></div>`,
      styleUrls: ['./app.component.css']
    })
    export class AppComponent implements OnInit {
      title = 'app';

      ngOnInit() {
        const draw = SVG('canvas').size(400, 400);
        const rect = draw.rect(100, 100);
        rect.draggable();

      }
Melchia
  • 22,578
  • 22
  • 103
  • 117
  • 1
    Thank you so much! It turned out that svg.js and it's plugins were in "conflict" somehow with other dependencies (e.x. tinymce) that I added in angular.cli.json. So i just moved svg.js & plugins scripts before the other scripts, just after jqery in the very beginning of the list and it finally worked! :) – balazs630 Jan 25 '18 at 16:20
  • why would not having a definition file prevent you using ES6 import / export? Your answer is incorrect. – Playdome.io Aug 01 '19 at 10:17
  • @DDD No you'll get error "Cannot find external module 'svg.draggable' ". The TypeScript transpiler needs to know the shape of your import to ensure any uses of the import are correctly typed. – Melchia Feb 18 '20 at 09:45
3

Update: Opps...realized your problem was with svg.draggable.js not just svg.js. I'm going to leave this here if anyone else needs this guidance. Sorry for any confusion.

The following worked for my setup (Angular 9, Typescript, SVG.js v3.0).

Install SVG.js

npm install --save @svgdotjs/svg.js

Import into Component

Per the SVG.js Getting Started guide, import SVG into your component.

import { SVG } from '@svgdotjs/svg.js'

Use SVG as wanted

export class MyComponent implements OnInit {

  constructor() {}

  ngOnInit(): void {

    // don't forget to add "#" CSS selector to the name of the DOM element.
    const draw = SVG().addTo('#canvas').size(400, 400);
    const rect = draw.rect(100, 100, );
  }
Simon Diemert
  • 330
  • 3
  • 9
  • Thanks this helps. Where is your element with id "canvas"? How can I add rectangle to the a div with id "mydivid" in MyComplment.html? I am not able to add the rectangle to the div in MyComonent.html. – Lalit Rane Dec 18 '21 at 17:21