How to center the "fillRect" -methode relative to canvas element - javascript

I want to center the blue rectangle made with fillrec relative to the size of the canvas (aqua). I didnt find a solution yet, due to my newbie knowledge working with JS. And my little research and trying things out didn't help either. I was hoping for a little guidance regarding that matter.
canvas {
padding: 0;
margin: auto;
display: block;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: aqua;
}
<html>
<link rel="stylesheet" href="canvas.css">
<body>
<canvas width="800", height="800", id="1" > </canvas>
<script>
let canvas = document.querySelector('canvas');
let context = canvas.getContext('2d');
context.fillStyle = "Blue"
context.fillRect(15, 15, 400, 400);
</script>
</body>
</html>

Uhhh if you canvas is always 800 and that square always 400 you can do
context.fillRect(200, 200, 400, 400);
It just plus and minus
Or you can check this out
How do I center a rectangle on a canvas

Related

Fabric.js - Why does this svg have such poor quality upon importing into my canvas?

This is an svg image loaded onto the canvas. As you can tell, it looks very much like a raster image. To give a little more context, the light blue box is 1000px by 400px.
Notice also the image of the IText object looks like a raster image instead of a vector image.
Anyone know what's happening here and how to fix it?
---update---
Sorry, this took so long to get out... I got side tracked, but as requested:
<html>
<head>
<title>
Debug Me
</title>
<!--jQuery CDN-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<!--Path to fabric.js-->
<script type='text/javascript' src="./CreekWareJava/fabric.js-3.6.3/dist/fabric.js"></script>
<!--bootstrap related-->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.bundle.min.js" integrity="sha384-1CmrxMRARb6aLqgBO7yyAxTOQE2AKb9GfXnEo760AUcUmFx3ibVJJAzGytlQcNXd" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
</head>
<body>
<div class="container">
<div class="row">
<div class="col" id="canvas_container">
<canvas id="canvas">
Canvas is not supported by this browser! Please upgrade your browser.
</canvas>
</div>
</div>
</div>
<style>
#canvas_container
{
display: flex !important;
justify-content: center !important;
}
canvas
{
position: absolute !important;
height: 100% !important;
width: 100% !important;
top: 50% !important;
left: 50% !important;
transform: translate(-50%, -50%) !important;
}
.canvas-container
{
width: 1000px !important;
height: 400px !important;
border: 5px solid green !important;
position: relative !important;
}
</style>
<script>
window.onload = function()
{
canvas = new fabric.Canvas('canvas');
// – Raman Nikitsenka's proposal
// it shouldn't hurt to have it in here...
fabric.Object.prototype.objectCaching = false;
//Adding some text
addText("Some text");
addImage("http://fabricjs.com/assets/1.svg");
}
function addText(text)
{
var canH = canvas.getHeight() / 2;
var canW = canvas.getWidth() / 2;
var text = new fabric.IText(text, { left: canW, top: canH, fill: "Black", textAlign: 'center' });
text.originX = 'center';
text.originY = 'center';
canvas.add(text);
canvas.bringToFront(text);
canvas.requestRenderAll();
}
function addImage(source)
{
fabric.loadSVGFromURL(source ,function(objects,options) {
var loadedObjects = fabric.util.groupSVGElements(objects, options);
loadedObjects.set({
width: 200,
height: 200
});
canvas.add(loadedObjects);
canvas.renderAll();
});
}
</script>
</body>
</html>
This is the simplified code. As you can tell when you load it, both the svg and the text will come out very blurry. When you resize the dragon or the text, you can tell that it is trying to render it but doesn't do so properly.
Some additional observations:
fabric.js takes the initial canvas element and creates 2 new canvases, then wraps them in a div with a class called .canvas-container. I have a wrapper div for that container with id #canvas_container.
-- Update again... --
I added the following code to the window.onload eventlistener directly after the new fabric object...
for (var i = 0; i < 4; i++)
{
canvas.setHeight(document.getElementById('canvas').height);
canvas.setWidth(document.getElementById('canvas').width);
canvas.requestRenderAll();
console.log(i, "fw", canvas.width, "fh", canvas.height, "cw", document.getElementById("canvas").width, "ch", document.getElementById("canvas").height, "fr", canvas.width / canvas.height, "cr", document.getElementById("canvas").width / document.getElementById("canvas").height);
}
My observations from this are that the more I increase the counter for the loop, the better the image quality and text quality. On the other hand however, it will make the resize boxes and bounding box much thinner and decrease the physical size of the objects. The console will output fabric's canvas's width and height, then the physical html canvas element's width and height, followed by the ratios of each respectively. Thoughts?
So the problem is that fabric.js checks the tag for a width and height to initialize the new fabric canvas to, and if you don't include it in the tag, it won't render the canvas properly. To fix it, you can use
canvas.setHeight(document.getElementById("your_canvas_id").style.height);
canvas.requestRenderAll();
and likewise for the width.
Fabric.js changes my canvas size to 300x150 after initialization is another resource for this question.

