cropping a image in a canvas - javascript

I have a canvas of size 300px to 300px and I drag and drop a very large image on to it. so it takes the size of the canvas. Then I have a resizable and moveable square which I use to crop certain areas. So using jquery I take the width and height of the crop square and the x and y distance to the clipping point. But when I finally crop and display the region in a second canvas I can see that the cropped region is not exactly what I selected as the region to be cropped.
I dont want to use getimagedata and putimagedata commands. I want to use drawimage command only
Please help
var x = $("#crop_square").width();
var y = $("#crop_square").height();
var ty = $("#crop_square").offset().top - $("#area_c").offset().top;
var tx = $("#crop_square").offset().left - $("#area_c").offset().left;
var c = document.getElementById("area_c");
var c2 = document.getElementById("area_c2");
var ctx = c.getContext("2d");
var ctx2 = c2.getContext("2d");
ctx2.drawImage(image_src,tx,ty,x, y,0,0,c2.width,c2.height);
<canvas id ="area_c" style="width:300px;height:300px;border:3px solid black;z-index:1" ondrop="dropb(event)" ondragover="myfkb(event)" >
</canvas>
<canvas id ="area_c2" style="width:300px;height:300px;border:3px solid black;z-index:1" >
</canvas>

Don't minus area_c top and left from tx,ty
Try this
var x = $("#crop_square").width();
var y = $("#crop_square").height();
var ty = $("#crop_square").offset().top;
var tx = $("#crop_square").offset().left;
var c = document.getElementById("area_c");
var c2 = document.getElementById("area_c2");
var ctx = c.getContext("2d");
var ctx2 = c2.getContext("2d");
ctx2.drawImage(image_src,tx,ty,x, y,0,0,c2.width,c2.height);

Related

Fabric JS getContext('2d') not matching getImageData color

