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.
Related
I'm trying to make a ball made by .arc function grow with time, and i want to be able to specify the duration. this is where I'm stuck:
function start(){
var ball1,ball2,ball3,ball4;
var ball=document.getElementById("MyCanvas");
ball1=ball.getContext("2d");
ball1.fillStyle="yellow";
ball1.beginPath();
ball1.arc(95,50,40,0,2*Math.PI);
ball1.fill();
scaling(ball1);
}
function scaling(ball){
ball.beginPath();
ball.arc(95,50,100,0,2*Math.PI);
}
window.addEventListener("load",start,false);
body{background-color:white;}
<canvas id="MyCanvas" width="1000" height="500" style="border:black 1px solid"></canvas>
so is there a way to do it with .arc? and if not, any other way to do it? (like border-radius:50%).
Really, ball should contain all the data for... a ball. Instead you set it equal to the canvas:
var ball = document.getElementById("MyCanvas");
...and use ball1 for the context
ball1 = ball.getContext("2d");
Firstly, you should rename those variables to something else.
var canvas, context;
var ball;
function start(){
canvas = document.getElementById("MyCanvas");
context = canvas.getContext("2d");
}
window.addEventListener("load",start,false);
and then you need to think about an animation loop and all sorts of other things...
Perhaps instead you should think about something much simpler like using pure CSS.
.circle{
width: 50px;
height: 50px;
transition: all 1s;
background: yellow;
border-radius: 50%;
cursor: pointer;
}
.circle:hover{
width: 100px;
height: 100px;
}
<div class="circle"></div>
I'm trying to create a stylised timeline for an audio player. I would like to draw a nice thick line with round caps at the ends. I thought it would be relatively trivial to do this with canvas. However, I'm finding that at least in Chrome on Mac OS, the lines are not anti-aliased; and also (possibly as a consequence) the line caps are elongated, rather than perfect half-circles.
What perplexes me is that when I view the W3 Schools example the line is anti-aliased, with the expected caps. This makes me wonder if something in my code is triggering a non-anti-aliased mode in the browser...
Here is my full code:
<html>
<head>
<style>
body {
background-color: #212b69;
}
.centering {
height: 100%;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
}
#timeline {
width: 60%;
height: 50px;
}
</style>
</head>
<body>
<div class="centering">
<canvas id="timeline" />
</div>
<script type="text/javascript">
var timeline = document.getElementById('timeline');
var ctx = timeline.getContext('2d');
var centrline = timeline.height/2;
// ctx.translate(0.5, 0.5); // I have tried the half-pixel trick
// line settings
ctx.lineCap = "round";
ctx.lineWidth = 30;
ctx.strokeStyle = "white";
// draw test stroke
ctx.beginPath();
ctx.moveTo(20, centrline);
ctx.lineTo(60, centrline+10); // offset to show aliasing of edges
ctx.stroke();
</script>
</body>
</html>
My result:
Compared with W3Schools result:
I understand from these posts that vector anti-aliasing is determined by the browser. Note also that I've tried the trick of translating the canvas by a half-pixel to kick it into anti-aliasing mode. If there is no way to get canvas to get what I want it to do, is there some other method? Given that I only want to create a relatively simple shape...
Just remove the following css rule and the shape will stop skewing.
#timeline {
width: 60%;
height: 50px;
}
Here's a working example without skew: enter link description here
var timeline = document.getElementById('timeline');
var ctx = timeline.getContext('2d');
var centrline = timeline.height/2;
// ctx.translate(0.5, 0.5); // I have tried the half-pixel trick
// line settings
ctx.lineCap = "round";
ctx.lineWidth = 30;
ctx.strokeStyle = "white";
// draw test stroke
ctx.beginPath();
ctx.moveTo(20, centrline);
ctx.lineTo(60, centrline+10); // offset to show aliasing of edges
ctx.stroke();
body {
background-color: #212b69;
}
.centering {
height: 100%;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
}
<div class="centering">
<canvas id="timeline" />
</div>
Using a custom #font-face within a canvas element, renders fine in DOM, when rendered through canvas it stretches the text vertically. Or might be squashing it horizontally, cannot tell.
CSS:
#font-face {
font-family: 'myFont';
src: url('myFont.ttf');
}
Canvas element width is set to 100% of its parent (a 300x250px square) through CSS, text is added to canvas by:
cContext.fillStyle = "rgba(255,255,255,1)";
cContext.font = '58px "myFont"';
cContext.fillText("1000", 22, 71);
var c = document.getElementById("square");
var ctx = c.getContext("2d");;
ctx.font = "40px Arial";
ctx.fillStyle = "#FF0000";
ctx.fillText("1000",40,80);
var c2 = document.getElementById("notsquare");
var ctx2 = c2.getContext("2d");;
ctx2.font = "40px Arial";
ctx2.fillStyle = "#FF0000";
ctx2.fillText("1000",40,60);
#square, #notsquare{
border: 1px solid red;
}
#notsquare{
width: 300px;
height: 400px;
left:0px;
}
<canvas id='square' width='300' height='300' ></canvas>
<canvas id='notsquare' width='300' height='300' ></canvas>
Example from #pointy remark.
To specify the width and height of the canvas element you should use the attributes of the element and not css.
if you want to resize the canvas you should do so in the JS like this
Resize HTML5 canvas to fit window
As the title says everything. I want to change the size of my HTML5 canvas. I am using fabricjs library to work with HTML5 canvas. However, fabricjs makes the size of the canvas smaller. Now I want to its size using css but it does not affect it. When I give other css rules to canvas then it does affect but not width and height.
jsfiddle
Here is my fabricjs code
var canvas = new fabric.Canvas('c');
var rect = new fabric.Rect({
left: 50,
top: 50,
fill: 'red',
width: 100,
height: 100
});
canvas.add(rect);
here is my html
<canvas id="c"></canvas>
and here is my CSS
#c {
width: 100%;
border: 1px solid green;
}
Found the answer. Below solution works for me
var canvas = new fabric.Canvas('c');
canvas.setHeight(500);
canvas.setWidth(800);
Second solution is
<canvas id="c" width="900" height="600"></canvas>
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";