paperjs / paper.js

The Swiss Army Knife of Vector Graphics Scripting – Scriptographer ported to JavaScript and the browser, using HTML5 Canvas. Created by @lehni & @puckey
http://paperjs.org
Other
14.45k stars 1.22k forks source link

Thank you! (And issue with importing *.svgs in node.js) #1220

Closed pwichmann closed 7 years ago

pwichmann commented 7 years ago

Thank you for this amazing library! This is incredible. Many thanks to all contributors.

My problem is that I just cannot get the *.svg import to work in node.js.

Why does this code snippet not work at all? (But also does not throw any errors.) Generally, paper.js works in my environment. So it is not a general problem.

`with(paper) {

    paper.setup(new paper.Size(300, 200));

    var group = new Group();
    project.importSVG('./test.svg', {

        onError: function (message) {
            console.error(message);
        },

        onLoad: function (item) {
            // Do something with item
            // console.log(item);
            group.addChild(item);
        }

    });

    var paper_svg = project.exportSVG({asString: true});

    fs.writeFile(path.resolve("./somefolder/somepath.svg"), paper_svg, function (err) {
        if (err) throw err;
        console.log('Saved!');
    });

}`

pwichmann commented 7 years ago

It just won't work. I tried so many things. :(

lehni commented 7 years ago

Did you try the examples that we provide? Could you provide a test case? It's impossible to say without seeing what's going wrong... e.g. what version of node and paper.js are you using?

pwichmann commented 7 years ago

Hi Jürg, Thank you for the amazing library!

Node.js version: v6.9.2 Paper.js version: 3.10.9

All my attempts were based on the examples and comments on GitHub and the Google Group.

I tried creating a group first and then adding the result:


