How to draw flow chart document shape on canvas? - javascript

am trying to draw flow chart document shape (https://i.imgur.com/ZfWDDfs.png) on canvas i have partially done it but have hard time with the lower curve as it shows ok it one position but when i change x y coordinates the curve is effected so i wonder how to properly draw the curve in it so that it remain same after coordinate change.
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
// var x = 150, y = 150, w = 350, h = 350; // display ok
var x = 50, y = 50, w = 350, h = 350; // display not ok
ctx.lineWidth = 10;
ctx.beginPath();
ctx.lineJoin="round";
// draw one horizontal and two vertical lines
ctx.moveTo(x, y);
ctx.lineTo((x + w)+(w/4), y);
ctx.lineTo((x + w)+(w/4) , y + h/1.3);
ctx.moveTo(x, y);
ctx.lineTo(x, y + h);
// bottom curve .. problem start here
ctx.quadraticCurveTo(x,h + (h/1.2), (x + w/2) ,h + h/4);
ctx.lineTo((x + w)+(w/4), y+h/1.3);
ctx.stroke();
This code using x = 50 and y = 50 :
let drawChart = function(ctx, points) {
ctx.moveTo((points[0].x), points[0].y);
for (var i = 0; i < points.length - 1; i++) {
// Draw point
// ctx.arc(points[i].x, points[i].y, 2, 0, Math.PI * 2, false);
var x_mid = (points[i].x + points[i + 1].x) / 2;
var y_mid = (points[i].y + points[i + 1].y) / 2;
var cp_x1 = (x_mid + points[i].x) / 2;
var cp_y1 = (y_mid + points[i].y) / 2;
var cp_x2 = (x_mid + points[i + 1].x) / 2;
var cp_y2 = (y_mid + points[i + 1].y) / 2;
ctx.quadraticCurveTo(cp_x1, points[i].y, x_mid, y_mid);
ctx.quadraticCurveTo(cp_x2, points[i + 1].y, points[i + 1].x, points[i + 1].y);
ctx.stroke();
}
// ctx.arc(points[points.length - 1].x, points[points.length - 1].y, 2, 0, Math.PI * 2, false)
// ctx.stroke();
}
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
//var x = 150, y = 150, w = 350, h = 350; // ok
var x = 50,
y = 50,
w = 350,
h = 350; // not ok
ctx.lineWidth = 10;
ctx.beginPath();
ctx.lineJoin = "round";
ctx.moveTo(x, y);
ctx.lineTo((x + w) + (w / 4), y);
ctx.lineTo((x + w) + (w / 4), y + h / 1.3);
ctx.moveTo(x, y);
ctx.lineTo(x, y + h);
// var points = [{x:x,y:y + h},{x:(x + w/2),y:h + h/5},{x:(x + w)+(w/4),y:h/1.3 }]
// var points = [{x:x,y:y + h},{x:(x + w/3),y:h + h/2},{x:(x + w/1.2),y:h + h/4},{x:(x + w)+(w/4),y:h + h/5}]
//drawChart(ctx,points);
ctx.quadraticCurveTo(x, h + (h / 1.2), (x + w / 2), h + h / 4);
// ctx.quadraticCurveTo((x + w/2),h , (x + w)+(w/4) , h + h/5 );
ctx.lineTo((x + w) + (w / 4), y + h / 1.3);
// ctx.closePath();
ctx.stroke();
// ctx.fill();
<canvas id="myCanvas" width="800" height="600" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
http://jsfiddle.net/0da2e869/

You have to use :
ctx.quadraticCurveTo(x, y + h * 1.6, x + w / 2, y + h);
The first and second arg was position on your grid.
ctx.quadraticCurveTo(cpx, cpy, x, y);
NB : To improve your draw use ctx.lineCap = "round";. ;)
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
drawIt(150, 150, 350, 350); // ok
ctx.strokeStyle = "red";
drawIt(50, 50, 350, 350); // not ok
function drawIt(x, y, w, h) {
ctx.lineWidth = 10;
ctx.beginPath();
ctx.lineJoin = "round";
ctx.lineCap = "round"; //<========== lineCap
ctx.moveTo(x, y);
ctx.lineTo((x + w) + (w / 4), y);
ctx.lineTo((x + w) + (w / 4), y + h / 1.3);
ctx.moveTo(x, y);
ctx.lineTo(x, y + h);
ctx.quadraticCurveTo(x, y + h * 1.6, x + w / 2, y + h);
ctx.lineTo((x + w) + (w / 4), y + h / 1.3);
ctx.stroke();
}
canvas {
/* Focus on the "not ok" */
transform-origin: top left;
transform: scale(.25);
transition:1s;
}
body:hover canvas {
/* Focus on the "not ok" */
transform-origin: top left;
transform: none;
}
<canvas id="myCanvas" width="800" height="800" style="border:1px solid #d3d3d3;"></canvas>

