Skip to main content
Known Participant
February 7, 2025
Question

Can someone take a look at this tool, or maybe suggest a new one?

  • February 7, 2025
  • 1 reply
  • 947 views

My Pixel Line art Tool has broken, it has worked for years, and its finally Degraded to the point where it is spamming errors: 

 

Errors:

 

Error in drawLine: moveTo: Argument number 1 is invalid. Error in drawLineOnStage: addPoint: Argument number 2 is invalid.

 

var snap = true;
var dashlength = 0;
var dashspacing = 0;
var joinPoints = true;
var done = true;
var almostDone = 0;
var thick = 1;
var stPoint = null;
var snapArray = null;

function configureTool() {
    theTool = fl.tools.activeTool;
    theTool.setToolName("pxLine");
    theTool.setIcon("pxLine.png");
    theTool.setMenuString("Pixel Line Tool");
    theTool.setToolTip("Pixel Line Tool");
    theTool.setOptionsFile("pxLine.xml");
    theTool.setPI("shape");
}

function notifySettingsChanged() {
    theTool = fl.tools.activeTool;
    snap = theTool.snap;
    dashlength = theTool.dashlength;
    dashspacing = theTool.dashspacing;
}

function setCursor() {
    fl.tools.setCursor(2);
}

function activate() {
    snapArray = [-3.142, -2.678, -2.356, -2.034, -1.571, -1.108, -0.785, -0.4634, 0,
        0.4634, 0.785, 1.108, 1.571, 2.034, 2.356, 2.678, 3.142
    ];
    fl.drawingLayer.beginDraw();
}

function deactivate() {
    fl.drawingLayer.endDraw();
}

function mouseDown() {
    try {
        var stroke = fl.getDocumentDOM().getCustomStroke("toolbar");
        thick = Math.max(1, Math.round(stroke.thickness));
        stPoint = fl.tools.penDownLoc;
        if (stPoint) {
            roundOff(stPoint);
        }
    } catch (e) {
        fl.trace("Error in mouseDown: " + e.message);
    }
}

function mouseMove() {
    try {
        if (done) {
            if (fl.tools.mouseIsDown && stPoint) {
                fl.drawingLayer.beginFrame();
                var penPoint = fl.tools.penLoc;
                if (penPoint) {
                    constrainPrincipal(stPoint, penPoint);
                    var line = buildLine(stPoint, penPoint);
                    drawLine(line);
                }
                fl.drawingLayer.endFrame();
            } else {
                drawPreview();
            }
        } else {
            fl.drawingLayer.beginFrame();
            fl.drawingLayer.endFrame();
        }

        if (almostDone > 0) {
            almostDone++;
            if (almostDone > 5) {
                almostDone = 0;
                done = true;
            }
        }
    } catch (e) {
        fl.trace("Error in mouseMove: " + e.message);
    }
}

function mouseUp() {
    try {
        done = false;
        almostDone = 0;

        var endPoint = fl.tools.penLoc;
        if (endPoint) {
            endPoint = fl.tools.snapPoint(endPoint);
            constrainPrincipal(stPoint, endPoint);
            var line = buildLine(stPoint, endPoint);
            drawLineOnStage(line);
        }

        almostDone = 1;
        fl.drawingLayer.beginFrame();
        fl.drawingLayer.endFrame();
    } catch (e) {
        fl.trace("Error in mouseUp: " + e.message);
    }
}

function drawPreview() {
    try {
        thick = 1;
        var penPoint = fl.tools.penLoc;
        if (!penPoint) return;

        roundOff(penPoint);
        var v = fl.getDocumentDOM().viewMatrix;
        
        if (!v) return;
        
        var e = v.tx;
        var f = v.ty;
        var p = penPoint;

        var a1 = p.x * v.a + e;
        var b1 = p.y * v.c;
        var c1 = p.x * v.b + f;
        var d1 = p.y * v.d;

        var a2 = a1 + thick * v.a;
        var b2 = b1 + thick * v.c;
        var c2 = c1 + thick * v.b;
        var d2 = d1 + thick * v.d;

        fl.drawingLayer.beginFrame();
        fl.drawingLayer.moveTo(a1 + b1, c1 + d1);
        fl.drawingLayer.lineTo(a1 + b2, c1 + d2);
        fl.drawingLayer.lineTo(a2 + b2, c2 + d2);
        fl.drawingLayer.lineTo(a2 + b1, c2 + d1);
        fl.drawingLayer.lineTo(a1 + b1, c1 + d1);
        fl.drawingLayer.endFrame();
        fl.tools.setCursor(2);
    } catch (e) {
        fl.trace("Error in drawPreview: " + e.message);
    }
}

function constrainPrincipal(p1, p2) {
    if (!p1 || !p2 || !snapArray) return;
    
    var sn = snap;
    if (fl.tools.shiftIsDown) {
        sn = !sn;
    }

    if (sn) {
        var dx = (p2.x - p1.x);
        var dy = (p2.y - p1.y);
        var angle = Math.atan2(dy, dx);
        var closeI = findClosest(angle, snapArray);
        var closeAng = snapArray[closeI];
        
        if (Math.abs(dy) > Math.abs(dx)) {
            if (closeAng !== 0) {
                p2.x = p1.x + dy / Math.tan(closeAng);
            }
        } else {
            if (closeAng !== Math.PI/2 && closeAng !== -Math.PI/2) {
                p2.y = p1.y + dx * Math.tan(closeAng);
            }
        }
    }
}

