Draw an rectangle between html elements - javascript

I'm trying to draw a rectangle between 2 tag by javascript but i couldn't have any achievement. The things i´m trying to do is something like this:
Screenshot
i tried to draw a rectangle by giving X, Y but the size changes when the page size changes:
var x = 100;
var y = 111;
var width = 200;
var height = 40
var canvas = document.createElement('canvas'); //Create a canvas element
//Set canvas width/height
canvas.style.width = '100%';
canvas.style.height = '100%';
//Set canvas drawing area width/height
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
//Position canvas
canvas.style.position = 'absolute';
canvas.style.left = 0;
canvas.style.top = 0;
canvas.style.zIndex = 100000;
canvas.style.pointerEvents = 'none'; //Make sure you can click 'through' the canvas
document.body.appendChild(canvas); //Append canvas to body element
var context = canvas.getContext('2d');
//Draw rectangle
context.rect(x, y, width, height);
context.fillStyle = 'yellow';
context.fill();
function getOffset(el) {
el = el.getBoundingClientRect();
return {
left: el.left + window.scrollX,
top: el.top + window.scrollY
}
}

Related

Javascript fillRect on canvas with absolute position inside a relative container

I have two canvases inside a container like this:
<div class="canvasContainer">
<canvas class="drawCanvas" style="z-index: 0;"></canvas>
<canvas class="drawCanvas" height="150" width="300" style="z-index: 1;"></canvas>
</div>
The first canvas (z-index 0) contains an image and the second canvas is for drawing. Both canvas have a position absolute and the canvasContainer has a relative position, but for some reason the fillRect function on the canvas context does not work when I apply the relative postion to the canvasContainer. When I remove the relative postion the fillRect function in Javascript does work, but then my canvas is positioned absolute to the body tag. Why does the fillRect function not work inside my canvasContainer when its postion is relative?
This is how I draw on my canvas
let canvas = document.createElement('canvas');
canvas.style.zIndex = "0";
canvas.className = "drawCanvas";
let context = canvas.getContext("2d");
img.onload = function() {
context.drawImage(img, 0, 0);
}
canvasContainer.appendChild(canvas);
let canvas2 = document.createElement('canvas');
canvas2.className = "drawCanvas";
canvas2.style.zIndex = "1";
canvas2.height = canvas.height;
canvas2.width = canvas.width;
canvas2.md = false;
canvas2.addEventListener('mousedown', function(event){
this.md = true;
});
canvas2.addEventListener('mouseup', function(event){
this.md = false;
});
canvas2.addEventListener('mousemove', function(event){
let mouseX = event.clientX - this.offsetLeft;
let mouseY = event.clientY - this.offsetTop;
if(this.md){
let ctx = this.getContext('2d');
ctx.fillStyle = "blue";
ctx.fillRect(mouseX, mouseY, 4, 4);
}
}
});
imageContainer.appendChild(canvas2);
}

HTML canvas dimensions are right but the context uses the default ones