var group = new Group(); project.importSVG('./test.svg', { //expandShapes: true, onLoad: function (item) { // Do something with item console.log(item); group.addChild(item); }, onError: function (message) { console.error(message); } });


If if print the item to the console, I do get a result:


Group { _children: [ Shape { _matrix: [Object], _id: 65, _index: 0, _parent: [Circular], _applyMatrix: false, _style: [Object], _project: [Object], _type: 'rectangle', _size: [Object], _radius: [Object], _globalMatrix: undefined, _decomposed: undefined, _position: undefined, _bounds: undefined, _clipMask: true }, CompoundPath { _children: [Object], _namedChildren: {}, _matrix: [Object], _id: 66, _index: 1, _parent: [Circular], _applyMatrix: true, _style: [Object], _project: [Object], _globalMatrix: undefined, _decomposed: undefined, _position: undefined, _bounds: undefined } ], _namedChildren: {}, _matrix: Matrix { _d: 1, _a: 1, _ty: 0, _tx: 0, _c: 0, _b: 0, _owner: [Circular] }, _id: 64, _index: 5, _parent: Layer { _children: [ [Object], [Object], [Object], [Object], [Object], [Circular] ], _namedChildren: {}, _matrix: Matrix { _d: 1, _a: 1, _ty: 0, _tx: 0, _c: 0, _b: 0, _owner: [Circular] }, _id: 2, _index: 0, _parent: null, _applyMatrix: true, _style: [......]


The type of the created group is 'object'. But nothing gets ever added to the project / active layer and then exported in the next step.

Which import statement should definitely work in node.js?

pwichmann commented 7 years ago

P.S. I am happy to donate some money to paper.js as a thank you for some help with this particular problem.

lehni commented 7 years ago

There is no paper.js version 3.10.9. I am not sure where you got this number from?

And could you provide the svg file in question? I need to be able to reproduce the problem. A full test-case that illustrates the failing behavior would be ideal, including a package.json file and instructions for how to run the code.

pwichmann commented 7 years ago

Many thanks! I will provide you the full test case as soon as possible. And donate a monetary Xmas gift via your website.

Also, I am sorry to have made a mistake with respect to the version number. I was tricked by my usual Python routines and had tried to get the version like this: $ npm install paper --version Which returns npm's version, unfortunately.

It looks like the version of paper.js I am using is: 0.10.2.

pwichmann commented 7 years ago

I have written a little example here (this should be freely accessible): Link to Cloud9 project

Please excuse any stupid mistakes I am likely to have made. And many thanks for your help!

lehni commented 7 years ago

So after inspecting your example, there are two problems going on really:

  1. You are importing SVG data asynchronously, but are exporting your project in the main code, right after calling importSVG(), at which point the data isn't imported yet. Your corrected app.js file looks like this:

    project.importSVG('./svg-import/115784.svg', function(item) {
        var paper_svg = project.exportSVG({ asString: true });
    
        // Actually export the *.svg into a new file
        // Only the rectangle gets exported...
        fs.writeFile(path.resolve("./svg-export/export.svg"), paper_svg, function (err) {
            if (err) throw err;
            console.log('*.svg exported and saved as /svg-export/export.svg!');
        });
    });
  2. There is a problem with this SVG data in conjunction exportSVG() currently that I need to look into. It seems to cause an exception at the moment. I am investigating this right now.

lehni commented 7 years ago

So there's an exception that happens in exportSVG(), but because that code runs asynchronously, the error never sees the console. This way, you can see the error happening:

    project.importSVG('./svg-import/115784.svg', function(item) {
        try {
            var paper_svg = project.exportSVG({ asString: true });
            fs.writeFile(path.resolve("./svg-export/export.svg"), paper_svg, function (err) {
                if (err) throw err;
                console.log('*.svg exported and saved as /svg-export/export.svg!');
            });
        } catch (e) {
            console.error(e);
        }
    });

Output:

TypeError: Cannot read property '_id' of undefined
    at getDefinition (/Users/lehni/Downloads/Chrome/workspace/node_modules/paper/dist/paper-full.js:13579:16)
    at setDefinition (/Users/lehni/Downloads/Chrome/workspace/node_modules/paper/dist/paper-full.js:13585:4)
    at exportGroup (/Users/lehni/Downloads/Chrome/workspace/node_modules/paper/dist/paper-full.js:13343:6)
    at exportSVG (/Users/lehni/Downloads/Chrome/workspace/node_modules/paper/dist/paper-full.js:13616:23)
    at exportGroup (/Users/lehni/Downloads/Chrome/workspace/node_modules/paper/dist/paper-full.js:13338:20)
    at exportSVG (/Users/lehni/Downloads/Chrome/workspace/node_modules/paper/dist/paper-full.js:13616:23)
    at Project.exportSVG (/Users/lehni/Downloads/Chrome/workspace/node_modules/paper/dist/paper-full.js:13673:24)
    at /Users/lehni/Downloads/Chrome/workspace/app.js:46:37
    at XMLHttpRequest.onLoad (/Users/lehni/Downloads/Chrome/workspace/node_modules/paper/dist/paper-full.js:14169:6)
    at XMLHttpRequest.xhr.onload (/Users/lehni/Downloads/Chrome/workspace/node_modules/paper/dist/paper-full.js:12879:21)
lehni commented 7 years ago

And this error appears to be the same problem as #1138 which is already fixed. Time to roll out a new version! But even then, I still see an issue: the resulting output appears to be shifted outside of the clipping rect, further investigating...

pwichmann commented 7 years ago

Thank you for all your work, Jürg! I really appreciate it. It would be amazing if the import/export worked - I'd love to use paper.js for a larger (maybe even commercial) project.

lehni commented 7 years ago

So I debugged this other issue with the import, and it turns out that your SVG data doesn't define a fill but expects the default fill to cascade through. Unfortunately this doesn't seem to work on Node.js, I believe it's because styles don't cascade for SVG elements in JSDOM yet. I'd recommend explicitly setting styles in your SVG data for now, but this is another bug that needs splitting into a separate issue. Other than that, you should be good to go with the latest develop version:

http://paperjs.org/download/#development-builds

lehni commented 7 years ago

The JSDOM related issue is tracked here now: #1229

pwichmann commented 7 years ago

Thank you, Jürg. I will try to summarise my findings here (work in progress).

pwichmann commented 7 years ago

Unfortunately, I am still running into problems that I do not understand. I am not sure if paper.js-related or not. Feel free to ignore if you think this is not paper.js related.

The example is still online here.

Many many thanks for your help.


module.js:327
    throw err;
    ^

Error: Cannot find module './node/window.js'
    at Function.Module._resolveFilename (module.js:325:15)
    at Function.Module._load (module.js:276:25)
    at Module.require (module.js:353:17)
    at require (internal/module.js:12:17)
    at Object.<anonymous> (/home/ubuntu/workspace/lib/paperjs/dist/paper-full.js:35:16)
    at Object.<anonymous> (/home/ubuntu/workspace/lib/paperjs/dist/paper-full.js:14939:3)
    at Module._compile (module.js:409:26)
    at Object.Module._extensions..js (module.js:416:10)
    at Module.load (module.js:343:32)
    at Function.Module._load (module.js:300:12)```
lehni commented 7 years ago

You need the full dist folder, not just dist/paper-full.js It looks like the dist/node/ folder is missing.

pwichmann commented 7 years ago

Thank you again! I had assumed the developer build was of the same structure as the normal one. I didn't crosscheck. The dev build didn't have the node folder. Thank you for all your help!

EDIT: Probably because I just downloaded the build as a *.zip.

lehni commented 7 years ago

Oh good point, that should include the node folder too I guess...

lehni commented 7 years ago

Done: fa4502dfe3f01317eb4c218745982482ebf8401c