2

Please see the image attached. I want the retangle (border) not to overlap the other images. For some weird reason only the last image added to the canvas is showing correctly.

enter image description here

Here is my code

<!DOCTYPE HTML>
<html>
<head>
<style>
  body {
    margin: 0px;
    padding: 0px;
  }
</style>
</head>
<body>
<canvas id="myCanvas" width="600" height="600"></canvas>
<script>


  function loadImages(sources, callback) {
    var images = {};
    var loadedImages = 0;
    var numImages = 0;
    // get num of sources
    for(var src in sources) {
      numImages++;
    }
    for(var src in sources) {
      images[src] = new Image();

      images[src].onload = function() {
        if(++loadedImages >= numImages) {
          callback(images);
        }
      };
      images[src].src = sources[src];
    }
  }
  var canvas = document.getElementById('myCanvas');
  var context = canvas.getContext('2d');

  var sources = {
  bg: 'bg2.jpg',
    a: 'a.jpg',
    b: 'b.jpg',
     c: 'c.jpg',
     d: 'd.jpg',
       e: 'e.jpg',
      f: 'f.jpg'

  };



    function drawImageRot(img,x,y,width,height,deg){

var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var rad = deg * Math.PI / 180;
ctx.translate(x + width / 2, y + height / 2);
ctx.rotate(rad);

ctx.rect(width / 2 * (-1), height / 2 * (-1), width, height);
ctx.stroke();
ctx.strokeStyle = 'white';
ctx.lineWidth = 2;
ctx.drawImage(img,width / 2 * (-1),height / 2 * (-1),width,height);
ctx.rotate(rad * ( -1 ) );
ctx.translate((x + width / 2) * (-1), (y + height / 2) * (-1));
}
  loadImages(sources, function(images) {
   drawImageRot(images.bg, 0, 0, 600, 600,0);


   drawImageRot(images.b, 380, 55,277, 184,-20);

 drawImageRot(images.a,-20,-20, 300, 224,-30);
         drawImageRot(images.e, 130, 150,350, 274,0);
    drawImageRot(images.d, 320, 430,277, 184,20);
     drawImageRot(images.f, 0, 380, 240,160,-10);




  });



</script>

razeth01
  • 638
  • 2
  • 11
  • 25

2 Answers2

5

My idea is drawing the rectangle border first and then draw the images. Another thing is the way that you are drawing the rectangles. If you wanna draw rectangles this is the code snippet:

    ctx.beginPath();
    ctx.rect(width / 2 * (-1), height / 2 * (-1), width, height);
    ctx.lineWidth = 5;
    ctx.strokeStyle = 'white';
    ctx.stroke();

Another thing too, is the way that you turn back to the original position. There's a more simple way with the use of ctx.save() and ctx.restore(). This is the way that canvas propose you to turn back when you are doing transformations.

So here is my solution I hope that you enjoy it. Thanks Sergio.

function loadImages(sources, callback) {
    var images = {};
    var loadedImages = 0;
    var numImages = 0;
    // get num of sources
    for(var src in sources) {
      numImages++;
    }
    for(var src in sources) {
      images[src] = new Image();

      images[src].onload = function() {
        if(++loadedImages >= numImages) {
          callback(images);
        }
      };
      images[src].src = sources[src];
    }
  }


  var canvas = document.getElementById('myCanvas');
  var context = canvas.getContext('2d');


  var sources = {
  bg: 'bg2.jpg',
    a: 'a.jpg',
    b: 'b.jpg',
     c: 'c.jpg',
     d: 'd.jpg',
       e: 'e.jpg',
      f: 'f.jpg'

  };


function drawRectanlesBorders(img,x,y,width,height,deg){

        var c=document.getElementById("myCanvas");
        var ctx=c.getContext("2d");
        var rad = deg * Math.PI / 180;

        ctx.save();
        ctx.translate(x + width / 2, y + height / 2);
        ctx.rotate(rad);
        ctx.beginPath();
        ctx.rect(width / 2 * (-1), height / 2 * (-1), width, height);
        ctx.lineWidth = 5;
        ctx.strokeStyle = 'white';
        ctx.stroke();
        ctx.restore();
    }


function drawImageRot(img,x,y,width,height,deg){

        var c=document.getElementById("myCanvas");
        var ctx=c.getContext("2d");
        var rad = deg * Math.PI / 180;

        ctx.save();
        ctx.translate(x + width / 2, y + height / 2);
        ctx.rotate(rad);
        ctx.drawImage(img,width / 2 * (-1),height / 2 * (-1),width,height);
        ctx.restore();
    }


loadImages(sources, function(images) {

            //draw background  image
        drawImageRot(images.bg, 0, 0, 600, 600,0);

           //draw borders
        drawRectanlesBorders(images.b, 380, 55,277, 184,-20);


        drawRectanlesBorders(images.a,-20,-20, 300, 224,-30);
                drawRectanlesBorders(images.e, 130, 150,350, 274,0);
        drawRectanlesBorders(images.d, 320, 430,277, 184,20);
        drawRectanlesBorders(images.f, 0, 380, 240,160,-10);

         //draw images
        drawImageRot(images.b, 380, 55,277, 184,-20);

        drawImageRot(images.a,-20,-20, 300, 224,-30);
                drawImageRot(images.e, 130, 150,350, 274,0);
        drawImageRot(images.d, 320, 430,277, 184,20);
        drawImageRot(images.f, 0, 380, 240,160,-10);

  });

You should decide the order to paint the images too see what you really wanna see.

sergio
  • 619
  • 6
  • 16
  • 1
    +1 Your solution looks pretty good! One improvement would be to create the canvas & context variables outside and before the functions--no need to recreate them with each function call. – markE Oct 01 '13 at 16:06
  • Yes, you're right. I made this solution too fast, copying and pasting and I have forgot that detail. Thanks for your observation. – sergio Oct 01 '13 at 17:05
  • If only I could accept your answer 20 times. Works perfectly! Thanks man. – razeth01 Oct 02 '13 at 06:40
3

Rather than setting the z-index values as negative, try increasing the values (in positive number range) for each new image.

Edit: Found the similar problem (solved already). It guides through various optimum methods of drawing on canvas.

Community
  • 1
  • 1
Vikram Tiwari
  • 3,615
  • 1
  • 29
  • 39