confusion on drawImage() method coordinates - javascript

image coordinates always confuses me.so to test this i did a little example.i have an image which is 500x500.i have two canvas and i want to draw the image on the first canvas .the size of the canvas is 500x500.the canvas is 50 px from the top and 250 px from the left.the image is not drawn on the canvas.how i can i solve this & please correct me if i am doing any wrong here
there are eight co-ordinates in draw image function (which confuses me most)
1st=0,start_X of source image;
2nd=0,start_Y of source image;
3rd=500,destination_x of source image;
4th=500,destination_Y of source image;
5th=0,canvas_start_X ;
6th=0,canvas_start_Y;
7th=500,canvas_finish_X;
8th=500,canvas_finish_Y;
jsfiddle
code:
<html>
<head>
<style>
*{margin:0px;padding:0px;}
#mydiv{
width:100%;
height:100%;
background-color:black;
}
#mycanvas1{
width:500px;
height:500px;
background-color:white;
border:1px solid white;
margin-top:50px;
margin-left:250px;
}
</style>
</head>
<body>
<div id="mydiv">
<canvas id="mycanvas1"></canvas>
<canvas id="mycanvas2"></canvas>
</div>
<script >
function makeit(){
var canvas1=document.getElementById("mycanvas1");
var ctxbg=canvas1.getContext('2d');
var bgImage=new Image();
bgImage.src="bg.jpg";
alert(bgImage.width+" " +bgImage.height);
bgImage.addEventListener('load',drawBg,false);
function drawBg(){
ctxbg.drawImage(bgImage,0,0,500,0,0,,500,500);
}
}
window.onload=makeit;
</script>
</body>

If the most confusing way of drawing images to the canvas (in the 2d context) confuses you most why don't you try one of the less confusing ways?
ctx.drawImage(img,x,y);
or
ctx.drawImage(img,x,y,width,height);
You should also set your canvas width / height properties on the canvas element, not in the css. The css does not change the actual size of the canvas, the amount of pixels used, just the way it "looks", aka is rendered in the browser. You could display a 1x1 pixels sized canvas in 800x600 and it would still be 1 pixel in size.
What happened in your case is that without width / height properties specified it defaulted to 300x150 in size, so only rendering the top left corner of your image scaled up to 500x500 pixels via css.
That's how you want to set the dimensions.
<canvas id="mycanvas1" width="500" height="500"></canvas>

The 3rd & 4th numeric arguments specify the width and height of the area that is to be clipped from the original image. The 3rd and 4th arguments are used for clipping a subsection from the original image.
The 7th & 8th numeric arguments specify the width and height of the image to be drawn on the canvas. The 7th and 8th arguments are used for scaling the original image as it is drawn on the canvas.
Think of the extended drawImage like this:
drawImage(
sourceImage,
// clip a subsection of the original image
// starting at clipX,clipY
// with the clipped subsection being clipWidth and clipHeight in size
clipX,clipY,clipWidth,clipHeight,
// draw that clipped subsection on the canvas at canvasX,canvasY
// with optional scaling to scaledWidth,scaledHeight
// (no scaling if clipWidth==scaledWidth && clipHeight==scaledHeight)
canvasX,canvasY,scaledWidth,scaledHeight
);
So you can load and draw your image like this:
var bgImage=new Image();
bgImage.onload=function(){
ctxbg.drawImage(bgImage,0,0)
}
bgImage.src="bg.jpg";
Since your not clipping or scaling the original image as you draw it to canvas, there's no reason to use the extended version of drawImage. But the extended version of drawImage would still work if you specify no clipping and no scaling.
This code will draw the entire bgImage on the canvas (assuming the canvas is large enough to hold the full bgImage):
var bgImage=new Image();
bgImage.onload=function(){
ctxbg.drawImage(bgImage,0,0,bgImage.width,bgImage.height,0,0,bgImage.width,bgImage.height)
}
bgImage.src="bg.jpg";
Example code:
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
#mydiv{
width:1000px;
height:1000px;
background-color:black;
}
#mycanvas1{
width:500px;
height:500px;
background-color:white;
border:1px solid white;
margin-top:50px;
margin-left:250px;
}
</style>
<script>
window.onload=function(){
var canvas1=document.getElementById("mycanvas1");
var ctx=canvas1.getContext("2d");
var ctxbg=canvas1.getContext('2d');
var bgImage=new Image();
bgImage.onload=function(){
var w=bgImage.width;
var h=bgImage.height;
ctxbg.drawImage(bgImage,0,0,w,h,0,0,w,h);
}
bgImage.src="https://dl.dropboxusercontent.com/u/139992952/multple/bgImage1.jpg";
};
</script>
</head>
<body>
<div id="mydiv">
<canvas id="mycanvas1" width=300 height=300></canvas>
</div>
</body>
</html>

