Skip to main content
Known Participant
Feb 7, 2025 8:28 PM UTC
Question

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

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);
    }
}

    9 replies

    kglad
    Community Expert
    Community Expert
    Feb 7, 2025 8:45 PM UTC

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

    Translate
    dane AAuthor
    Known Participant
    Feb 7, 2025 8:50 PM UTC

    it has, here is the entire code in pastebin:

     

    jsfl:

    https://pastebin.com/qguhStLK

     

    Xml:
    https://pastebin.com/tRNYJ4b4

     

     

    Translate
    Firewood:D
    Inspiring
    Feb 8, 2025 3:20 AM UTC

    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

    Translate