How can I do if I want to change the color of the area on the top of the drawed line. Here is my example:
https://www.w3schools.com/code/tryit.asp?filename=GG3IR6IS9TZ1
Thanks
Make a shape with your values and fill her.
https://www.w3schools.com/code/tryit.asp?filename=GG3J6QC13SU5
// your graph
ctx.beginPath();
ctx.moveTo(0, 40);
ctx.lineTo(300, 60);
ctx.stroke();
// fillment
ctx.beginPath();
ctx.moveTo(0, 40); //y our dynamic values
ctx.lineTo(300, 60); // your dynamic values
ctx.lineTo(300, 300); // canvas bottom right end
ctx.lineTo(0, 300); // canvas bottom left end
ctx.closePath();
Pass this logic for a function for other graph use, keep your code dry.
Related
How do I create a transparent gradient stroke that using html5 canvas? I need it to go from one point to another and look like the below image.
At the moment I have got this:
const gradient = ctx.createLinearGradient(1, 0, 100, 0);
gradient.addColorStop(0, '#fff');
gradient.addColorStop(1, '#d29baf');
ctx.lineWidth = 30;
ctx.strokeStyle = gradient;
ctx.beginPath();
ctx.moveTo(fromXPos, fromYPos);
ctx.lineTo(toXPos, toYPos);
ctx.stroke();
This makes it look like a solid block though like:
Thanks.
Fill a shape
Use a shape and fill it with the gradient.
You can use CSS colour type rgba(red,green,blue,alpha) where red,green,blue are values from 0-255 and alpha is 0 transparent to 1 opaque.
To create a shape you start with ctx.beginPath() to create a new shape then use lineTo(x,y) to mark out each corner. If you want to add another shape using the same fill or stroke you use ctx.moveTo(x,y) to move to the first point.
Note many people use ctx.beginPath(); ctx.moveTo(x,y); but that works just the same as ctx.beginPath(); ctx.lineTo(x,y); As the first point after beginPath is always converted to a moveTo for any type of path object.
const ctx = canvas.getContext("2d");
// draw first box (left of canvas)
ctx.fillStyle = "#ab7383";
ctx.fillRect(20,100,50,50);
// draw second box (to right of first)
ctx.fillStyle = "#904860";
ctx.fillRect(100,20,50,130);
// gradient from top of second box to bottom of both boxes
const g = ctx.createLinearGradient(0, 20, 0, 150);
g.addColorStop(0, `rgba(${0xd2},${0xba},${0xaf},1`); // opaque
g.addColorStop(1, `rgba(${0xd2},${0xba},${0xaf},0`); // transparent
ctx.fillStyle = g;
ctx.beginPath();
ctx.lineTo(70, 100); // top right of first box
ctx.lineTo(100, 20); // top left of second box
ctx.lineTo(100, 150); // bottom left of second box
ctx.lineTo(70, 150); // bottom right of first box
ctx.fill(); // fill the shape
<canvas id="canvas" style="border:2px solid black"></canvas>
I'm finishing a project, but I have one more step to finish.
I want to visualize microphone input by a canvas.
Getting the data from the microphone isn't a problem.
But I want to visualize it in a special way. (see image)
I want to animate each element from the wave.
My problem isn't the animation.
My problem is to create those shapes in the CANVAS.
This is an example of one shape:
I can create a rounded corner shape with the canvas
const draw = () => {
fillRoundedRect(20, 20, 100, 100, 20);
ctx.fillStyle = "red";
ctx.fill();
};
const fillRoundedRect = (x, y, w, h, r) => {
ctx.beginPath();
ctx.moveTo(x+r, y);
ctx.lineTo(x+w-r, y);
ctx.quadraticCurveTo(x+w, y, x+w, y+r);
ctx.lineTo(x+w, y+h-r);
ctx.quadraticCurveTo(x+w, y+h, x+w-r, y+h);
ctx.lineTo(x+r, y+h);
ctx.quadraticCurveTo(x, y+h, x, y+h-r);
ctx.lineTo(x, y+r);
ctx.quadraticCurveTo(x, y, x+r, y);
ctx.fill();
};
Can someone help me with creating a shape like in the second image?
Thanks in advance guys!
Instead of trying to make a single shape with dependency on surrounding shapes and a high risk of headache math-wise, use instead two shapes which you merge using composition. My suggestion anyways.
Draw all the bars in full height using composition mode source-over (default)
Define a single shape on top using some sort of spline (I would suggest a cardinal spline).
Set composition mode to destination-out and render an enclosed shape using the spline as top "line".
Example
This should work in a loop (remember to clear canvas for each frame) but shows only the building stones needed here -
var ctx = c.getContext("2d");
var points = [];
var skippy = 0;
// render all bars
ctx.globalCompositeOperation = "source-over"; // not needed here, but in a loop yes!
// produce bars
ctx.beginPath(); // not needed here, but in a loop yes!
for(var x = 0; x < c.width; x += 30) {
ctx.rect(x, 0, 16, c.height)
// OKIDOKI, lets produce the spline using random points (y) as well
// but not for all, only every second for prettyness... modify to taste
if (skippy++ % 2 === 0) points.push(x, c.height * Math.random());
}
points.push(c.width, c.height * Math.random()); // one last
ctx.fillStyle = "rgb(198, 198, 198)";
ctx.fill();
// render spline
ctx.beginPath();
ctx.moveTo(0, c.height); // bottom left corner
curve(ctx, points); // spline
ctx.lineTo(c.width, c.height); // bottom right corner
ctx.closePath();
ctx.globalCompositeOperation = "destination-out";
ctx.fill();
Right now I am playing around with Canvas and its features, however I am experiencing a weird problem. I am currently trying to draw a circle inside of a Triangle made of several "lineTo's". My problem being when I just implement an arc; it draws the Circle but with a line from the center and out towards the right side (angle 0). If I enclose my arc in beginPath and closePath it draws it perfectly however the Triangle disappears (JSFiddle is provided). Why is this happening also am I doing something specifically wrong? I am new to Canvas and I want to learn, thank you in advance!
JSFIDDLE https://jsfiddle.net/720hg2aq/1/
// Draw Triangle
ctx.moveTo((width*0.4), (height*0.05));
ctx.lineTo((width*0.6), (height*0.05));
ctx.moveTo((width*0.6), (height*0.05));
ctx.lineTo((width*0.5), (height*0.15));
ctx.moveTo((width*0.5), (height*0.15));
ctx.lineTo((width*0.4), (height*0.05));
ctx.moveTo((width*0.5), (height*0.09));
// End of Triangle
// Begin Circle
ctx.beginPath();
ctx.arc((width*0.5), (height*0.09), 20, 0 , 2 * Math.PI);
ctx.closePath();
// End Circle
// Draw it out
ctx.strokeStyle = '#000';
ctx.stroke();
The beginPath() method begins a path, or resets the current path.
Once you begin a path, use moveTo(), lineTo(), quadricCurveTo(), bezierCurveTo(), arcTo(), or arc() to make the path, then storke() it.
So the code should be:
ctx.strokeStyle = "black";
// Draw Triangle
ctx.beginPath(); /// Let's start the work!
ctx.moveTo((width*0.4), (height*0.05));
ctx.lineTo((width*0.6), (height*0.05));
ctx.moveTo((width*0.6), (height*0.05));
ctx.lineTo((width*0.5), (height*0.15));
ctx.moveTo((width*0.5), (height*0.15));
ctx.lineTo((width*0.4), (height*0.05));
ctx.moveTo((width*0.5), (height*0.09));
ctx.stroke(); /// Brushing with your dye!!
// End of Triangle
// Begin Circle
ctx.beginPath(); /// Let's start the **NEW** work!
/// Don't let the previous path be connected with the current path!
ctx.arc((width*0.5), (height*0.09), 20, 0 , 2 * Math.PI);
ctx.closePath();
ctx.stroke(); /// Brushing with your dye!!
// End Circle
I am trying to animate a small dot along a curved path using a HTML5 Canvas. The animation i have working but i cannot get the clearRect to work so each frame is just stacking on top of the next.
Here is the drawing code, can2 and ctx2 are global variable set in the .ready function of the page.
function drawTempStep(){
//Clear the Canvas
ctx2.clearRect(0, 0, can2.width, can2.height);
ctx2.save();
//Check we're centered
ctx2.moveTo(0, 0);
//Rotate Canvas so we are drawing strait
ctx2.rotate(getRadians(canvasRotation));
//Begin new Path
//Create reflection for the dot
//First create gradiated fill style
var grd = ctx2.createRadialGradient(0, weatherDivSize.width / 2 * .70, 0, 0, weatherDivSize.width / 2 * .70, weatherDivSize.width*.2);
grd.addColorStop(0, "rgba(176,0,0,0.2)");
grd.addColorStop(1, "rgba(0,0,0,0)");
//Now beging the path
ctx2.beginPath();
//Draw the Arc
ctx2.arc(0, weatherDivSize.width / 2 * .70, weatherDivSize.width*.2, 0, 2 * Math.PI, false);
ctx2.closePath();
//Fille and stroke it
ctx2.fillStyle = grd;
ctx2.fill();
ctx.stroke();
//Now lets draw the smaller inner circle
ctx2.beginPath();
ctx2.arc(0, weatherDivSize.width / 2 * .70, weatherDivSize.width*.009, 0, 2 * Math.PI, false);
ctx2.closePath();
ctx2.fillStyle = '#B00000';
ctx2.fill();
ctx.stroke();
//Return the canvas rotation to it's starting point
ctx2.rotate(-getRadians(canvasRotation));
//All done so restore the context to it's previous state
ctx2.restore();
}
Here is a link to the the full project on CodePen so you can see what's going on.
CodePen Link
Thanks
Gareth
i have four divs that is p1,p2,p3,p4. it is draggable. at any point i click "draw" button iwant to draw angle sign like below
$(document).ready(function(){
var c=document.getElementById('canvas');
var ctx=c.getContext("2d");
ctx.beginPath();
ctx.moveTo(parseInt($("#p1").css("left"))-5,parseInt($("#p1").css("top"))-5)
ctx.lineTo(parseInt($("#p2").css("left"))-5,parseInt($("#p2").css("top"))-5)
ctx.lineTo(parseInt($("#p3").css("left"))-5,parseInt($("#p3").css("top"))-5)
ctx.lineTo(parseInt($("#p4").css("left"))-5,parseInt($("#p4").css("top"))-5)
ctx.lineTo(parseInt($("#p1").css("left"))-5,parseInt($("#p1").css("top"))-5)
ctx.fillStyle='#E6E0EC';
ctx.fill();
ctx.strokeStyle="#604A7B";
ctx.lineWidth="3"
ctx.stroke();
ctx.closePath();
$("#p1,#p2,#p3,#p4").draggable({
drag:function(){
ctx.clearRect(0,0,500,500);
ctx.beginPath();
ctx.moveTo(parseInt($("#p1").css("left"))-5,parseInt($("#p1").css("top"))-5)
ctx.lineTo(parseInt($("#p2").css("left"))-5,parseInt($("#p2").css("top"))-5)
ctx.lineTo(parseInt($("#p3").css("left"))-5,parseInt($("#p3").css("top"))-5)
ctx.lineTo(parseInt($("#p4").css("left"))-5,parseInt($("#p4").css("top"))-5)
ctx.lineTo(parseInt($("#p1").css("left"))-5,parseInt($("#p1").css("top"))-5)
ctx.fillStyle='#E6E0EC';
ctx.fill();
ctx.strokeStyle="#604A7B";
ctx.lineWidth="3"
ctx.stroke();
ctx.closePath();
}
});
How can i make this please provide simple solution.
the fiddle:http://jsfiddle.net/b954W/
i want to draw the arc inside the shape at any point.
Here's how to illustrate the angle between line segments
Demo: http://jsfiddle.net/m1erickson/XnL3B/
Step#1: Calculate the angles
You can calculate the angle between 2 lines connected at a vertex using Math.atan2:
// calculate the angles in radians using Math.atan2
var dx1=pt1.x-pt2.x;
var dy1=pt1.y-pt2.y;
var dx2=pt3.x-pt2.x;
var dy2=pt3.y-pt2.y;
var a1=Math.atan2(dy1,dx1);
var a2=Math.atan2(dy2,dx2);
Step#2: Draw the angle's wedge
You can draw the wedge illustrating the angle using context.arc:
// draw angleSymbol using context.arc
ctx.save();
ctx.beginPath();
ctx.moveTo(pt2.x,pt2.y);
ctx.arc(pt2.x,pt2.y,20,a1,a2);
ctx.closePath();
ctx.fillStyle="red";
ctx.globalAlpha=0.25;
ctx.fill();
ctx.restore();
Step#3: Draw the degree angle in text
And you can draw the text of the angle (converted to degrees) using context.fillText:
// draw the degree angle in text
var a=parseInt((a2-a1)*180/Math.PI+360)%360;
ctx.fillStyle="black";
ctx.fillText(a,pt2.x+15,pt2.y);