Canvas stroke and fill color [duplicate] - javascript

This question already has an answer here:
html 5 canvas LineTo() line color issues
(1 answer)
Closed 3 years ago.
Problem is that stroke opacity is lower than fill opacity and I can't get stroke color to be the same opacity as fill color.
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.strokeStyle = "rgba(255,0,0,1)";
ctx.fillStyle = "rgba(255,0,0,1)";
ctx.strokeRect(20, 20, 25, 25);
ctx.fillRect(20, 50, 25, 25);
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
If we set fillStyle opacity 0.5, than they will be the same, but we can't raise opacity of stroke.
So how set stroke color to be the same as fill color?

They have exactly the same color. The problem is the antialiasing.
You can check that the stroke looks darker if you make it wider.
ctx.lineWidth = 5;
It will have an intense red in the central part of the stroke but a non-saturated one in the edges.
Sadly, you can control it (i.e. turn it off) because it depends on the browser.
You can read more about it (and look for alternatives) in this other question.
The trick that was working better for me is to translate the canvas by half-pixel distance.
ctx.translate(0.5, 0.5);
It was suggested here and here. I can not be sure if is going to achieve the desired effect in every browser though (i tested it on Firefox).
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.strokeStyle = "rgba(255,0,0,1)";
ctx.fillStyle = "rgba(255,0,0,1)";
ctx.translate(0.5, 0.5);
ctx.strokeRect(20, 20, 25, 25);
ctx.fillRect(20, 50, 25, 25);
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">Your browser does not support the HTML5 canvas tag.</canvas>

Related

fillText over gradient background does not show

When I change from strokeText to fillText the text disappears. I just have a gradient canvas background and I am trying to put fillText over the gradient. strokeText works fine but when I change to fillText, the text is gone.
'''
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext("2d");
var grd = ctx.createRadialGradient(100, 100, 100, 100, 130, 50);
grd.addColorStop(0, "orange");
grd.addColorStop(1, "yellow");
// Fill with gradient
ctx.fillStyle = grd;
ctx.fillRect(0, 0, 200, 100);
ctx.font="20px Georgia";
ctx.strokeText("hello",10,30);
'''
HTML
<canvas id="canvas" width="200" height="100" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML canvas tag.</canvas>
It “disappears” because you only set fillStyle once therefore both fillRect and fillText are the same gradient color. The text is there but it’s blended into the background. Change the fillStyle again before the text.
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext("2d");
var grd = ctx.createRadialGradient(100, 100, 100, 100, 130, 50);
grd.addColorStop(0, "orange");
grd.addColorStop(1, "yellow");
// Fill with gradient
ctx.fillStyle = grd;
ctx.fillRect(0, 0, 200, 100);
ctx.fillStyle = "blue";
ctx.font="20px Georgia";
ctx.fillText("hello",10,30);
The reason it doesn’t do that with stroke is because stroke doesn’t get it’s orders from fillStyle so therefore it uses the default which is black.

Getting S shape with Bezier curve on canvas in HTML

I have this code to draw a Bezier curve:
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.moveTo(20, 20);
ctx.bezierCurveTo(30, 100, 200, 100, 200, 200);
ctx.stroke();
<canvas id="myCanvas" width="300" height="400" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
This code results in a S shaped Beizer curve:
My problem is that I want to change the start and end control points as per my wish but at the same time I want that S shape to be there.
I have observed whenever I change the control points, the overall shape of the curve becomes strange.
What is the way out?
If the S shape is currently displayed as you wish, then the middle control points are such that their X-coordinate roughly matches the X-coordinate of the end point they are closest to, and the Y-coordinate is the same for both middle control points: it is about half-way the Y range of the end points.
So you can calculate the control points dynamically if you only have the two end points:
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
function drawS(start, end) {
ctx.beginPath();
ctx.moveTo(...start);
let midY = (start[1] + end[1]) / 2;
ctx.bezierCurveTo(start[0], midY, end[0], midY, ...end);
ctx.stroke();
}
drawS([20, 20], [200, 180]);
<canvas id="myCanvas" width="300" height="200" style="border:1px solid #d3d3d3;"></canvas>

How to use javascript to make this shape and add javascript animation to it

I am trying to do a sample weather application for a quite long time now, but can not produce the same effect as seen here. Basically, it has to show sunrise and sunset information, but use similar effects in visualization.
Can someone assist on how to make the same shape and add the code below to it so it would produce the same effects?
The blue area effect is seen here below with this code.
But I can not make the shapes to work with the effect. Can someone assist on how to make the shapes so sunrise sunset would work properly. The colored blue areas are actually hollow, meaning the animation code fills the shapes relative to time passed.
The code uses circle properties at the moment, but are there any shapes that can be made so, it would look like in the image.
var c1 = document.getElementById("canvas1");
var c2 = document.getElementById("canvas2");
var ctx = c1.getContext("2d");
ctx.beginPath();
ctx.arc(100, 100, 90, 0, 2 * Math.PI);
ctx.lineWidth = 2;
ctx.stroke();
animateCanvas();
function animateCanvas(){
var w = 0;
var timer = setInterval(function(){
c2.width = w;
w += 1;
var ctx = c2.getContext("2d");
ctx.beginPath();
ctx.arc(100, 100, 89, 0, 2 * Math.PI);
ctx.fillStyle = "#efba32";
ctx.fill();
if (w===200){clearInterval(timer)}
}, 20);
}
.canvases{
position: absolute;
top: 0;
left: 0;
}
<canvas id="canvas1" class="canvases" width="200" height="200"></canvas>
<canvas id="canvas2" class="canvases" width="200" height="200"></canvas>
How to make these shapes with javascript?