I have a canvas element inside a div in an HTML page. I've set its width and height via CSS to 100% of the parent div, and it sets them correctly.
I defined a "draw" function, and I use it like this: <body onload="draw();"> . And it's implemented like this:
function draw() {
var cm = 6; // canvas margin
var canvases = document.getElementsByClassName('container');
for (var i=0; i<canvases.length; i++) {
var c = canvases[i];
var w = c.offsetWidth;
var h = c.offsetHeight;
console.log('w: ' + w + '; h: ' + h);
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.lineWidth = 2;
ctx.strokeStyle = '#561a04';
ctx.moveTo(cm, cm);
ctx.lineTo(w-cm, cm);
ctx.lineTo(w-cm, h-cm);
ctx.lineTo(cm, h-cm);
ctx.lineTo(cm, cm);
ctx.stroke();
}
}
Now: the console prints the real and correct values of the width and height of the canvas (specifically 381 and 188); but it seems that the context draws as if the canvas was of its default dimensions... in fact if I simply set w = 330; h = 150; it works as expected, but then the canvas stretches the drawing and I not satisfied with the result.
What can I do to make the context use the right dimensions of the canvas? I wanted to redraw the image every time the canvas is resized, but I believe there's no event on the resize of any div, am I right?
Thank you.
Both the canvas itself and the canvas element have a width and height, they're separate things. If they're not the same, the content of the canvas is automatically scaled to fit the element. If you want a 1:1 relation, you need to set the actual width and height of the canvas.
Just after:
var w = c.offsetWidth;
var h = c.offsetHeight;
add
c.width = w;
c.height = h;
Example:
function draw() {
var cm = 6; // canvas margin
var canvases = document.getElementsByClassName('container');
for (var i=0; i<canvases.length; i++) {
var c = canvases[i];
var w = c.offsetWidth;
var h = c.offsetHeight;
c.width = w;
c.height = h;
console.log('w: ' + w + '; h: ' + h);
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.lineWidth = 2;
ctx.strokeStyle = '#561a04';
ctx.moveTo(cm, cm);
ctx.lineTo(w-cm, cm);
ctx.lineTo(w-cm, h-cm);
ctx.lineTo(cm, h-cm);
ctx.lineTo(cm, cm);
ctx.stroke();
}
}
draw();
.parent {
width: 200px;
height: 200px;
position: relative;
}
.parent canvas {
width: 100%;
height: 100%;
}
<div class="parent">
<canvas class="container"></canvas>
</div>
<div id="status"></div>
I've been using canvas for a while, instead of setting it to 100% in the css, set it to 100% with Javascript
EDIT:
I didn't notice you want to set it to 100% of parents div, this should do it
Please try this:
var canvas = document.getElementById("canvas");
canvas.width = canvas.parentElement.offsetWidth; //set canvas width to its parent width
canvas.height = canvas.parentElement.offsetHeight;//set canvas height to its parent height
var ctx = canvas.getContext("2d");
this will set canvas width and height to match it's parrents width & height
Please let me know if that solves your problem!

Alter the dimensions of the canvas image permanently and NOT keep the aspect ratio

I am creating a gradient on a canvas, generating a PNG file, and then downloading it. I want a radial gradient which is an ellipse. Since canvas gradients must be circles, I am generating the gradient as a circle and then resizing the canvas element to create the ellipse. This works fine and the visually generated image is the ellipse I want.
When I go to download the generated canvas, it is using the full size of the canvas, not the css styled size and so I get the original full sized circle. Is there a way to actually alter the dimensions of the canvas image and NOT keep the aspect ratio? All the SO posts that show up on the topic want to keep the aspect ratio.
makeCanvas();
scaled();
var input = document.createElement("input");
input.type = "button";
input.style.display = "block";
input.value = "Download Canvas to PNG";
input.onclick = function() {
var canvas = document.getElementById("canvas");
downloadURI(canvas.toDataURL("image/png"), "gradient.png");
}
document.body.appendChild(input);
var input = document.createElement("input");
input.type = "button";
input.style.display = "block";
input.value = "Download Scaled";
input.onclick = function() {
var canvas = document.getElementById("scaled");
downloadURI(canvas.toDataURL("image/png"), "gradient.png");
}
document.body.appendChild(input);
function makeCanvas() {
var canvasGradient;
var ctx;
width = 200;
height = 200;
var canvas = document.createElement("canvas");
canvas.id = "canvas";
canvas.style.width = width + "px";
canvas.style.height = height + "px";
canvas.width = width;
canvas.height = height;
ctx = canvas.getContext('2d');
var gradient;
// both circles have to share the center of the canvas
var coords = {
x1: 0,
y1: 0,
x2: 0,
y2: 0
};
coords.x1 = (width / 2);
coords.x2 = coords.x1;
coords.y1 = (height / 2);
coords.y2 = coords.y1;
// inner circle is just the center - a point
coords.r1 = 0;
// outer circle is the edge
coords.r2 = Math.min(height, width);
gradient = ctx.createRadialGradient(coords.x1, coords.y1, coords.r1, coords.x2, coords.y2, coords.r2);
gradient.addColorStop(0, "white");
gradient.addColorStop(1, "black");
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, width, height);
canvas.style.width = width / 2 + "px";
document.body.append(canvas);
can = alter(canvas, ctx);
//document.body.append(can);
}
function downloadURI(uri, name) {
var link = document.createElement("a");
link.download = name;
link.href = uri;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
delete link;
}
function alter(canvas, ctx) {
var can = document.createElement("canvas");
can.id = "can";
can.width = Math.floor(canvas.width / 2);
can.height = canvas.height;
can.ctx = can.getContext("2d");
can.ctx.drawImage(canvas, 0, 0, can.width, can.height);
canvas.width = can.width;
canvas.height = can.height;
ctx.drawImage(can, 0, 0);
return can;
}
function scaled() {
var canvas = document.createElement("canvas");
canvas.id = "scaled";
canvas.style.width = "200px";
canvas.style.height = "200px";
canvas.width = 200;
canvas.height = 200;
ctx = canvas.getContext('2d');
var gradient;
var g = ctx.createRadialGradient(100, 100, 0, 100, 100, 100);
g.addColorStop(0, "white")
g.addColorStop(1, "red")
ctx.fillStyle = g
ctx.scale(0.5, 1) // scale x axis 0.5
ctx.fillRect(0, 0, 200, 200) // gradient circle squashed along x
document.body.append(canvas);
}
Use transformations to change shape of gradients.
For your info gradient circles can be transformed to a ellipse.
var g = ctx.createRadialGradient(200,200,0,200,200,200)
g.addColorStop(0,"red")
g.addColorStop(1,"white")
ctx.fillStyle = g
ctx.scale(0.5,1) // scale x axis 0.5
ctx.fillRect(0,0,400,400) // gradient circle squashed along x
Scaling a canvas
Create a second canvas
// assuming canvas , ctx is the original canvas and context
var can = document.createElement("canvas");
Set the resolution
can.width = Math.floor(canvas.width / 2);
can.height = canvas.height;
Get context and draw original on new canvas
can.ctx = can.getContext("2d");
can.ctx.drawImage(canvas,0,0,can.width,can.height);
Set the original canvas to the new size
canvas.width = can.width;
canvas.height = can.height;
Draw on the scaled can onto the original canvas
ctx.drawImage(can,0,0);
can = undefined; // reference to dump temp canvas
You now have the canvas scale yet keeping the content. You could also just replace the old canvas with the new one

