0

I have 2 canvases.Wat I do is I draw shapes(i.e a line) on the second canvas.When I want to apply transformations(rotate,scale,etc) to this drawn line, I modify the context of first canvas and draw my second canvas on it.Works perfectly.Now when i want to again draw shapes(i.e a line) on second canvas (with transformations),I draw first canvas on second and draw a line on it.Works perfectly fine.Now the problem occurs.When i again want to apply transformations(rotate,scale,etc) to this line i modify the context of first canvas and draw second canvas on it.But this time,I get abrupt changes when I draw on first canvas(draw second canvas).This is due to the transformations applied by drawing 1st canvas on the second and again drawing second canvas to first.Is there a way to change(reset or modify) anything thats already drawn on canvas?

var cantem = document.getElementById('canvasTemp1');  //second canvas
    var ctxtem = cantem.getContext('2d');

    var canMan = document.getElementById('canvasTempMan');    //first canvas
    canMan.style.visibility = "visible";
    var ctxcanman = canMan.getContext('2d');

    var sWidth = getCanvasWidth();               //returns canvas width
    var sHeight = getCanvasHeight();             //returns canvas height

    canMan.height = sHeight;
    canMan.width = sWidth;

    cantem.style.visibility = "hidden";



    ctxcanman.setTransform(1, 0, 0, 1, 0, 0);
    ctxcanman.clearRect(0, 0, cantem.width, cantem.height);

    ctxcanman.translate(sWidth / 2, sHeight / 2);


    ctxcanman.scale(ZoomFactor, ZoomFactor);
    ctxcanman.rotate(RotateAngle * Math.PI / 180);

    ctxcanman.translate(-sWidth / 2, -sHeight / 2);


    ctxcanman.drawImage(cantem, 0, 0, cantem.width, cantem.height, OffsetX, OffsetY, sWidth, sHeight);
    ctxcanman.save();

Now here I draw my first canvas to second-->

 var can = document.getElementById('canvasTempMan');
    can.style.visibility = "hidden";
    var cantem = document.getElementById('canvasTemp1');
    var ctxannotate = cantem.getContext("2d");
    ctxannotate.setTransform(1, 0, 0, 1, 0, 0);
    ctxannotate.clearRect(0, 0, cantem.width, cantem.height);

    ctxannotate.save();
    ctxannotate.drawImage(can, 0, 0, cantem.width, cantem.height, OffsetX, OffsetY, can.width, can.height);

I draw(shapes i.e line) on my second canvas using mouse events and simple context functions like moveTo,lineTo,etc.

AkshayJ
  • 771
  • 6
  • 15
  • Read up on *transformation matrices*. They can save all the accumulated transforms (translates, rotates, scales) that have been done on any of your individual shapes and allow the transforms to be reapplied if you later need to continue transforming any shape. – markE Jun 12 '15 at 05:19
  • @markE Thats fine..But is it possible to reset the transformations on already drawn canvas?? – AkshayJ Jun 12 '15 at 05:31
  • No. Nothing already drawn on the canvas can be transformed. **To change the position of anything on the canvas the *only* method is:** (#1) clear the canvas, (#2) calculate the new positions of the shapes, (#3) redraw all the shapes in their new positions. Step#2 is where transformation matrices are useful because they let you "remember" all the previous movements, scalings and rotations of the shapes. ;-) – markE Jun 12 '15 at 05:35
  • My scenario is abit different...1)I draw on canvas..2)apply transformations..3)again draw..4)and again try to transform everything thats drawn previously... – AkshayJ Jun 12 '15 at 05:38
  • Sure, you can pre-calculate where the shapes will be next, but for those transformations to be visually applied on the canvas you must then clear the canvas and redraw all the shapes in their new positions. Again, nothing already on the canvas can be repositioned without clearing and redrawing...shapes on the canvas can never be repositioned. :-) – markE Jun 12 '15 at 05:42
  • So I dont have any wayout for my problem is what u mean?? – AkshayJ Jun 12 '15 at 05:45
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/80349/discussion-between-akshayj-and-marke). – AkshayJ Jun 12 '15 at 05:47
  • Well, your way out is to use canvas as intended: (1) draw something, (2) let the user view the content, (3) erase the canvas, (4) draw something new for the user to view. Shapes drawn on canvas are like your family photo in a frame. You can't reposition your wife further to the left--it's just a picture. ;-) – markE Jun 12 '15 at 05:48