deleting a circle made in HTML5 Canvas [duplicate]

This question already has answers here:
Erasing previously drawn lines on an HTML5 canvas
(5 answers)
Closed 4 years ago.
I've made a canvas where I draw shapes on. When I want to delete them, I basically create the same shape again but it's white, so I don't delete any other shapes (saved the x and y coordinate, so nothing to worry there)
ctx.fillStyle="#FFFFFF";
ctx.strokeStyle="#FFFFFF";
ctx.beginPath();
ctx.arc(x, y, 40, 0, 2 * Math.PI);
ctx.fill();
The problem is that on some shapes there is still a remaining black rest, that I can't get rid of (it's even worse on other shapes)
What Am I missing?
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.arc(50,50 , 40, 0, 2 * Math.PI);
ctx.fill();
ctx.fillStyle="#FFFFFF";
ctx.strokeStyle="#FFFFFF";
ctx.beginPath();
ctx.arc(50,50 , 40, 0, 2 * Math.PI);
ctx.fill();
<canvas id="myCanvas" width="1000" height=600 style="border: 1px solid #000000;">
</canvas>
EDIT: https://jsfiddle.net/sfj5y091/3/
EDIT 2:
I solved this problem in the end, by completely redrawing all the shapes after one shape was deleted in the system, which even enabled the deletion of shapes that overlapped without destroying the other shape
The residue is caused by smoothing or anti-aliasing.
To draw the black circle on the initially white background, an "aura" of gray pixels is drawn at the edge of the 40-pixel-radius circle to give it a smooth appearance, and that "aura" is a tiny bit bigger than what you planned to draw.
If you then draw a white 40-pixel-radius circle on top of that, it blends the new white edge pixels with what is now a non-white background. The result is lighter gray pixels, and not white pixels.
If your only option is still to paint over old pixels, then you'll have to use a slightly bigger radius for the white circle:
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.arc(50, 50, 40, 0, 2 * Math.PI); // radius of 40
ctx.fill();
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#FFFFFF";
ctx.beginPath();
ctx.arc(50, 50, 41, 0, 2 * Math.PI); // radius of 41
ctx.fill();
<canvas id="myCanvas" width="150" height="150" style="border: 1px solid #000000;">
</canvas>
<br /> Nothing to see here ;-)
For more on anti-aliasing, see e.g. Can I turn off antialiasing on an HTML <canvas> element?
Double buffering in action
Try
step1();
setTimeout(function () {
step2();
setTimeout(function () {
step3();
}, 1000);
}, 1000);
function step1() {
clearCanvas('myCanvas1');
drawShape('myCanvas1'
,{type:"circle", strokeStyle:"#000000", fillStyle:"#000000", radious:40, x:50, y:50});
};
function step2() {
clearCanvas('myCanvas2');
showOtherCanvas('myCanvas2', 'myCanvas1');
};
function step3() {
clearCanvas('myCanvas1');
drawShape('myCanvas1'
,{type:"circle", strokeStyle:"#000000", fillStyle:"#000000", radious:40, x:50, y:50});
showOtherCanvas('myCanvas1', 'myCanvas2');
};
function drawCircle (canvasID, info) {
var canvas = document.getElementById(canvasID);
var ctx = canvas.getContext('2d');
ctx.fillStyle=info.fillStyle;
ctx.strokeStyle=info.strokeStyle;
ctx.beginPath();
ctx.arc(info.x, info.y, info.radious, 0, 2 * Math.PI);
ctx.fill();
ctx.beginPath();
ctx.arc(info.x, info.y, info.radious, 0, 2 * Math.PI);
ctx.stroke();
}
function showOtherCanvas(cnv1, cnv2) {
var c1 = document.getElementById(cnv1);
var c2 = document.getElementById(cnv2);
c1.style['z-index'] = 3;
c2.style['z-index'] = 1;
c1.style['z-index'] = 2;
}
function clearCanvas(canvasID) {
var canvas = document.getElementById(canvasID);
var ctx = canvas.getContext('2d');
ctx.fillStyle="#FFFFFF";
ctx.strokeStyle="#FFFFFF";
ctx.fillRect(0,0,640,400);
}
function drawShape (canvasID, info) {
switch (info.type) {
case "circle" : drawCircle(canvasID, info);
}
}
<canvas id="myCanvas2" width="640" height="400"
style="border: 1px solid #000000; position: absolute; top: 10; left: 10; z-index:1">
</canvas>
<canvas id="myCanvas1" width="640" height="400"
style="border: 1px solid #000000; position: absolute; top: 10; left: 10; z-index:2">
</canvas>
The change is so fast you won't see any flicker.

Custom diamond shape in html or jscript

I need is some way to draw a shape in html. I've tried searching around, but I haven't found anything related.
Here is a sketch of what I need.
I need to draw shape in red. I know how to draw the dots, but I don't know how to connect them, because the red dots can move. The blue dots mark where the red dots can go.
You could use a canvas. Here’s how you could draw a triangle:
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.moveTo(50, 50);
ctx.lineTo(100, 50);
ctx.lineTo(50, 100);
ctx.closePath();
ctx.fillStyle = 'rgba(0, 0, 255, 0.5)';
ctx.fill();
ctx.strokeStyle = 'blue';
ctx.lineWidth = 3;
ctx.stroke();
<canvas id="canvas" width="150" height="150">Your browser lacks canvas support.</canvas>
I’ll leave it to you to figure out how to draw a diamond and make it red.

Categories