p5.js: resize canvas height when div changes height

I'm trying to make the canvas with p5.js resize together with a div in which it is in when clicking on a button that extends this div giving it additional height. I don't need the canvas to reload, instead I just need it to add some additional height. Is there a way to do it? I tried making the canvas width 100% and height: auto, but it doesn't work. Please, see the code below:
<div class="canvas-wrapper">
<div id="canvas"></div>
</div>
<button type="button" class="button" id="extend-canvas">Extend</button>
Scripts:
function setup() {
var myCanvas = createCanvas(498, 598);
myCanvas.parent('canvas');
}
$( "#extend-canvas" ).click(function() {
var canvasHeight = $(".canvas-wrapper").height();
$(".canvas-wrapper").height(canvasHeight + 300);
});
CSS:
.canvas-wrapper {
margin: 0 auto;
background: #fff;
width: 500px;
height: 600px;
position: relative;
}
#canvas canvas {
width: 100% !important;
height: auto !important;
}
You can use the resizeCanvas() function for this. More info can be found in the reference.
Here's an example that resizes the canvas to match the screen width and height:
function setup() {
createCanvas(windowWidth, windowHeight);
}
function draw() {
background(0, 100, 200);
}
function windowResized() {
resizeCanvas(windowWidth, windowHeight);
}
But you could also get the width and height of the div and set the canvas size to that.

jquery, resize a canvas without scaling

I was trying to put a canvas in a container. I wanted the canvas to have the same size as the container. To do this I used JQuery, however, this turned out to scale my canvas. This was not my intention, especially because I draw after resizing. Doing seemingly the same thing in good old fashion JavaScript gives me the expected result.
I personally did not expect the JQuery result and it took some time before I figured out the problem. Does anybody know why they opted for this implementation and why it gives a different result? I hope by sharing this I can save some people a lot of time!
Thanks for anybody willing to research this further of fix this!
Here is some example code:
<html>
<head>
<title>Canvas resizing</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<style type="text/css">
#container1{
background-color: green;
width: 100px;
height: 100px;
margin: 50px auto;
}
#container2{
background-color: red;
width: 100px;
height: 100px;
margin: 50px auto;
}
</style>
</head>
<body>
<div id="container1">
<canvas></canvas>
</div>
<div id="container2">
<canvas></canvas>
</div>
<script type="text/javascript">
function draw (canvas) {
var context=canvas.getContext("2d");
context.lineWidth = 5;
context.rect(25,25,50,50);
context.stroke();
}
$(document).ready(function () {
//javascript
var container = document.getElementById('container1');
var canvas = container.childNodes[1];
canvas.width = 100;
canvas.height = 100;
draw(canvas);
//jquery
var container = $('#container2');
var canvas = container.children()[0];
$(canvas).width(100);
$(canvas).height(100);
draw(canvas);
});
</script>
</body>
</html>
The jQuery width and height methods are shorthand aliases for setting the CSS width and height properties. Sizing a canvas using CSS causes the scaled, distorted look you're seeing. Your pure javascript version of the code is setting the width and height attributes of the canvas element. To achieve the same in jQuery you can use:
$(canvas).prop('width', 100)
$(canvas).prop('height', 100)
JSFiddle

Canvas element lines aren't straight?

I am trying to draw an element on a canvas but whenever I draw the canvas, the lines turn out faded and not bold. I don't understand why this happening with my code.. whenever I try it with code from W3schools it turns out fine. Here is my code and an image below.
<!DOCTYPE html>
<html>
<head>
<title>Talk Walk</title>
<style type="text/css">
#canvas {
position: absolute;
top: 0px;
left: 0px;
height: 500px;
width: 750px;
background-color: blue;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext("2d");
ctx.fillStyle = "green";
ctx.fillRect(0,0,150,75);
</script>
</body>
</html>
The problem here is that there's some aliasing going on when you're drawing the rectangles.
This is happening because the "edge" of the green rectangle isn't drawn exactly on a pixel. Normally, you wouldn't really see it, but since you're stretching out the canvas by using css to set it's width and height, you get this result:
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext("2d");
ctx.fillStyle = "green";
ctx.fillRect(0,0,150,75);
#canvas {
height: 500px;
width: 750px;
background-color: blue;
}
<canvas id="canvas"></canvas>
To fix that, use the width and height HTML attributes, instead of css:
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext("2d");
ctx.fillStyle = "green";
ctx.fillRect(0,0,150,75);
#canvas {
background-color: blue;
}
<canvas id="canvas" height="500" width="750"></canvas>
This properly scales the canvas, so the aliasing (while still there if you zoom in) doesn't scale up.