function findClosest(val, arr) {
    var closest = 0;
    var lowD = 5;
    for (var i = 0; i < arr.length; i++) {
        var d = Math.abs(arr[i] - val);
        if (d < lowD) {
            closest = i;
            lowD = d;
        }
    }
    return closest;
}

function roundOff(point) {
    if (point) {
        point.x = Math.floor(point.x);
        point.y = Math.floor(point.y);
    }
}

function buildLine(from, to) {
    if (!from || !to) return [];
    
    var line = [];
    var x1 = Math.floor(from.x);
    var y1 = Math.floor(from.y);
    var x2 = to.x;
    var y2 = to.y;
    
    var dx = x2 - x1;
    var dy = y2 - y1;

    y2 = dy < 0 ? Math.ceil(y2) : Math.floor(y2);
    x2 = dx < 0 ? Math.ceil(x2) : Math.floor(x2);

    line.push({x: x1, y: y1});

    if (Math.abs(dx) > Math.abs(dy)) {
        var m = dy / dx;
        var b = y1 - m * x1;
        var step = dx < 0 ? -1 : 1;
        var counter = 1;
        
        while (x1 !== x2) {
            x1 += step;
            if (dashlength === 0 || ((counter % (dashlength + dashspacing)) < dashlength)) {
                line.push({x: x1, y: Math.round(m * x1 + b)});
            }
            counter++;
        }
    } else if (dy !== 0) {
        var m = dx / dy;
        var b = x1 - m * y1;
        var step = dy < 0 ? -1 : 1;
        var counter = 1;
        
        while (y1 !== y2) {
            y1 += step;
            if (dashlength === 0 || ((counter % (dashlength + dashspacing)) < dashlength)) {
                line.push({x: Math.round(m * y1 + b), y: y1});
            }
            counter++;
        }
    }
    
    return line;
}

function drawLine(line) {
    if (!line || line.length < 2) return;
    
    try {
        var v = fl.getDocumentDOM().viewMatrix;
        if (!v) return;
        
        var dy = line[line.length - 1].y - line[0].y;
        var dx = line[line.length - 1].x - line[0].x;
        
        var a = thick;
        var b = 1;
        var c = thick;
        var d = 1;
        
        var e = v.tx;
        var f = v.ty;
        
        for (var i = 0; i < line.length; i++) {
            var p = line[i];
            p.x -= Math.floor(c/2);
            p.y -= Math.floor(d/2);
            
            var a1 = p.x * v.a + e;
            var b1 = p.y * v.c;
            var c1 = p.x * v.b + f;
            var d1 = p.y * v.d;
            
            var a2 = a1 + a * v.a;
            var b2 = b1 + b * v.c;
            var c2 = c1 + c * v.b;
            var d2 = d1 + d * v.d;

            fl.drawingLayer.moveTo(a1 + b1, c1 + d1);
            fl.drawingLayer.lineTo(a1 + b2, c1 + d2);
            fl.drawingLayer.lineTo(a2 + b2, c2 + d2);
            fl.drawingLayer.lineTo(a2 + b1, c2 + d1);
            fl.drawingLayer.lineTo(a1 + b1, c1 + d1);
        }
    } catch (e) {
        fl.trace("Error in drawLine: " + e.message);
    }
}

function drawLineOnStage(line) {
    if (!line || line.length < 2) return;
    
    try {
        var path = fl.drawingLayer.newPath();
        var dy = line[line.length - 1].y - line[0].y;
        var dx = line[line.length - 1].x - line[0].x;
        var ang = Math.atan2(dy, dx);
        
        var a, b, c, d;
        
        if ((ang > Math.PI/4 && ang < 3*Math.PI/4) ||
            (ang < -Math.PI/4 && ang > -3*Math.PI/4)) {
            a = thick;
            b = 1;
            c = Math.floor(thick/2);
            d = 0;
        } else {
            a = 1;
            b = thick;
            c = 0;
            d = Math.floor(thick/2);
        }

        if ((line[line.length - 1].x - line[0].x > 0 && line[line.length - 1].y - line[0].y < 0) ||
            (line[line.length - 1].x - line[0].x < 0 && line[line.length - 1].y - line[0].y > 0)) {
            for (var i = 0; i < line.length; i++) {
                var p = line[i];
                p.x -= c;
                p.y -= d;
                path.addPoint(p.x, p.y + b);
                path.addPoint(p.x + a, p.y + b);
                path.addPoint(p.x + a, p.y);
                path.addPoint(p.x, p.y);
                path.addPoint(p.x, p.y + b);
            }
        } else {
            for (var i = 0; i < line.length; i++) {
                var p = line[i];
                p.x -= c;
                p.y -= d;
                path.addPoint(p.x, p.y);
                path.addPoint(p.x + a, p.y);
                path.addPoint(p.x + a, p.y + b);
                path.addPoint(p.x, p.y + b);
                path.addPoint(p.x, p.y);
            }
        }
        path.makeShape(false, true);
    } catch (e) {
        fl.trace("Error in drawLineOnStage: " + e.message);
    }
}

    1 reply

    kglad
    Community Expert
    Community Expert
    February 7, 2025

    unless the code changed, it wouldn't "degrade"

    dane AAuthor
    Known Participant
    February 7, 2025

    it has, here is the entire code in pastebin:

     

    jsfl:

    https://pastebin.com/qguhStLK

     

    Xml:
    https://pastebin.com/tRNYJ4b4

     

     

    Firewood:D
    Inspiring
    February 8, 2025

    Are you referring to the pixel tool pixeltools? I just tried it in animate2022 and found that it doesn't work with a handwriting tablet, but it works with a mouse. This should be the problem you are talking about, right?
    Everything else is normal