Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 400
Jason Avatar asked Aug 13 '14 01:08

Jason


1 Answers

You are creating new paper project inside the link function, which runs every time for every new use of your directive, in particular, every time a new view is generated.

If you want it to run only once, you can put it in the directive's compile function, or inside a dedicated Angular service or don't close/re-open the view.

The latter can be done simply using ng-show/ng-hide keeping the views inside your DOM instead of changing the routes: https://stackoverflow.com/a/26820013/1614973.

like image 140
Dmitri Zaitsev Avatar answered Oct 17 '22 10:10

Dmitri Zaitsev