EzDevInfo.com

paper.js

The Swiss Army Knife of Vector Graphics Scripting – Scriptographer ported to JavaScript and the browser, using HTML5 Canvas. Created by <a href="https://github.com/lehni" class="user-mention">@lehni</a> &amp; <a href="https://github.com/puckey" class="user-mention">@puckey</a> Paper.js

Serialize items in Paper.js

Is there a way to serialize all current items in a project with paper.js? So their positions, styles, etc etc?


Source: (StackOverflow)

Which paper.js file do I use in their dist directory?

I want to use paper.js, but there are 3 different versions of paper.js that I can't find an explanation for the differences of. Which do I use?

from paper.js' dist directory:

  • paper-core.js
  • paper-full.js
  • paper.js

There's actually a 4th, paper-node.js, but I assume that's for Node.js which I'm not using at the moment.


Source: (StackOverflow)

Advertisements

Wave animation for a character converted to svg

I have problems animating part of the character 'W' that is converted to svg. This character is styled out a bit, it has like small flag at the left side (the part that I want to animate).
Right now when the animation is going, that flag is stretched vertically at the top of page. It should stay at the same position where it was, also the top and bottom line of the flag should be in parallel( like in image sample below).


enter image description here
Code sample:

var pathData = "M253.477,175...";
var path = new paper.Path(pathData);
var flags = {
    collection:[]
}
var Flag = function(){
  var model = {
      startIndex:0, // start point in path.segments array
      middleIndex:0,// middle point in path.segments array
      endIndex:0, // end point in path.segments array
      height:20, // the wave animation height
      segments:[] // only flag segments
  }  
  return model;
};

var initializeFlag = function(){
    var segments = path.segments;
    //...   
    for(var i = flag.startIndex; i <= flag.endIndex; i++ ){
        flag.segments.push(segments[i]);
    }
    flags.collection.push(flag); //adds to flags collection
};

var doWaveAnimation = function(segment, counter, height, top, e){
    var sinus = Math.sin(e.time * 3 + counter);
    segment.point.y = sinus * height + top;  
};

var animateFlags = function(e){
   var collection = flags.collection;
   for(var i = 0; i < collection.length; i++){
      var flag = collection[i];

      for(var s = flag.startIndex, n = flag.endIndex -1;
         s < flag.middleIndex && n > flag.middleIndex -2;
         s++, n--){

          //top line
          doWaveAnimation(flag.segments[n], n, flag.height, 180, e);
          //bottom line
          doWaveAnimation(flag.segments[s], s, flag.height, 200, e);
       }
    }
};
//...

Full code sample -> flag animation

To get greater understanding what kind of "wave" animation I want, here is also one example(at the bottom of page) -> http://paperjs.org/

EDIT
Looks like the main reason why this animation is not working properly is that both lines are not positioned horizontally but diagonally..


Source: (StackOverflow)

Concurent drawing with paper.js

I have an app that deals with drawing widget based upon paper.js. Several users can draw at the same time, and changes are broadcast to each other in real time. The problem is that I need to store the changes and show drawn image while document is loaded.

The natural solution is to store commands sent by clients in DB. But drawn images can consist of thousands of commands, and I can have tens of images. So when I'm opening a document getting a list of commands from server, drawing can take too much time.

Is there a better way of storing images and interaction between clients?

Note that I have a scaling feature, so storing raster is not an option.

UPDATE: If I'm storing an image (e.g. in a BLOB) it's not clear how to apply changes made in real time. Passing image each time is not the solution I want.


Source: (StackOverflow)

How to structure AngularJS and PaperJS project

