简体   繁体   中英

Kinetic.js rendering lines slowly when used in freehand drawing

I'm building a drawing board app in JavaScript using the Kinetic.js library. I'm having an issue with performance in the code I implemented for freehand drawing. Basically, I create an invisible rectangle that is the size of the stage, then attach event handlers to it to determine where to place the drawn line. Each time the mouse moves with the left-click button held down, I add the mouse coordinated to an array and use the points in that array to map my line. There is about a one second delay between the mouse movement and the line actually being rendered. I'm not sure if this delay is caused by an error in my own code or limitations in the Kinetic library. Here is the code:

Whiteboard.prototype.initializeDrawings = function() {
    // Create an invisible shape that will act as an event listener
    var background = new Kinetic.Rect({
        x: 0,
        y: 0,
        width: this.stage.getWidth(),
        height: this.stage.getHeight(),
    });
    this.mouseDrag = false;
    // Attach handlers
    background.on('mousedown touchstart', function(e) {
        this.mouseDrag = true;
        this.currentLine = [];
    });
    // Save a copy of whiteboard instance
    var wb = this;

    background.on('mousemove touchmove', function(e) {
        if(this.mouseDrag === true) {
            this.currentLine.push([e.clientX, e.clientY]);
            wb.userDrawings.clear();
            wb.userDrawings.add(new Kinetic.Line({
                points: this.currentLine,
                stroke: 'red',
                strokeWidth: 4,
                lineCap: 'round',
                lineJoin: 'round'
            }));
            wb.stage.add(wb.userDrawings);
        }
    });
    background.on('mouseup touchstop', function(e) {
        this.mouseDrag = false;
    });
    this.stage.add(new Kinetic.Layer().add(background));
};

Overall, the code works, but because of the requirements for this application, I need to significantly minimize the delay between moving the mouse and rendering the path.

You don't want to be creating a new Kinetic.Line with every mousemove...

To gain better performance:

Instead of creating a new Kinetic.Line with every mousemove, create a single new Line in the mousedown handler and add points to that existing line in mousemove.

// a var which will eventually hold a Kinetic.Line (in your class or in global scope)

var myExistingLine;

// in mousedown

myExistingLine=new Kinetic.Line({ ...

// in mousemove

currentLine.push([mouseX,mouseY]);

myExistingLine.setPoints(currentLine);

myExistingLine.draw();  // or layer.drawScene();

To squeeze maximum performance:

Create a Kinetic.Shape which gives you access to a wrapped canvas context. Let the user draw their polyline on that context. After the user has created their polyline you can put those points in a new Kinetic.Line to get the benefits of a "managed" polyline--and remove the Kinetic.Shape.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM