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>
Related
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>
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?
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.
This is my JS code, I would realy appreciate if someone would help me, because this code is not even running and I don't know why.
<canvas id="Canvas1" width="400" height="100"></canvas>
<script>
var can = document.getElementById('Canvas1');
var ctx = can.getContext('2d');
ctx.fillStyle = "black";
ctx.fillRect(100, 100, 250, 100);
</script>
<canvas id="Canvas1" width="400" height="100" style="border:1px solid #000000;"></canvas>
<script>
var can = document.getElementById('Canvas1');
var ctx = can.getContext('2d');
ctx.fillStyle = "#000000";
ctx.fillRect(0, 0, 150, 50);
</script>
You missed border in canvas so u was not seeing o/p
and also you starting fillRect at 100(height) that is your end point of rect so u are not able to see the result.
Remember
ctx.fillRect(p1, p2 ,p3 , p4);
p1 = Start point X
p2 = Start point Y
p3 = width of your rectangle that should be less than or equal to Canvas width.
p4 = Height of your rectangle that should be less than or equal to Canvas height.
I'm trying to create a 2d canvas with the accelerometer API.
The API full example works when I tilt the phone the acceleration.x and acceleration.y changes.
So I made a canvas 2d circle and implemented the acceleration.x and acceleration.y but when I did that, the circle is gone.
This is my html
<canvas id="myCanvas" width="200" height="200" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
This is my partial script
function movingCircle (acceleration) {
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var x = acceleration.x;
var y = acceleration.y;
ctx.fillStyle = "rgba(255, 255, 0, .5)";
ctx.beginPath();
ctx.arc(x,y,20,0,2*Math.PI, true);
ctx.stroke();
ctx.closePath();
ctx.fill();
c.innerHTML = 'testing';
}
ctx.arc(x,y,20,0,2*Math.PI, true); if I change the x and y into 47.5, 25 then I can see my circle clearly positioned near the top left corner.
Anyone can give me a hand what I did wrong here?
Acceleration's x & y keys are not absolute cordinates on which you can plot your circle. Acceleration is difference in velocity over time. So rather you them as quantities to add to your current circle position.
Something like: x = x + acceleration.x;