The idea is to make use of Angular in a simple canvas game development. In theory the project should benefit from being more systematic, manageable and scalable. This is not a sprite/tile/collision game and PaperJS is used to do most canvas drawing and interactions.

  1. What is the best approach to integrate Paper.js (or other canvas drawing library) into multiple NG views, in order to have each view representing a game stage?
  2. Is it possible to setup Paper once and use paper across multiple views?
  3. The game allows user to revisit previous stages/views. Do I have to re-setup Paper every time the view/canvas loads? (Shown in example below, if only setup once a blank canvas will appear on view's second visit)
  4. How do I transfer Paper js information between views? e.g. captures user drawing in view 1, and display drawing in view 3.

Background:

Paper JS

I'm working on a project to create a simple canvas game with 4 stages. I decided to use PaperJS for its advantage for drawing and animating shapes. Content and ui for each stage is kept in a separate layer within the same paper project.

Angular JS

The game has become more complicated as it develops. After some research, I decided to use Angular to organise the whole game, although I'm new to Angular. The plan:

  • The 4 game stages are split into four views, each has its own canvas
  • Custom directives are used to setup paper on each canvas
  • Using service for communication between canvases. For example allow users to draw in stage one and display drawing in stage two

I have made a mock up in plunker showing the basic setup and animation with Paper.js. Each canvas sits in a separate view with routing enabled.

Plunker demo: http://plnkr.co/edit/Um1jTp8xTmAzVEdzk2Oq?p=preview

For testing sake, I have made

paper.project.layers[0].children

visible anytime. After a paper is setup, firing "add shapes" button would introduce children to the active layer as expected.

Problem 1 (Draw1 in demo)

In DRAW1, paper will only setup once on the canvas when the view first loads:

drawControllers.directive('drawingBoard',['drawService',function(drawService){

function link(scope, element, attrs){

    // setup Paper

    var canvas = element[0];

    if ( scope.objectValue.count < 1){

        paper = new paper.PaperScope();
        paper.setup(canvas);
        scope.setCount( scope.objectValue.count + 1 );

        with (paper) {

            var shape = new Shape.Circle(new Point(200, 200), 200);
                shape.strokeColor = 'black';
                shape.fillColor = 'yellow';

            // Display data in canvas
            var text = new PointText(new Point(20, 20));
                text.justification = 'left';
                text.fillColor = 'black';

            var text2 = new PointText(new Point(200, 200));
                text2.justification = 'center';
                text2.fillColor = 'black';
                text2.content = 'click to change size';

            shape.onClick = function(event) {
                this.fillColor = 'orange';
                scope.$apply(function () {
                  scope.setWidth(Math.round((Math.random()*100)+100));
                });
            }

            view.onFrame = function(event) {

                if ( text.position.x > 440 ){
                  text.position.x = -40;
                } else {
                  text.position.x = text.position.x + 3;
                }

                text.content = 'Shape width: ' + scope.objectValue.width;

                shape.radius = scope.objectValue.width;

                scope.$apply(function () {
                    scope.setMessage();          
                });

            }

            paper.view.draw();

        }

    } else {

        scope.setMessage();

    }

}

return {
    link: link
}

}]);

However, if navigate from DRAW1 to HOME and back to DRAW1, the canvas would appear blank. But firing "add shapes" at this point would still create new children to the layer.

Problem 2 (DRAW2 in demo)

By removing this line

if ( scope.objectValue.count < 1){
    // ... paper setup ...
}

Paper will setup in DRAW2 every time it loads.

But that introduces a new paper project every time.

Thank you

Thank you for any advice and suggestions.


Source: (StackOverflow)

Paper.js with excanvas

I've grown to like paper.js a lot but after realizing that it does not support IE8, I was wondering if it was possible to have paper.js working together with excanvas? Has anyone tested this and are there examples available?

Thank you.


Source: (StackOverflow)

recommended way to extend classes in Paper.js

Is there a recommended way to extend classes in Paper.js? In particular, I am interested in extending Path

Pardon if my terminology is incorrect, but I am essentailly asking the same question about paper that is being asked about three here


Source: (StackOverflow)

CAD-in-a browser, HTML5 Canvas and performance limitations of Javascript/browser development

I am building a CAD app that runs in a browser.


It's based on Paper.js, a very neat Canvas library that allows you to manipulate vectors.

Paper.js is more than great. There is a plethora of features to use, it's creators are really helpful in answering questions/bug fixing and it's generally a very easy-to-use and professionaly maintained library. New features also come in at a good pace and it's easy to update to newer versions of the library.

The major issue I am having at the moment is performance.


The CAD-app targets laser-cutting.

  • Laser-cutting has the advantage of being able to cut intricate designs out of materials, hence the app should be able to handle very high-node count designs.

  • Unfortunately the app cannot handle such high-node count designs. It gets extremely cludgy after >50 000 nodes designs and it's generally not the kind of a responsive tool that a designer would want to use in those scenarios.

  • I have the impression that Paper.js is somewhat optimized as a library and I already started thinking that the app has stumbled upon fundamental limitations of Javascript speed/Browser developement VS native desktop C++ applications.

The question

Therefore I need to think of a ''hack'' that will allow my app to be responsive in scenarios like the one described above. Are there some classroom examples of optimizing large node-count documents editing in CAD apps?

E.G: I thought of rasterizing paths that are not directly selected and worked on, save their path data into LocalStorage and as soon as the user clicks on them to manipulate them, to re-import back their path data. That would minimize the memory usage on non-worked-on items.

Unfortunately rasterizing,saving and reimporting is also a bottleneck. So this solution is less than optimal.

Edit: Rasterizing could be a viable solution, see below

I would like to hear of more ideas like the one described above, if anyone can help.


Source: (StackOverflow)

Implementing a Paper.js spiral raster example on server-side

I am trying to draw a spiral raster example (link) on a server (running Node.js). However, I am facing an issue where my path is not displayed on the exported frame and I can only see the downloaded image. Probably a silly mistake on my side, however, days of looking through Google and documentation didn't help me to solve an issue.

What I did:

  • Add paper. prefixes
  • Changed +/- to corresponding add() and subtract()
  • Tried presenting a path within a layer.

Here is my code:

var paper = require('paper');
var fs = require('fs');
var drawer = {};

var canvas = new paper.Canvas(1000, 1000);
paper.setup(canvas);

var layer = paper.project.activeLayer;

drawer.drawSpiral = function(url, filename, fn) {   
    var url = 'http://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png';
    var raster = new paper.Raster(url);

    raster.onLoad = function() {
        raster.fitBounds(paper.view.bounds);

        var position = paper.view.center;
        var count = 0;
        var max = Math.min(raster.bounds.width, raster.bounds.height) * 0.5;

        var path = new paper.Path();
        path.fillColor = 'black';
        path.closed = true;

        while ((paper.view.center - position).length < max) {
            count++;

            var vector = new paper.Point(count * 5, count / 100);
            var rot = vector.rotate(90);
            var color = raster.getAverageColor(position.add(vector).divide(2));
            var value = color ? (1 - color.gray) * 3.7 : 0;

            rot.length = Math.max(value, 0.2);
            path.add(position.add(vector).subtract(rot));
            path.insert(0, position.add(vector).add(rot));

            position = position.add(vector);
        }

        path.smooth();
        layer.insertChild(0, path);
        layer.fitBounds(paper.view.bounds);
        drawer.exportPNG(filename, fn);  
    };
}

drawer.exportPNG = function(filename, fn) {
    out = fs.createWriteStream(__dirname + '/static/img/' + filename + '.png');
    stream = canvas.pngStream();

    stream.on('data', function(chunk) {
        out.write(chunk);
    });

    stream.on('end', function() {
        fn();
    });
}

module.exports = drawer;

Invoked, obviously, like this:

var drawer = require('./drawer.js');
drawer.drawSpiral('','abc', function(){});

Source: (StackOverflow)

Creating unique variables

My foundations in Javascript aren't the strongest and I'm curious how others would go about the current challenge I've created for myself.

I'm playing around with paper.js

The following code creates this screenshot

The eye reacts to mouse events in the same way as the eyes here (learned from that code) — www.arc.id.au/XEyes.html

Here's what I have:

// Eye position center
eCntrX = 100
eCntrY = 100

var topLid = new Path()
topLid.add(new Point(eCntrX - 60, eCntrY))
topLid.add(new Point(eCntrX, eCntrY - 28))
topLid.add(new Point(eCntrX + 60, eCntrY))
topLid.add(new Point(eCntrX, eCntrY + 28))

topLid.strokeWidth = '6'
topLid.strokeColor = '#000'
topLid.closed = true
topLid.smooth()

var iris = new Path.Circle(eCntrX, eCntrY, 24)
iris.fillColor = '#6CE0FF'
iris.strokeWidth = '6'
iris.strokeColor = '#000'

var pupil = new Path.Circle(eCntrX, eCntrY, 15)
pupil.fillColor = '#000'

var glint = new Path.Circle(eCntrX, eCntrY, 5)
glint.fillColor = '#fff'
glint.position = new Point(eCntrX + 6, eCntrY - 6)

var ball = new Group([iris, pupil, glint])


function onMouseMove(event) {

  // Cursor position
  var csrX = event.point.x
  var csrY = event.point.y

  // Ball position
  var ballX = ball.position.x
  var ballY = ball.position.y

  // Displacement
  var dx = csrX - ballX
  var dy = csrY - ballY

  //Radius
  var r = 5

  //Pythagerous thereom calcs. R
  var R = Math.sqrt(dx*dx+dy*dy)

  x = dx*r/R
  y = dy*r/R

  ball.position = new Point(eCntrX + x, eCntrY + y)

  // console.log('x:' + x + 'y:' + y)

}

I'm looking to fill the whole page with eyes. My end goals is to create something like this:

End result

My question is, what is the best way to go about creating multiple eyes that are interactive.

I've been playing around with 'for', but the onMouseMove function only applies to the last Eye created.

Have also been looking at paperjs item.clone — paperjs.org/reference/item#clone

Or is it a matter of me creating unique variables for each eye?

Here's the code with the for as requested:

for(var i = 0; i < 10; i++){

  // Eye position center
  // 100, 300, 500, 600
  eCntrX = 100 * i + 100
  eCntrY = 100

  var topLid = new Path()
  topLid.add(new Point(eCntrX - 60, eCntrY))
  topLid.add(new Point(eCntrX, eCntrY - 28))
  topLid.add(new Point(eCntrX + 60, eCntrY))
  topLid.add(new Point(eCntrX, eCntrY + 28))

  topLid.strokeWidth = '6'
  topLid.strokeColor = '#000'
  topLid.closed = true
  topLid.smooth()

  var iris = new Path.Circle(eCntrX, eCntrY, 24)
  iris.fillColor = '#6CE0FF'
  iris.strokeWidth = '6'
  iris.strokeColor = '#000'

  var pupil = new Path.Circle(eCntrX, eCntrY, 15)
  pupil.fillColor = '#000'

  var glint = new Path.Circle(eCntrX, eCntrY, 5)
  glint.fillColor = '#fff'
  glint.position = new Point(eCntrX + 6, eCntrY - 6)

  var ball = new Group([iris, pupil, glint])

}

function onMouseMove(event) {

    // Cursor position
    var csrX = event.point.x
    var csrY = event.point.y

    // Ball position
    var ballX = ball.position.x
    var ballY = ball.position.y

    // Displacement
    var dx = csrX - ballX
    var dy = csrY - ballY

    //Radius
    var r = 5

    //Pythagerous thereom calcs. R
    var R = Math.sqrt(dx*dx+dy*dy)

    x = dx*r/R
    y = dy*r/R

    ball.position = new Point(eCntrX + x, eCntrY + y)

    console.log('x:' + x + 'y:' + y)


}

Source: (StackOverflow)

Paper.js won't resize the canvas correctly

I'm trying out Paper.js for fun, but it seems I'm already stuck at the very start.

Adding resize="true" to the canvas tag is supposed to make the element as high and wide as the browser window. However, doing that results in some rather strange behavior.

I expected the canvas to adjust itself to the viewport right after loading the page, but it didn't do so, which is why I initially thought it didn't resize at all. What actually happens, though, is even more bizarre: The canvas starts out at its default size of 300x150, and when I resize the viewport, it grows - slowly, but indefinitely.

For the record, I've tried using data-paper-resize="true" or just resize instead, or using Chrome instead of Firefox - all to no avail.

I'm not expecting an answer if this problem is caused by some inexplicably weird setup on my end. I am wondering, however, if the problem is common (or even known to exist at all) and has known causes and solutions.

Here's the code I'm using:

<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <script type="text/javascript" src="paper-full.min.js"></script>
        <script type="text/paperscript" canvas="myCanvas">

            var path = new Path();
            path.strokeColor = 'black';
            path.moveTo(new Point(120, 120));
            path.lineTo(new Point(500, 500));

        </script>
    </head>
    <body>
        <canvas id="myCanvas" style="border: 1px dotted red;" resize="true"></canvas>
    </body>
</html>

Source: (StackOverflow)

paper.js how to set up multiple canvases using only javascript

I'm trying to use paper.js in a webapp, but I've been unable to get it to work with multiple canvases. It's like the scopes are getting mixed up between the canvases, so when I intend to draw on canvas 1, it appears on canvas 2.

In each view, I'm initialize the paper like this:

this.mypaper = new paper.PaperScope();
this.mypaper.setup($("myCanvasId")[0]);

When I create new paper objects, I use what should be the local scope:

var circle = new this.mypaper.Path.Circle(10, 10, 5);

However, when I create a circle in view1, it draws it in view2 instead.

I've done a lot of reading, but I still haven't found a clear explanation of how to setup multiple paperscopes or how to isolate views from each other.

Does anyone know how to use multiple canvases with paper.js correctly?


EDIT: I've created a jsFiddle to illustrate the problem: http://jsfiddle.net/94RTX/1/


Source: (StackOverflow)

Paper.js shim config Require.js

I'm trying to initialize an application but seem to be having trouble getting paper js to properly load into my script. I'm using require.js as my AMD loader and am trying to load paper js with the shim module.

Here's my code:

requirejs.config({
    urlArgs: "bust=" + (new Date()).getTime(),//used to keep the browser from caching the scripts as we move
    baseUrl : "scripts",//base scripts page!
    paths : {   
        'jquery' : "../components/jquery/jquery.min", //specific libraries -- can be specified later
        'underscore' : "../components/underscore/underscore",
        'paper' : "../components/paper/paper"
    },
    shim: {
        'underscore': {
            exports: '_'
        },
        'paper' : {
            exports: 'Paper'
        },
    },
});

// initialize the document with a doc ready!

requirejs(["jquery", "underscore", "paper"], function ($, _, Paper) {
    alert(_);
    alert(Paper);
});

The first alert works fine, (the underscore) meaning that it loads okay, but I can't seem to figure out how to get paper.js working properly.

Any help would be greatly appreciated.


Source: (StackOverflow)

Using SVG path syntax in paper.js?

With the raphael.js library, paths are described using the SVG path syntax, (e.g. M98.36,214.208l2.186-1.093V210.2l-3.378,0.117l1.174,4.137L98.36,214.208z, which provides a very compact way to create a shape (especially if your shape is drawn with an external application such as Illustrator).

I'm interested in using the paper.js library (not SVG-based), but a first look at the documentation seems to show that paths are built step by step through object methods. This is a very different approach ("path building" vs "path description", one could say), not very suitable to my needs.

So: is there a way to use SVG Paths in paper.js? Or a similar "path description" solution?

Reference:


Source: (StackOverflow)

Canvas element does not resize when using ReactJS and PaperJS together

I have found that canvas elements correctly resize on window resize when they are inside react components. They also resize correctly when used with PaperJS. However, they do not resize when used with PaperJS and ReactJS together.

Is this an incompatibility between PaperJS and ReactJS or am I instantiating PaperJS incorrectly? I'm calling paper.setup(canvas) in the componentDidMount function of the react component which contains the canvas element. Is that the correct place to do this?

I've included code snippets below.

Note: For some reason the "Run code snippet" feature complains on the ReactJS snippets, so I've included JSFiddle links which work fine.

PaperJS Only [SUCCESS] - Canvas resizes on window resize https://jsfiddle.net/eadlam/srmracev/

// Instantiate the paperScope with the canvas element
var myCanvas = document.getElementById('myCanvas');
paper.setup(myCanvas);

// Draw a circle in the center
var width = paper.view.size.width;
var height = paper.view.size.height;
var circle = new paper.Shape.Circle({
  center: [width / 2, height / 2],
  fillColor: 'grey',
  radius: 10
});

// render
paper.view.draw();
canvas {
  width: 100%;
  height: 100%;
  border: solid 1px red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/paper.js/0.9.22/paper-core.min.js"></script>
<canvas id="myCanvas" resize="true"></canvas>

ReactJS Only [SUCCESS] - Canvas resizes on window resize https://jsfiddle.net/eadlam/0de1mpoa/

var Canvas = React.createClass({
  render: function () {
    return <canvas id="myCanvas" resize="true"></canvas>;
  }
});

React.render(<Canvas/>, document.getElementById('container'));
canvas {
  width: 100%;
  height: 100%;
  border: solid 1px red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.1/JSXTransformer.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.1/react-with-addons.js"></script>
<script src="https://facebook.github.io/react/js/jsfiddle-integration.js"></script>

<div id="container"></div>

ReactJS + CanvasJS [FAIL] - Canvas does not resize on window resize https://jsfiddle.net/eadlam/jLo3opgq/

var Canvas = React.createClass({

    componentDidMount: function () {
        // Instantiate the paperScope with the canvas element
        var myCanvas = document.getElementById('myCanvas');
        paper.setup(myCanvas);
        
        // Draw a circle in the center
        var width = paper.view.size.width;
        var height = paper.view.size.height;
        var circle = new paper.Shape.Circle({
            center: [width / 2, height / 2],
            fillColor: 'grey',
            radius: 10
        });
        
        // render
        paper.view.draw();
    },

    render: function () {
        return <canvas id="myCanvas" resize="true"></canvas>;
    }
});

React.render(<Canvas/>, document.getElementById('container'));
canvas {
  width: 100%;
  height: 100%;
  border: solid 1px red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.1/JSXTransformer.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.1/react-with-addons.js"></script>
<script src="https://facebook.github.io/react/js/jsfiddle-integration.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/paper.js/0.9.22/paper-core.min.js"></script>

<div id="container"></div>


Source: (StackOverflow)