Related

Fabric JS how to set border radius on bounding box of selected objects

Is it possible to change the border radius of a bounding box of a selected item? I have read through the documentation of the possible attributes that can be attributed to an object and haven't found anything that specifies the changing of the border radius of an object's bounding box. Is there perhaps an solution through CSS this can be done?
Here's a drop-in replacement for the fabric.Object.prototype.drawBorders method that handles the drawing of selection borders. I've extended it to use the property selectionRadius to determine the amount of border radius to use in the selection box.
var canvas = new fabric.Canvas("canvas");
canvas.add(new fabric.Rect({
width: 150,
height: 100,
left: 25,
top: 25,
fill: 'lightgreen',
strokeWidth: 0,
padding: 20,
selectionRadius: 20,
borderColor: 'red'
}));
fabric.Object.prototype.drawBorders = function(ctx, styleOverride) {
styleOverride = styleOverride || {};
var wh = this._calculateCurrentDimensions(),
strokeWidth = this.borderScaleFactor,
width = wh.x + strokeWidth,
height = wh.y + strokeWidth,
hasControls = typeof styleOverride.hasControls !== 'undefined' ?
styleOverride.hasControls : this.hasControls,
shouldStroke = false;
ctx.save();
ctx.strokeStyle = styleOverride.borderColor || this.borderColor;
this._setLineDash(ctx, styleOverride.borderDashArray || this.borderDashArray, null);
//start custom draw method with rounded corners
var rx = this.selectionRadius ? Math.min(this.selectionRadius, width / 2) : 0,
ry = this.selectionRadius ? Math.min(this.selectionRadius, height / 2) : 0,
w = width,
h = height,
x = -width / 2,
y = -height / 2,
isRounded = rx !== 0 || ry !== 0,
/* "magic number" for bezier approximations of arcs */
k = 1 - 0.5522847498;
ctx.beginPath();
ctx.moveTo(x + rx, y);
ctx.lineTo(x + w - rx, y);
isRounded && ctx.bezierCurveTo(x + w - k * rx, y, x + w, y + k * ry, x + w, y + ry);
ctx.lineTo(x + w, y + h - ry);
isRounded && ctx.bezierCurveTo(x + w, y + h - k * ry, x + w - k * rx, y + h, x + w - rx, y + h);
ctx.lineTo(x + rx, y + h);
isRounded && ctx.bezierCurveTo(x + k * rx, y + h, x, y + h - k * ry, x, y + h - ry);
ctx.lineTo(x, y + ry);
isRounded && ctx.bezierCurveTo(x, y + k * ry, x + k * rx, y, x + rx, y);
ctx.closePath();
ctx.stroke();
//end custom draw method with rounded corners
if (hasControls) {
ctx.beginPath();
this.forEachControl(function(control, key, fabricObject) {
// in this moment, the ctx is centered on the object.
// width and height of the above function are the size of the bbox.
if (control.withConnection && control.getVisibility(fabricObject, key)) {
// reset movement for each control
shouldStroke = true;
ctx.moveTo(control.x * width, control.y * height);
ctx.lineTo(
control.x * width + control.offsetX,
control.y * height + control.offsetY
);
}
});
if (shouldStroke) {
ctx.stroke();
}
}
ctx.restore();
return this;
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.4.0/fabric.min.js"></script>
<canvas id="canvas" height="300" width="400"></canvas>

Rotating HTML canvas text

I have a rectangle with text labelled 150 along the edge
How do I rotate the text "150" to read as bottom to top. The below code makes 150 to look top to bottom along the edge.
The expected is above
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
const x = 150;
const y = 150;
const w = 200;
const h = 150;
ctx.fillStyle = "gray";
ctx.fillRect(x + 0.5, y + 0.5, w, h);
ctx.font = "12px Comic Sans MS";
ctx.fillStyle = "black";
ctx.textAlign = "center";
ctx.fillText("Rectangle", x + w / 2, y + h / 2);
ctx.fillText('200', x + w / 2, y + h - 5);
ctx.save();
ctx.translate(x + w, y + h / 2);
ctx.rotate(90 * Math.PI / 180);
ctx.fillText('150', 0, 0 + w - 5);
ctx.restore();
<canvas id="myCanvas" width="400" height="300"></canvas>
Notice negative translation & negative rotation.
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
const x = 150;
const y = 150;
const w = 200;
const h = 150;
ctx.fillStyle = "gray";
ctx.fillRect(x + 0.5, y + 0.5, w, h);
ctx.font = "12px Comic Sans MS";
ctx.fillStyle = "black";
ctx.textAlign = "center";
ctx.fillText("Rectangle", x + w / 2, y + h / 2);
ctx.fillText('200', x + w / 2, y + h - 5);
ctx.save();
ctx.translate(x - w, y + h / 2);
ctx.rotate(-90 * Math.PI / 180);
ctx.fillText('150', 0, w + 15); /* 15 is width of the text itself */
ctx.restore();
<canvas id="myCanvas" width="400" height="300"></canvas>

How to make a small triangle in a rectangle shape in canvas?

I want to add a small triangle similar to this example:
As you can see from the image there is a triangle in the middle of the side, I would like to have that in canvas.
This is what I have so far
// JavaScript for drawing on canvas
// applying colors + three triangles
function draw() {
// canvas with id="myCanvas"
var canvas = document.getElementById('myCanvas');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
roundRect(ctx, 100, 100, 180, 60, 10, true);
}
}
function roundRect(ctx, x, y, width, height, radius, fill, stroke) {
if (typeof stroke == "undefined") {
stroke = true;
}
if (typeof radius === "undefined") {
radius = 5;
}
ctx.beginPath();
ctx.moveTo(x + radius, y);
ctx.lineTo(x + width - radius, y);
ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
ctx.lineTo(x + width, y + height - radius);
ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
ctx.lineTo(x + radius, y + height);
ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
ctx.lineTo(x, y + radius);
ctx.quadraticCurveTo(x, y, x + radius, y);
ctx.closePath();
if (stroke) {
ctx.stroke();
}
if (fill) {
ctx.fill();
}
}
draw();
<canvas id="myCanvas" width="700" height="410">
<p>Some default content can appear here.</p>
</canvas>
<p>Triangles!</p>
4 arcs for a rounded box plus a triangle to fit..
You can create a rounded box with just the rounded corners. Adding the triangle is just a matter of setting out the 3 points between drawing two corners.
The example draws two types of quote boxes, left and right.
The size, corner radius, triangle size and position are all set as arguments.
The animation is just to show the variations possible.
const ctx = canvas.getContext("2d");
// r is radius of corners in pixels
// quoteSize in pixels
// quotePos as fraction of avalible space 0-1
function roundedQuoteBoxLeft(x, y, w, h, r, quoteSize, quotePos) {
// draw 4 corners of box from top, left, top right , bottom right, bottom left
ctx.arc(x + r, y + r, r, Math.PI, Math.PI * 1.5);
ctx.arc(x + w - r, y + r, r, Math.PI * 1.5, Math.PI * 2);
ctx.arc(x + w - r, y + h - r, r, 0, Math.PI * 0.5);
ctx.arc(x + r, y + h - r, r, Math.PI * 0.5, Math.PI);
// make sure trianle fits
if (quoteSize > h - r * 2) { quoteSize = h - r * 2 }
// get triangle position
var qy = (h - (r * 2 + quoteSize)) * quotePos + r + y;
// draw triangle
ctx.lineTo(x, qy + quoteSize);
ctx.lineTo(x - quoteSize, qy + quoteSize / 2);
ctx.lineTo(x, qy);
// and add the last line back to start
ctx.closePath();
}
function roundedQuoteBoxRight(x, y, w, h, r, quoteSize, quotePos) {
// draw top arcs from left to right
ctx.arc(x + r, y + r, r, Math.PI, Math.PI * 1.5);
ctx.arc(x + w - r, y + r, r, Math.PI * 1.5, Math.PI * 2);
// make sure trianle fits
if (quoteSize > h - r * 2) { quoteSize = h - r * 2 }
// get pos of triangle
var qy = (h - (r * 2 + quoteSize)) * quotePos + r + y;
// draw triangle
ctx.lineTo(x + w, qy);
ctx.lineTo(x + w + quoteSize, qy + quoteSize / 2);
ctx.lineTo(x + w, qy + quoteSize);
// draw remaining arcs
ctx.arc(x + w - r, y + h - r, r, 0, Math.PI * 0.5);
ctx.arc(x + r, y + h - r, r, Math.PI * 0.5, Math.PI);
// and add the last line back to start
ctx.closePath();
}
function sin(time) {
return Math.sin(time) * 0.5 + 0.5;
}
requestAnimationFrame(drawIt)
function drawIt(time) {
ctx.clearRect(0, 0, 500, 250);
// get some sizes
var width = sin(time / 1000) * 100 + 100;
var height = sin(time / 1300) * 50 + 100;
var radius = sin(time / 900) * 20 + 5;
var x = sin(time / 1900) * 20 + 20;
var y = sin(time / 1400) * 50 + 10;
var quotePos = sin(time / 700)
var quoteSize = x - 10;
// set up box render
ctx.lineJoin = "round";
ctx.strokeStyle = "#8D4";
ctx.lineWidth = 4;
ctx.fillStyle = "#482";
// draw left quote box
ctx.beginPath();
roundedQuoteBoxLeft(x, y, width, height, radius, quoteSize, quotePos);
ctx.fill();
ctx.stroke()
x += width + 10;
width = 500 - x - quoteSize;
// draw right quote box
ctx.beginPath();
roundedQuoteBoxRight(x, y, width, height, radius, quoteSize, quotePos);
ctx.fill();
ctx.stroke()
/// animate
requestAnimationFrame(drawIt)
}
<canvas id="canvas" width="500" height="250"></canvas>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Your Canvas</title>
<style type="text/css"><!--
#container { position: relative; }
#imageTemp { position: absolute; top: 1px; left: 1px; }
--></style>
</head>
<body>
<canvas id="imageView" width="600" height="500"></canvas>
<script type="text/javascript">
var canvas, context, canvaso, contexto;
canvaso = document.getElementById('imageView');
context = canvaso.getContext('2d');
context.lineWidth = 5;
context.strokeStyle = '#000000';
context.beginPath();
context.moveTo(143, 224);
context.lineTo(168, 191);
context.stroke();
context.closePath();
context.strokeStyle = '#000000';
context.beginPath();
context.moveTo(143, 221);
context.lineTo(169, 247);
context.stroke();
context.closePath();
context.strokeStyle = '#000000';
context.strokeRect(168, 124, 242, 182);
</script>
</body>
</html>

Basketball Physics Collision Detection and Bounce Physics

I am making a basketball physics simulator. I am am using a parametric equation to calculate the path of the ball. I am having a hard time with collision detection with the front of the rim, backboard, pole, and the court floor (bottom of canvas). Additionally I want to make the ball bounce when hitting these objects but I am having a hard time. Can anyone offer some help with this problem?
Here is the code snippet:
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.transform(1, 0, 0, -1, 0, canvas.height)
ctx.translate(canvas.width / 2, canvas.height / 2);
var speed = 5;
var gravity = 16;
var bounce = 10;
var mouseX = 0;
var mouseY = 0;
var stage = 1;
var x = 0;
var y = 0;
var xOrgn = 0;
var yOrgn = 0;
var xClk = 175;
var yClk = 100;
var mag = 0;
var ang = 0;
var xVel = 0;
var yVel = 0;
var time = 0;
function drawBall() {
ctx.beginPath();
ctx.arc(x, y, 12, 0, Math.PI * 2);
ctx.fillStyle = "#FF8C00";
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.lineWidth = 2;
ctx.moveTo(x, y + 12);
ctx.lineTo(x, y - 12);
ctx.strokeStyle = 'black';
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.lineWidth = 2;
ctx.moveTo(x - 12, y);
ctx.lineTo(x + 12, y);
ctx.strokeStyle = 'black';
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.lineWidth = 2;
ctx.moveTo(x - 8, y - 8);
ctx.bezierCurveTo(x - 2, y - 4, x - 2, y + 4, x - 8, y + 8);
ctx.strokeStyle = 'black';
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.lineWidth = 2;
ctx.moveTo(x + 8, y - 8);
ctx.bezierCurveTo(x + 2, y - 4, x + 2, y + 4, x + 8, y + 8);
ctx.strokeStyle = 'black';
ctx.stroke();
}
function drawHoop() {
ctx.beginPath();
ctx.rect(228, -160, 12, 172);
ctx.fillStyle = "#191919";
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.rect(222, -12, 6, 80);
ctx.fillStyle = "#666666";
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.rect(171, -6, 51, 6);
ctx.fillStyle = "#e50000";
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.arc(171, -3, 3, 0, Math.PI * 2);
ctx.fillStyle = "#e50000";
ctx.fill();
ctx.closePath();
}
function drawCursor() {
ctx.beginPath();
ctx.lineWidth = 2;
ctx.moveTo(mouseX - 12, mouseY);
ctx.lineTo(mouseX + 12, mouseY);
ctx.strokeStyle = '#00cd00';
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.lineWidth = 2;
ctx.moveTo(mouseX, mouseY - 12);
ctx.lineTo(mouseX, mouseY + 12);
ctx.strokeStyle = '#00cd00';
ctx.stroke();
ctx.closePath();
}
function calcVel() {
mag = Math.sqrt((Math.pow(xClk - xOrgn, 2) + Math.pow(yClk - yOrgn, 2)) / 4);
ang = Math.atan((yClk - yOrgn) / (xClk - xOrgn));
xVel = mag * Math.cos(ang);
yVel = mag * Math.sin(ang);
}
function draw() {
ctx.clearRect(-(canvas.width / 2), -(canvas.height / 2), canvas.width, canvas.height);
ctx.canvas.addEventListener('mousemove', function(event) {
mouseX = event.clientX - ctx.canvas.offsetLeft - canvas.width / 2;
mouseY = -event.clientY + ctx.canvas.offsetTop + canvas.height / 2;
});
drawBall();
drawHoop();
if (stage === 1) {
x = mouseX;
y = mouseY;
ctx.canvas.addEventListener('click', function(event) {
xOrgn = x;
yOrgn = y;
stage = 2;
});
} else if (stage === 2) {
drawCursor();
ctx.canvas.addEventListener('click', function(event) {
xClk = mouseX;
yclk = mouseY;
calcVel();
time = 0;
stage = 3;
});
} else if (stage === 3) {
x = xVel * time + xOrgn;
y = -gravity * Math.pow(time, 2) + yVel * time + yOrgn;
time = time + speed * 0.01;
}
}
setInterval(draw, 10);
canvas {
background: white;
}
<canvas id="myCanvas" width="480" height="320"></canvas>
Here is the code in jsfiddle: JSfiddle
You have to add collision detection in "Stage 3" only. Since the locations and sizes of everything are hardcoded, it's pretty simple to add in collision detection item by item. (but if you make this much more complicated, I would add in some variables or objects that make it easy to get the positions of things as variables, etc).
I added in a horizontal bounce when the ball hits the backboard, and a vertical bounce off the floor. Any others are similar.
(Note, what made these possible were updating x and y (and xVel, yVel) iteratively rather than from a determined equation. The results are the same, but the calculation and dynamic behaviour are easier).
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.transform(1, 0, 0, -1, 0, canvas.height)
ctx.translate(canvas.width / 2, canvas.height / 2);
var speed = 5;
var gravity = 16;
var bounce = 10;
var mouseX = 0;
var mouseY = 0;
var stage = 1;
var x = 0;
var y = 0;
var xOrgn = 0;
var yOrgn = 0;
var xClk = 175;
var yClk = 100;
var mag = 0;
var ang = 0;
var xVel = 0;
var yVel = 0;
var time = 0;
function drawBall() {
ctx.beginPath();
ctx.arc(x, y, 12, 0, Math.PI * 2);
ctx.fillStyle = "#FF8C00";
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.lineWidth = 2;
ctx.moveTo(x, y + 12);
ctx.lineTo(x, y - 12);
ctx.strokeStyle = 'black';
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.lineWidth = 2;
ctx.moveTo(x - 12, y);
ctx.lineTo(x + 12, y);
ctx.strokeStyle = 'black';
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.lineWidth = 2;
ctx.moveTo(x - 8, y - 8);
ctx.bezierCurveTo(x - 2, y - 4, x - 2, y + 4, x - 8, y + 8);
ctx.strokeStyle = 'black';
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.lineWidth = 2;
ctx.moveTo(x + 8, y - 8);
ctx.bezierCurveTo(x + 2, y - 4, x + 2, y + 4, x + 8, y + 8);
ctx.strokeStyle = 'black';
ctx.stroke();
}
function drawHoop() {
ctx.beginPath();
ctx.rect(228, -160, 12, 172);
ctx.fillStyle = "#191919";
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.rect(222, -12, 6, 80);
ctx.fillStyle = "#666666";
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.rect(171, -6, 51, 6);
ctx.fillStyle = "#e50000";
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.arc(171, -3, 3, 0, Math.PI * 2);
ctx.fillStyle = "#e50000";
ctx.fill();
ctx.closePath();
}
function drawCursor() {
ctx.beginPath();
ctx.lineWidth = 2;
ctx.moveTo(mouseX - 12, mouseY);
ctx.lineTo(mouseX + 12, mouseY);
ctx.strokeStyle = '#00cd00';
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.lineWidth = 2;
ctx.moveTo(mouseX, mouseY - 12);
ctx.lineTo(mouseX, mouseY + 12);
ctx.strokeStyle = '#00cd00';
ctx.stroke();
ctx.closePath();
}
function calcVel() {
mag = Math.sqrt((Math.pow(xClk - xOrgn, 2) + Math.pow(yClk - yOrgn, 2)) / 4);
ang = Math.atan((yClk - yOrgn) / (xClk - xOrgn));
xVel = mag * Math.cos(ang);
yVel = mag * Math.sin(ang);
}
function draw() {
ctx.clearRect(-(canvas.width / 2), -(canvas.height / 2), canvas.width, canvas.height);
ctx.canvas.addEventListener('mousemove', function(event) {
mouseX = event.clientX - ctx.canvas.offsetLeft - canvas.width / 2;
mouseY = -event.clientY + ctx.canvas.offsetTop + canvas.height / 2;
});
drawBall();
drawHoop();
if (stage === 1) {
x = mouseX;
y = mouseY;
ctx.canvas.addEventListener('click', function(event) {
xOrgn = x;
yOrgn = y;
stage = 2;
});
} else if (stage === 2) {
drawCursor();
ctx.canvas.addEventListener('click', function(event) {
xClk = mouseX;
yclk = mouseY;
calcVel();
time = 0;
stage = 3;
});
} else if (stage === 3) {
//x = xVel * time + xOrgn;
// update x from it's own value so we can vary the xVel.
x += xVel * speed * 0.01;
//y = -gravity * Math.pow(time, 2) + yVel * time + yOrgn;
// update yVel and y iteratively instead of this determined calculation
//y = -gravity * Math.pow(time, 2) + yVel * time + yOrgn;
yVel -= gravity * 0.1;
y += yVel * speed * 0.01;
// do a collision check: the backboard.
if (x > 222 - 12 && y > -12 && y < 62) {
xVel *= -1;
}
// with floor
if(y <= -142) {
y = -142;
yVel *= -1;
}
time = time + speed * 0.01;
}
}
setInterval(draw, 10);
canvas {
background: white;
}
<canvas id="myCanvas" width="480" height="320"></canvas>
You can handle any other collisions you want similarly

Is there a way to convert the plot of an equation into the plot of an inequality using Canvas?

I have some code that plots the equation of a graph in a coordinate plane. (Please see the comment below for the JsFiddle link that contains the code.) I'm trying to find a way to shade the region "less than" the equation, so that instead of plotting y = [equation], the graph depicts y < [equation]. It seems like this can be done for individual data points using "type:area" in canvas, but I'm wondering if this can be applied to the plot of an equation. I would greatly appreciate any help anyone can offer. Thanks!
var x_axis = 200;
var y_axis = 200;
var x_max = 7; // THIS CHANGES RANGE OF X-AXIS
var y_max = 7; // THIS CHANGES RANGE OF Y-AXIS
var x_scale = x_axis / (x_max + 1);
var y_scale = y_axis / (y_max + 1);
var x_offset = x_axis + 0.5; // location on canvas
var y_offset = y_axis + 0.5; // of graph's origin
var canvas = document.getElementById("axes");
if (canvas.getContext) {
canvas.width = x_axis * 2;
canvas.height = y_axis * 2;
var ctx = canvas.getContext("2d");
drawAxes(ctx);
}
function drawAxes(ctx) {
ctx.font = "20px";
ctx.font = "14px";
ctx.strokeText('Y', x_axis - 25, 10); //CHANGES LABEL OF Y-AXIS
ctx.strokeText('X', x_axis * 2 - 10, y_axis + 20); //CHANGES LABEL OF X-AXIS
ctx.font = "12px sans-serif";
ctx.lineWidth = 1;
// draw x-axis
ctx.beginPath();
ctx.moveTo(0, y_offset);
ctx.lineTo(x_axis * 2, y_offset);
ctx.stroke();
ctx.closePath();
// draw arrow
ctx.beginPath();
ctx.moveTo(x_axis * 2 + 0.5, y_axis + 0.5);
ctx.lineTo(x_axis * 2 + 0.5 - 8, y_axis + 0.5 - 3);
ctx.lineTo(x_axis * 2 + 0.5 - 8, y_axis + 0.5 + 3);
ctx.stroke();
ctx.closePath();
ctx.fill();
// draw x values
j = -x_max;
while (j <= x_max) {
x = j * x_scale;
ctx.strokeStyle = '#aaa';
ctx.beginPath();
ctx.moveTo(x + x_offset, y_offset);
ctx.lineTo(x + x_offset, y_offset + 10);
ctx.stroke();
ctx.closePath();
ctx.strokeStyle = '#666';
ctx.strokeText(j, x + x_offset - 10, y_offset + 20);
j++;
if (j == 0) {
j++;
}
}
// draw y-axis
ctx.beginPath();
ctx.moveTo(x_offset, 0);
ctx.lineTo(x_offset, y_axis * 2);
ctx.stroke();
ctx.closePath();
// draw arrow
ctx.beginPath();
ctx.moveTo(x_axis + 0.5, 0.5);
ctx.lineTo(x_axis + 0.5 - 3, 0.5 + 8);
ctx.lineTo(x_axis + 0.5 + 3, 0.5 + 8);
ctx.stroke();
ctx.closePath();
ctx.fill();
// draw y values
j = -y_max;
while (j <= y_max) {
y = j * y_scale;
ctx.strokeStyle = '#aaa';
ctx.beginPath();
ctx.moveTo(x_offset, y + y_offset);
ctx.lineTo(x_offset - 10, y + y_offset);
ctx.stroke();
ctx.closePath();
ctx.strokeStyle = '#666';
ctx.strokeText(-j, x_offset - 25, y + y_offset + 5);
j++;
if (j == 0) {
j++;
}
}
}
function offsetX(v) {
return x_offset + (v * x_scale);
}
function offsetY(v) {
return y_offset - (v * y_scale);
}
var canvas1 = document.getElementById("plot");
if (canvas1.getContext) {
canvas1.width = x_axis * 2;
canvas1.height = y_axis * 2;
var ctx1 = canvas1.getContext("2d");
ctx1.lineWidth = 1;
ctx1.beginPath();
ctx1.strokeStyle = 'black';
x = -x_max;
y = x * x; // FIRST THING TO CHANGE TO CHANGE EQUATION (MUST USE * FOR MULTIPLICATION)
ctx1.moveTo(offsetX(x), offsetY(y));
while (x < x_max) { // INCLUDE CODE FOR BROKEN LINE IN HERE
x += 0.1;
y = x * x; // SECOND THING TO CHANGE TO CHANGE EQUATION (MUST USE * FOR MULTIPLICATION)
ctx1.lineTo(offsetX(x), offsetY(y));
}
ctx1.stroke();
ctx1.closePath();
ctx.setTransform(0, 2, -2, 0, 3 * (y_axis / j), 3 * (x_axis / j)); // CHANGE LOCATION OF POINT; "3*(y_axis/j)" IS THE X-UNIT, SUCH THAT J IS THE MAXIMUM VALUE ON THE X-AXIS & 3 IS THE NUMBER OF INTERVALS FROM THE LEFT; "3*(X_axis/j)" IS THE Y-UNIT, SUCH THAT J IS THE MAXIMUM VALUE ON THE Y-AXIS & 3 IS THE NUMBER OF INTERVALS FROM THE TOP;
ctx.arc(1, 0, 2, 0, Math.PI * 2)
ctx.fill()
}
body {
margin: 20px 0 0 20px;
position: relative;
}
canvas {
left: 0;
position: absolute;
top: 0;
}
<canvas id="axes"></canvas>
<canvas id="plot"></canvas>
</body>

Categories