RequestAnimationFrame not working properly

After the requestAnimationFrame is called, the square does not move.
The square is expected to move though.
What is wrong with this code?
http://jsfiddle.net/o3qbesy6/1/
// Check if canvas exists and get the context of the canvas
var canvas = document.getElementsByTagName('canvas')[0];
var ctx = canvas.getContext('2d');
// Add width and height of the canvas
var width = 640, height = 480;
// Make the canvas width and height as the variables
canvas.width = width, canvas.height = height;
rect = {
x: 0,
y: 0,
width: 100,
height: 100
}
ctx.fillStyle = 'red';
ctx.fillRect(rect.x,rect.y,rect.width,rect.height);
function animate(){
if(rect.x <= 200){
rect.x += 5;
}
requestID = requestAnimationFrame(animate);
}
requestAnimationFrame(animate);

How can I cut an image at a 45 degree angle using Javascript?

Basically I need to reduce the size of an image and cut it to be a triangle. How would I do this using javascript?
This is approximately what I am looking to accomplish (obviously it would be a straight line, but that's the best I could do in paint):
Here's the code I have so far:
HTML: <div id = "mydiv"></div>
Javascript:
document.getElementById("mydiv").onclick = moulding_change('5f52a13c425655fa62058418542b95ca');
function moulding_change(thumb)
{
var ppi = 15;
var SITE_URL = "http://www.asa.tframes.org:1881";
var img = new Image();
img.src = SITE_URL + '/system/components/compimg/' + thumb + '/pattern';
img.onload = function() {
console.log("width before " + this.width);
//width needs to be the same as the height (in this case 450)
img.width = img.height / ppi;
//img.width = img.height;
img.height /= ppi;
console.log("width after " + this.width);
var canvas = document.createElement('canvas');
var ctx = canvas.getContext("2d");
canvas.style.position = "absolute";
canvas.style.zIndex = 5;
canvas.style.width = "1000px";
canvas.style.height = "1000px";
// Save the state, so we can undo the clipping
ctx.save();
// Create a shape, of some sort
ctx.beginPath();
ctx.moveTo(0,0);
ctx.lineTo(img.width,0);
ctx.lineTo(img.width,img.width);
ctx.closePath();
// Clip to the current path
ctx.clip();
ctx.drawImage(img, 0, 0);
// Undo the clipping
ctx.restore();
$("#mydiv").append(canvas);
};
}
Thanks to Geoff, I was able to create canvas elements. The problem ended up being that I wasn't specifying a width, height for the image.

Categories

Resources