Website: http://minimedit.com/
Currently implementing an eye dropper. It works fine in my normal resolution of 1080p, but when testing on a higher or lower resolution it doesn't work.
This is the basics of the code:
var ctx = canvas.getContext("2d");
canvas.on('mouse:down', function(e) {
var newColor = dropColor(e, ctx);
}
function dropColor(e, ctx) {
var mouse = canvas.getPointer(e.e),
x = parseInt(mouse.x),
y = parseInt(mouse.y),
px = ctx.getImageData(x, y, 1, 1).data;
return rgb2hex('rgba('+px+')');
}
When I first initiate the canvas I have it resize to fit resolution:
setResolution(16/9);
function setResolution(ratio) {
var conWidth = ($(".c-container").css('width')).replace(/\D/g,'');
var conHeight = ($(".c-container").css('height')).replace(/\D/g,'');
var tempWidth = 0;
var tempHeight = 0;
tempHeight = conWidth / ratio;
tempWidth = conHeight * ratio;
if (tempHeight > conHeight) {
canvas.setWidth(tempWidth);
canvas.setHeight(conHeight);
} else {
canvas.setWidth(conWidth);
canvas.setHeight(tempHeight);
}
}
The x and y mouse coordinates work fine when zoomed in, but they don't line up with the returned image data. It seems as though the ctx isn't changing it's width and height and scaling along with the actual canvas size.
The canvas element is showing the correct width and height before using getContext as well.
Any ideas on a solution?
Feel free to check out the full scripts on the live website at: http://minimedit.com/
Try "fabric.devicePixelRatio" for calculating actual position, for example:
x = parseInt(mouse.x) * fabric.devicePixelRatio

Canvas drawing wont show

I was making a web game just for a little practice, but my drawing will not show in the canvas element of the browser. I do not know why it will not show. By the way, I used variables as the value of the horizontal position so that I could easily change them later.
JavaScript
var canvas = getElementById('myCanvas');
var blt = canvas.getContext('2d');
var bS = 20;
var x = 220;
var y = 340;
var x1 = 227;
var x2 = 229;
var x3 = 240;
var x4 = 251;
var x5 = 253;
var x6 = 260;
function drawShip() {
blt.beginPath();
blt.moveTo(x,360);
blt.lineTo(x,340);
blt.lineTo(x1,337);
blt.lineTo(x2,337);
blt.lineTo(x2,340);
blt.lineTo(x3,330);
blt.lineTo(x4,340);
blt.lineTo(x4,337);
blt.lineTo(x5,337);
blt.lineTo(x6,340);
blt.lineTo(x6,360);
blt.lineTo(x,360);
blt.closePath();
};
drawShip();
You need to use the stroke() method to draw the path as a line.
Here you can find every canvas methods and some documentation and examples:
http://www.w3schools.com/tags/ref_canvas.asp
You forgot to stroke the path. Add this after blt.closePath()
blt.stroke();
In your code change the line
var canvas = getElementById('myCanvas');
by
var canvas = document.getElementById('myCanvas');
and add blt.stroke(); after blt.closePath();

How to set height on canvas after filled some text?

I'm filling canvas with some dynamic texts in ArrayList. And I set the height as length of ArrayList like ArrayList.length * 20 or something like that.
HTML:
<canvas id="myCanvas" width="272px" style="border: 1px solid black"></canvas>
JS :
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
var myheight = 10;
for(var i = 0; mylist.length > i; i++){
context.fillText("my text", 10, myheight);
myheight += 10;
}
loop works fine, texts are filled.. and I'm trying to calculate the canvas.height after the loop.
When I set canvas.height = myheight and all filled texts are gone.. canvas gone blank.
How can I set height after canvas filled by texts dynamically?
Help me..
Thank you.. And sorry for bad English..
Resizing window or canvas using canvas.height = myheight clears the canvas
you need to sava the content of canvas and redraw it again on the resized canvas
If you want to save the content of the canvas and redraw it,here is few options
Use context.getImageData to grab the whole canvas, resize the
canvas, then use context.putImageData to redraw it at the new scale.
Create a new canvas with the updated size and call
context.drawImage(oldCanvas, ...) to copy the old canvas onto the
new one.
call context.setScale(xscale, yscale) and call whatever function you
used to draw the canvas originally. Assuming you set up xscale and
yscale correctly, it will automatically scale everything to the new
size.
A quick solution to your problem is to calculate canvas height before drawing the text, because as you use canvas.height the canvas will be erased
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
var myheight = 10;
for(var i = 0; 10 > i; i++){
myheight += 10;
}
canvas.height = myheight;
myheight = 10;
for(var i = 0; 10 > i; i++){
context.fillText("my text", 10, myheight);
myheight += 10;
}
http://jsfiddle.net/borja204/66dn06tq/1/

How to draw rectangles on SVG on click event?

I am using raphael js in my application. Here I need to draw a small rectangle on a point of clicking in raphael paper. I need to connect these rectangle using a line. Can anyone make DEMO of this. I am adding sample DEMO. Please update this.
My DEMO.:
HERE
var paper = Raphael("editor", 635,500),
canvas= document.getElementById('editor').style.backgroundColor='gray';
Now I need to draw samll rectangles on clicking raphael paper and joing them with a line.
This should do the trick; http://jsfiddle.net/9dsgcv1c/1/
var paper = Raphael("editor", 635,500),
canvas= document.getElementById('editor').style.backgroundColor='gray';
var offsetx = paper.canvas.offsetLeft;
var offsety = paper.canvas.offsetTop;
var prevRect = null;
var rWidth = 50;
paper.canvas.onmousedown = function(e) {
var posX = e.pageX-offsetx;
var posY = e.pageY-offsety;
var rectX = posX - (rWidth/2)
var rectY = posY - (rWidth/2)
var c = paper.rect(rectX, rectY, rWidth, rWidth).attr({fill:"#fff"});
if(prevRect) {
var p = "M"+prevRect.x +" " +prevRect.y +"L"+posX+" "+posY
var line = paper.path(p);
}
prevRect = {x: posX, y:posY};
}
-
<b>Click on CAMVAS to draw rectangle</b>
<div id="editor"></div>

JavaScript - Splitting a tileset image to be stored in 2D Image() array

Let's say I have this image:
and I have this 2D array tiles[] .. and using Image() function... how can do I use the (what I assume be best way?) for loop to add each tile into the array so tile[0] through however many there are is read and used as Image() objects later to be painted on HTML5 canvas?
I would..
Figure out how many tiles wide and high this image is
Draw the image to a canvas in memory, and use the context to get image data.
Loop through and subimage each tile, storing in an array.
Assuming:
imageWidth, imageHeight, tileWidth, tileHeight
All describe what their names suggest, and:
EDIT: Added image load as per comment, fixed wrongly name ImageWidth and ImageHeight to imageWidth and imageHeight
EDIT: Performing code inside imageObj.onload as the image is drawn here, drawImage() from origin (0,0)
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var imageObj = new Image();
imageObj.src = "tilesetImageLocationHere";
imageObj.onload = function() {
ctx.drawImage(imageObj, 0, 0);
Then, split up your image into a list of tile data..
var tilesX = imageWidth / tileWidth;
var tilesY = imageHeight / tileHeight;
var totalTiles = tilesX * tilesY;
var tileData = new Array();
for(var i=0; i<tilesY; i++)
{
for(var j=0; j<tilesX; j++)
{
// Store the image data of each tile in the array.
tileData.push(ctx.getImageData(j*tileWidth, i*tileHeight, tileWidth, tileHeight));
}
}
//From here you should be able to draw your images back into a canvas like so:
ctx.putImageData(tileData[0], x, y);
}
ok I did this on my localhost: it should give you a base at least. I think you should be able to use this straight outta the box but you might have to make a few calculation adjustments for it depending on what you want. I just don't think it's neccessary to spend thee time to perfect it to your example:
You'll obviously have to point the image to your own image.
<html>
<head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
var canvas = document.getElementById('fakeCanvas');
var ctx = canvas.getContext('2d');
var img = new Image();
img.src = '/theImage.png';
var tiles = [];
var imageTileNumWidth = 23;
var imageTileNumHeight = 21;
img.onload = function(){
var imageWidth = img.width;
var imageHeight = img.height;
sndCanvasWidth = imageWidth/imageTileNumWidth;
sndCanvasHeight = imageHeight/imageTileNumHeight;
canvas.width = imageWidth;
canvas.height = imageHeight;
ctx.drawImage(img,0,0,imageWidth,imageHeight);
var sndCanvas = document.getElementById('drawCanvas');
sndCanvas.width=sndCanvasWidth;
sndCanvas.height=sndCanvasHeight;
var i=0;
var j=0;
var t=0;
for(i=0;i<imageWidth;i+=sndCanvasWidth){
for(j=0;j<imageHeight;j+=sndCanvasHeight){
var myImageData = ctx.getImageData(j,i,sndCanvasWidth,sndCanvasHeight);
var ctx2 = sndCanvas.getContext("2d");
ctx2.putImageData(myImageData,0,0);
tiles.push(myImageData);
}
}
};
});
</script>
</head>
<body>
<canvas id="fakeCanvas"></canvas>
<canvas id="drawCanvas"></canvas>
</body>
</html>

Categories

Resources