Related

HTML5 Canvas | Pattern to reveal overlayed line art based on pattern pixel color

I need to apply, via canvas element, a one color (black) bitmap image (line art) onto a 2 color (red and yellow) bitmap image (pattern) and have only the red pixels of that pattern be colored by the overlayed line art, kinda like an intersect. I saw this:
https://developer.mozilla.org/en/docs/Web/Guide/HTML/Canvas_tutorial/Compositing (see globalCompositeOperation > Darker method ) and wondered if that effect is what I need. Since that method no longer appears to be supported, is there a way to simulate such an effect? All images used for this only contain spot colors (100% red, 100% yellow, 100% black, 100% white). Any javascript code sample or hint(s) leading to a solution would be awesome. Thx for input.
If you can isolate just the red portion onto a separate image then you can use compositing to recolor where black intersects red.
Otherwise you can grab all the pixel colors on both images using context.getImageData.
Then you can change the red pixels to black where red & black intersect.
Example code and a Demo: http://jsfiddle.net/m1erickson/pcsmbr22/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; margin:20px; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var canvasB=document.getElementById("black");
var ctxB=canvasB.getContext("2d");
var canvasC=document.getElementById("color2");
var ctxC=canvasC.getContext("2d");
ctxB.fillRect(50,50,50,100);
ctxC.fillStyle='yellow';
ctxC.fillRect(75,50,50,50);
ctxC.fillStyle='red';
ctxC.fillRect(75,100,50,50);
var iDataB=ctxB.getImageData(0,0,canvasB.width,canvasB.height);
var dataB=iDataB.data;
var iDataC=ctxC.getImageData(0,0,canvasC.width,canvasC.height);
var dataC=iDataC.data;
// copy yellow-red onto results canvas
ctx.drawImage(canvasC,0,0);
var iData=ctx.getImageData(0,0,canvas.width,canvas.height);
var data=iData.data;
// copy black pixels when intersecting red pixels
for(var i=0;i<dataC.length;i+=4){
var isBlack=(dataB[i]==0 && dataB[i+1]==0 && dataB[i+2]==0 && dataB[i+3]==255);
var isRed=(dataC[i]==255 && dataC[i+1]==0 && dataC[i+2]==0 && dataC[i+3]==255);
if(isBlack && isRed){
data[i]=0;
data[i+1]=0;
data[i+2]=0;
data[i+3]=255;
}
}
ctx.putImageData(iData,0,0);
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="black" width=200 height=200></canvas>
<canvas id="color2" width=200 height=200></canvas>
<canvas id="canvas" width=200 height=200></canvas>
</body>
</html>

HTML5 Canvas merging to rectangles to form a new shape

I have a page that you will be able to draw squares on it. The squares will represent a room, so you have one square, then you make another over the first square and then two will join
It will looks like this
http://puu.sh/bllo7/95e2112d79.png
And functions like so http://jsfiddle.net/bLenxexL/
I need to figure out how get them squares to make another shape that will look like the image on the right of the picture above.
If this helps, the square info is stored in points in this format
[
{
start: {x: 312, y: 164},
end: {x: 734, y: 371}
},
{
start: {x: 696, y: 304},
end: {x: 1060, y: 561}
}
]
Any links to resources that will help me do this will be of much help thank you
You can use compositing to create a single stroke around your combined rectangles.
draw all your rectangles with strokes
set compositing to 'destination-out'. This causes new drawings to "erase" existing drawings where the two overlap.
fill all your rects. This erases all but the outline of the combined rectangles.
This works because strokes are drawn half-inside & half-outside the border of rectangles. When you erase the inside of the combined rectangles you are left with the half-outside strokes.
Example code and a Demo: http://jsfiddle.net/m1erickson/m5jg92wd/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
// draw all rects with strokes
ctx.strokeRect(20,20,100,200);
ctx.strokeRect(90,110,75,50);
// set compositing to erase existing drawings
// new drawings will erase existing drawings where the two overlap
ctx.globalCompositeOperation='destination-out';
// fill all rects
// This "erases" all but the outline stroke
ctx.fillRect(20,20,100,200);
ctx.fillRect(90,110,75,50);
// reset compositing to its default mode
ctx.globalCompositeOperation='source-over';
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>

