Skip to content Skip to sidebar Skip to footer

Draw On Rotated Canvas

I have a canvas where I can draw with the mouse. At some point I can rotate and scale the canvas container. What I would like is to be able to still draw, but the problem that I ha

Solution 1:

Finally I've got this working!!

All credits goes to Blindman67, I've modified his code to adapt it to my needs.

HTML

<divid="main"></div><br><spanid="screen"style="border: 2px solid red;"></span><spanid="world"style="border: 2px solid blue;"></span><buttonid="btnRotate">ROTATE!</button>

JS

var canvas = null;
var ctx = null;
var gridStart = null;
var gridEnd = null;
var gridStepMajor = null;
var gridStepMinor = null;
var minorCol = null;
var majorCol = null;
var minorWidth = null;
var majorWidth = null;

var scale = 1;
var rotation = 45;

    var painting = false,
    lastX = 0,
    lastY = 0,
    lineThickness = 1;

var matrix = [1, 0, 0, 1, 0, 0];      // normal matrixvar invMatrix = [1, 0, 0, 1];   // inverse matrixfunctioncreateMatrix(x, y, scale, rotation)
{
    rotation = rotation * (Math.PI / 180);

    var m = matrix; // just to make it easier to type and readvar im = invMatrix; // just to make it easier to type and read// create the scale and rotation part of the matrix
    m[3] =   m[0] = Math.cos(rotation) * scale;
    m[2] = -(m[1] = Math.sin(rotation) * scale);

    // translation
    m[4] = x;
    m[5] = y;

    // calculate the inverse transformation// first get the cross product of x axis and y axis
    cross = m[0] * m[3] - m[1] * m[2];

    // now get the inverted axies
    im[0] =  m[3] / cross;
    im[1] = -m[1] / cross;
    im[2] = -m[2] / cross;
    im[3] =  m[0] / cross;
}

// function to transform to world spacefunctiontoWorld(x,y)
{
    var xx, yy, m;
    m = invMatrix;
    xx = x - matrix[4];
    yy = y - matrix[5];
    return{
       x:   parseInt(xx * m[0] + yy * m[2], 10) ,
       y:   parseInt(xx * m[1] + yy * m[3], 10)
    }
}
//----------------------------------------------------------------------------var mouseWorldPos = toWorld(0, 0);

functiondraw()
{
    gridStart = 0;
    gridEnd = canvas.width;
    gridStepMajor = canvas.width / 10;
    gridStepMinor = canvas.width / 20;
    minorCol = "#999";
    majorCol = "#000";
    minorWidth = 1;
    majorWidth = 3;

    ctx.lineWidth = 2;
    ctx.beginPath();
    ctx.strokeStyle = majorCol ;
    ctx.lineWidth = majorWidth;

    for(i = gridStart; i <= gridEnd; i+= gridStepMajor)
    {
        ctx.moveTo(gridStart, i);
        ctx.lineTo(gridEnd, i);
        ctx.moveTo(i, gridStart);
        ctx.lineTo(i, gridEnd);
    }
    ctx.stroke();

    ctx.strokeStyle = minorCol;
    ctx.lineWidth = minorWidth;
    for(i = gridStart+gridStepMinor; i < gridEnd; i+= gridStepMinor)
    {
        ctx.moveTo(gridStart, i);
        ctx.lineTo(gridEnd, i);
        ctx.moveTo(i, gridStart);
        ctx.lineTo(i, gridEnd);
    }
    ctx.stroke();

    ctx.fillStyle = "red";
    ctx.strokeStyle = "red";
    ctx.lineWidth = 4;
    ctx.beginPath();
    ctx.arc(50, 50, 6, 0, Math.PI*2);
    ctx.fill();
}

functiondemo()
{
    canvas = document.createElement("canvas");
    canvas.width = 500;
    canvas.height = 300;
    canvas.ctx = canvas.getContext("2d");

    ctx = canvas.ctx;

    $("#main").append(canvas);

    draw();
}

var timer = 0;
var timerStep = 0.5;
var seconds = 15;

functionrotate()
{
    timer += timerStep;

    var cw = canvas.width / 2;
    var ch = canvas.height / 2;

    ctx.setTransform(1, 0, 0, 1, 0, 0);  // reset the transform so we can clear
    ctx.clearRect(0, 0, canvas.width, canvas.height);  // clear the canvascreateMatrix(cw, ch -50, scale, timer);

    var m = matrix;
    ctx.setTransform(m[0], m[1], m[2], m[3], m[4], m[5]);

    draw();

    if(timer <= rotation )
    {
        requestAnimationFrame(rotate);
    }
}

$(document).ready(function()
{
    demo();

    $(canvas).mousedown(function(e)
    {
        painting = true;
        ctx.fillStyle = "#0000FF";

        mouseWorldPos = toWorld(e.pageX, e.pageY);

        lastX = mouseWorldPos.x;
        lastY = mouseWorldPos.y;
    });

    $(canvas).mousemove(function(e)
    {
        $("#screen").text("X: " + e.pageX + " - Y:" + e.pageY);

        mouseWorldPos = toWorld(e.pageX, e.pageY);
        $("#world").text("X: " + mouseWorldPos.x + " - Y:" + mouseWorldPos.y);

        if (painting)
        {
            mouseX = mouseWorldPos.x;
            mouseY = mouseWorldPos.y;

            // find all points betweenvar x1 = mouseX,
                x2 = lastX,
                y1 = mouseY,
                y2 = lastY;


            var steep = (Math.abs(y2 - y1) > Math.abs(x2 - x1));
            if (steep){
                var x = x1;
                x1 = y1;
                y1 = x;

                var y = y2;
                y2 = x2;
                x2 = y;
            }
            if (x1 > x2) {
                var x = x1;
                x1 = x2;
                x2 = x;

                var y = y1;
                y1 = y2;
                y2 = y;
            }

            var dx = x2 - x1,
                dy = Math.abs(y2 - y1),
                error = 0,
                de = dy / dx,
                yStep = -1,
                y = y1;

            if (y1 < y2) {
                yStep = 1;
            }

            lineThickness = 5 - Math.sqrt((x2 - x1) *(x2-x1) + (y2 - y1) * (y2-y1))/10;
            if(lineThickness < 1){
                lineThickness = 1;
            }

            for (var x = x1; x < x2; x++) {
                if (steep) {
                    ctx.fillRect(y, x, lineThickness , lineThickness );
                } else {
                    ctx.fillRect(x, y, lineThickness , lineThickness );
                }

                error += de;
                if (error >= 0.5) {
                    y += yStep;
                    error -= 1.0;
                }
            }

            lastX = mouseX;
            lastY = mouseY;
        }
    });

    $(canvas).mouseup(function(e)
    {
        painting = false;
    });

    $("#btnRotate").click(function()
    {
        rotate();
    });
});

CSS

#main{outline: 1px solid orange; display: inline-block; position: relative;}
span{position: relative;}

DEMO

https://jsfiddle.net/mgf8uz7s/

Post a Comment for "Draw On Rotated Canvas"