Positioning a canvas below overlapping canvases

I have two canvases that overlap intentionally, to draw a ball falling on top of the other canvas. I want to put a third canvas below those two overlapping ones on the page, without any overlap. When the div element that holds the overlapping canvases has a relative position, it does not prevent other elements from overlapping it. As I understand it, that div must be positioned relatively so that the canvases inside it can be positioned absolutely and overlap.
Here is my HTML:
<div id="box" style="position: relative;"></div>
<div id="countdiv"></div>
Here is the JavaScript:
boxCanvas = document.createElement("canvas");
// the margins on the page are 3%
boxCanvas.width = window.innerWidth - (window.innerWidth * .06);
boxCanvas.height = document.getElementById("height").value;
boxCanvas.style = "border: 1px solid #808080; position: absolute; left: 0; top: 0; z-index: 0";
document.getElementById("box").appendChild(boxCanvas);
// second canvas for drawing balls falling
ballCanvas = document.createElement("canvas");
ballCanvas.width = boxCanvas.width;
ballCanvas.height = boxCanvas.height;
ballCanvas.style = "border: 1px solid #808080; position: absolute; left: 0; top: 0; z-index: 1";
document.getElementById("box").appendChild(ballCanvas);
And here is the JavaScript for the third canvas:
countCanvas = document.createElement("canvas");
countCanvas.width = window.innerWidth - (window.innerWidth * .06);
countCanvas.height = 100;
countCanvas.style = "border: 1px solid #808080;";
document.getElementById("box").appendChild(countCanvas);
countctx = countCanvas.getContext("2d");
ballCanvas.height = boxCanvas.height;
ballCanvas.style = "border: 1px solid #808080; position: absolute; left: 0; top: 0; z-index: 1";
document.getElementById("countdiv").appendChild(ballCanvas);
The problem can be seen here when you click drawbox() and then "show hitcounts". Thanks for the help! Let me know if I could provide any more information.
I must admit I’m not exactly sure what you’re asking.
I think you want to have 2 overlapping canvases on top followed by a separate canvas on the bottom.
And you want to do the styling in javascript instead of CSS.
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/hgHBw/
<!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>
#box{
border:1px solid blue;
}
.subcanvs{
border: 1px solid green;
}
#countCanvas{
border: 1px solid gold;
}
</style>
<script>
$(function(){
var w=300;
var h=200;
var boxDiv=document.getElementById("box");
boxDiv.style.width=w+"px";
boxDiv.style.height=h+"px";
boxDiv.style.position="relative";
var box=document.getElementById("boxCanvas");
var boxCtx=box.getContext("2d");
box.width=w;
box.height=h;
box.style.position="absolute";
box.style.left=0;
box.style.top=0;
var ball=document.getElementById("ballCanvas");
var ballCtx=ball.getContext("2d");
ball.width=w;
ball.height=h;
ball.style.position="absolute";
ball.style.left=0;
ball.style.top=0;
var counter=document.getElementById("countCanvas");
var countCtx=counter.getContext("2d");
counter.width=w;
counter.height=100;
test(boxCtx,20,30,"red");
test(ballCtx,100,30,"green");
test(countCtx,30,30,"blue");
function test(ctx,x,y,color){
ctx.beginPath();
ctx.fillStyle=color;
ctx.rect(x,y,50,50);
ctx.fill();
}
}); // end $(function(){});
</script>
</head>
<body>
<div id="box">
<canvas id="boxCanvas" class="subcanvs"></canvas>
<canvas id="ballCanvas" class="subcanvs"></canvas>
</div>
<canvas id="countCanvas"></canvas>
</body>
</html>
One thing to note:
// this sets the canvas drawing area to 100px wide
myCanvas.width=100;
// this styles the canvas element to be 100px wide on the page
// if this isn't == myCanvas.width then the image will be horizontally distorted
myCanvas.style.width="100px";

Categories