minimize image size in canvas

i wanted to add a image on my canvas .the width and height of the canvas is 400X400.and size of the image is 298x300.i want it to have the size of 30x30 when it will be drawn on the canvas.so i gave it width and height inside script tag.but it is not affecting the original size of the image .it covers up the whole canvas(even only half of it is shown).how can i fix this?
![<html>
<head>
<style>
#mycanvas{
width:400;
height:400;
border:1px solid black;
}
</style>
</head>
<body>
<script>
function draw(){
var canvas=document.getElementById("mycanvas");
var ctx=canvas.getContext('2d');
var img=new Image();
img.src="lol1.jpg";
img.style.width="30px";
img.style.height="30px";
ctx.drawImage(img,0,0);
}
window.onload=draw;
</script>
<canvas id="mycanvas"></canvas>
</body>
</html>]
Just use:
ctx.drawImage(img,0,0,30,30);
4th parameter is width, 5th is height.

Draw a line between two elements with hover

I've seen a number of examples on how to do this, but none of them do what I need done.
What I want done, is when a certain image (it could be wrapped in an individual div if needed) is hovered over, it draws a line from the center of that image to the center of another image (or potentially from the center of the first image to the center of several other images), and on mouse out, it returns to the original state.
I tried using HTML5 canvas, but when I tried to even draw a line on the canvas while shifting HTML (the images) over the canvas, the images covered the canvas and line drawn. When I tried to change the z-index of the canvas, it worked except that the canvas covered over the HTML and made the existing on-hover image changes not work.
I've found regular JS examples of drawing lines, but they all rely on knowing the exact points to draw from...is there any way to do this by having the exact points be calculated by the JS and not needing to be hard-coded in? With the on-hover displaying the drawn lines?
As an unconventional alternative you can give this library a try. It's a pre-HTML5-canvas oldie-but-still-goodie. It has an ability to turn any DIV into a pseudo "canvas", you can have any HTML elements inside of this DIV and do all kinds of drawing between them.
For example if you define your "canvas" like this:
<div id="myCanvas" style="position: relative;"></div>
You can init the library, set the color, stroke size and draw line like this:
var jg = new jsGraphics("myCanvas");
jg.setColor("#0000FF");
jg.setStroke(2);
jg.drawLine(x1, y1, x2, y2);
jg.paint();
It ain't HTML5 canvas, but it's a "canvas" you can place DOM elements directly inside of and draw there as well.
Here's a small demo: http://jsfiddle.net/Rs5eY/1/ wave the mouse over top image.
How about this alternative to highlight connections between images (if your design allows):
Add a background canvas that is wide/high enough for all your html img's to fit.
Add your html img's on top of the canvas (not as part of the canvas).
On hover, draw connecting lines on the canvas & put a highlight border around your connected imgs.
On leaving, clear the canvas connecting lines and remove the img borders.
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/4n9GK/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
#canvas{border:1px solid red;}
#img1{position:absolute; left:30px; top:30px; }
#img2{position:absolute; left:200px; top:180px; }
#img3{position:absolute; left:30px; top:330px; }
#img4{position:absolute; left:200px; top:30px; }
#img5{position:absolute; left:30px; top:180px; }
#img6{position:absolute; left:200px; top:330px; }
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
ctx.fillStyle="skyblue";
ctx.fillRect(0,0,canvas.width,canvas.height);
$(".connectable").hover(
function(){connectGroup(this);},
function(){unconnectGroup(this);}
);
function connectGroup(element){
var $element=$(element);
var hubId=$element.attr("id");
var p=$element.position();
var hubX=p.left;
var hubY=p.top;
var hubW=$element.width();
var hubH=$element.height();
ctx.fillStyle="green";
ctx.fillRect(hubX-3,hubY-3,hubW+6,hubH+6);
var group=$element.attr("data-group");
var g="img[data-group='"+group+"']"
var $group=$(g);
var notG="img:not("+g+")";
var $hidden=$(notG);
$hidden.fadeOut();
$group.each(function(){
var $groupMember=$(this);
var id=$groupMember.attr("id");
if(id!=hubId){
var p=$groupMember.position();
var x=p.left;
var y=p.top;
var w=$groupMember.width();
var h=$groupMember.height();
ctx.fillStyle="green";
ctx.strokeStyle="green";
ctx.beginPath();
ctx.moveTo(hubX+hubW/2,hubY+hubH/2);
ctx.lineTo(x+w/2,y+h/2);
ctx.stroke();
ctx.fillRect(x-3,y-3,w+6,h+6);
}
});
}
function unconnectGroup(element){
// clear the canvas
ctx.clearRect(0,0,canvas.width,canvas.height);
// show the hidden images
$("img").show();
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=330 height=450></canvas>
<img id="img1" class="connectable" data-group="1" src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house-icon.png" width=100 height=100/>
<img id="img2" class="connectable" data-group="1" src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house-icon.png" width=100 height=100/>
<img id="img3" class="connectable" data-group="1" src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house-icon.png" width=100 height=100/>
<img id="img4" class="connectable" data-group="2" src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/ship.png" width=100 height=100/>
<img id="img5" class="connectable" data-group="2" src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/ship.png" width=100 height=100/>
<img id="img6" class="connectable" data-group="2" src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/ship.png" width=100 height=100/>
<h3>Hover over image to show connections</h3>
</body>
</html>
as #Boaz suggests, you will ideally want to make the images part of the canvas, while keeping tract of where you drew them in some set of javascript variables. Then you can programmatically draw lines from image to image, since everything would be connected on the same instance of canvas. Is there some reason that you cannot do this?

Display whole image in circulr shape using Javascript or HTML5

How can I display whole image in circulr shape using Javascript or HTML5. I tried the code below but with this code only part of the image will be converted into circular shape. How can I make the whole display in circular shape?
<!DOCTYPE HTML>
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
}
#myCanvas {
border: 1px solid #9C9898;
}
</style>
<script type="text/javascript" >
</script>
</head>
<body>
<canvas id="myCanvas" width="578" height="200"></canvas>
<div id="myCanvas"></div>
<script>
var ctx = document.getElementById('myCanvas').getContext("2d");
ctx.arc(100,100, 50, 0, Math.PI*2,true); // you can use any shape
ctx.clip();
var img = new Image();
img.addEventListener('load', function(e) {
ctx.drawImage(this, 0, 0, 200, 300);
}, true);
img.src="images/hospital_review_profile_placeholder.png";
</script>
</body>
</html>
Instead of using ctx.clip(), you would resize and reposition your image to fit in your circle.
Here is code that will resize your image to its largest size that will fit in the circle.
Then the code positions the resized image properly in the circle.
Here is a Fiddle --- http://jsfiddle.net/m1erickson/s6MzZ/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var radius=50; // circle radius
var fullWidth=200; // actual width of image in pixels
var fullHeight=300; // actual height of image in pixels
var centerX=100; // center X coordinate of the circle
var centerY=100; // center Y coordinate of the Circle
// the image must be resized to fit into the circle
// Call CalcResizedImageDimensions() to get the resized width/height
var size=CalcResizedImageDimensions(radius,fullWidth,fullHeight);
var rectX=centerX-size.width/2; // the X coordinate of the resized rectangle
var rectY=centerY-size.height/2 // the Y coordinate of the resized rectangle
ctx.beginPath();
ctx.arc(centerX,centerY,radius,0,Math.PI*2,true);
// I illustrate with just a rectangle
// you would drawImage() instead
ctx.rect(rectX,rectY,size.width,size.height);
ctx.stroke();
function CalcResizedImageDimensions(r,w,h){
var d=2*r;
var newH=(d*h)/Math.sqrt(w*w+h*h);
var newW=w/h*newH;
return({width:newW,height:newH});
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=200 height=200></canvas>
</body>
</html>

Categories

Resources