1 Answers1

0

There are no elements within the canvas. What is drawn on the canvas can in general not be isolated (unless you're talking about single pixle manipulations).

Instead of storing your work (shapes, rotations and movements) on your canvas, you can store all that in your code, in the form of objects, then you can handle these objects individually be it further manipulation of even deletion.

If you "record" all your actions, you'll be in full control on what will be shown on the canvas.

You can for example have a function that creates a line:

function myLine (xStart, yStart, xEnd, yEnd, deg) {
    this.xS = xStart;
    this.yS = yStart;
    this.xE = xEnd;
    this.xE = yEnd;

    //if needed you can also save the number of degrees that the line has been rotated
    this.deg = deg;
}

Simply make an empty array at the start

var myLines = new Array();

and add your lines to it:

var newLine = new myLine(100,50,200,70,0);
myLines.push(newLine);

The same can be done with circles for example

function myCircle(x,y,radius) {
    this.x = x;
    this.y = y;
    this.r = radius;
    //no point in trying to rotate a circle so leaving the degrees out
}

This way, by storing your work, you can draw it all (or chosen parts thereof) at once by looping through your arrays of shapes.

You can still use two canvases, one to display all your drawn shapes and another one to display your actions connected to your mousemove-events, just like you describe in your question.

Drawing stuff while scale()/rotate()/translate() is active

See here for answer: Returning un-transformed mouse coordinates after rotating an object on html5 canvas

Community
  • 1
  • 1
Niddro
  • 1,705
  • 2
  • 12
  • 24
  • how can i restore the transformations already applied to my shapes(on canvas 2) and drawn?...While is am drawing canvas2 on first canvas?? – AkshayJ Jun 11 '15 at 07:22
  • Before you start changing the rotation, scaling or transformations of your canvas, put this in your code: `ctx.save();` Then do whatever you want to the canvas, but in the end you restore all those settings to your saved state by putting `ctx.restore();`. – Niddro Jun 11 '15 at 07:29
  • Assume i draw a line at 100% zoom factor;now I zoom in this line at 300% and again draw another line.When i further zoomin this canvas with 2 lines i get a abrupt change because line 2 was already drawn at 300% zoom factor. – AkshayJ Jun 11 '15 at 07:30
  • It depends on what you want. A line is still a line even if it's drawn during a 100% or a 300% zoom, right? When you finally zoom out to 100%, you want the lines to look the same, correct? – Niddro Jun 11 '15 at 07:34
  • Yeah...so what you say is to store the line coordinates in a array(howmany lines i draw) and then use this array of lines to draw on a canvas and then apply transformations each time?...isnt it?? – AkshayJ Jun 11 '15 at 07:38
  • Essentially yes. However, the scale and transformation might not be line-specific but the state of the entire canvas. In my answer above, I have answered the question "Is there a way to change(reset or modify) anything thats already drawn on canvas?". If you feel that I didn't answer the right question, please modify your question above so that we keep any discussions away from the comments. If you feel I answered your question but you have more, please mark my answer as correct and make a new question. – Niddro Jun 11 '15 at 08:04
  • This doesnt solve my question even though i save those lines in a array.How can I get the coordinates of lines drawn on a rotated or scaled context?...:( – AkshayJ Jun 12 '15 at 12:00
  • @AkshayJ see updated answer, it's already been answered by another user =) – Niddro Jun 12 '15 at 16:34
  • @Niddro..thanx for the help..But ctx.currentTransform isnt supported cross-browser :(...do you knw any other way to get the current transformation matrix? – AkshayJ Jun 15 '15 at 04:43
  • @AkshayJ, it would be for yourself to keep track on the current state with variables in your code. – Niddro Jun 15 '15 at 04:57