I have the rectangle pointing at the mouse. What I want: when I lift the mouse and click and drag that the rectangle rotates further.
Or that I can click on any corner to rotate the rectangle. Just like you would with your finger and a sheet of paper.
let angle = 0;
function setup() {
createCanvas(400, 400);
}
function draw() {
background(220);
push();
translate(150, 150);
rotate(angle);
stroke(0);
strokeWeight(2);
rect(-100, -75, 200, 150);
stroke(255, 0, 0);
strokeWeight(5);
line(-100, -75, 100, -75);
stroke(0, 255, 0);
point(0, 0);
pop();
}
function mouseDragged() {
m_angle = atan2(mouseY - 150, mouseX - 150);
angle = /* MAGIC FORMULA HERE */ m_angle;
}
https://editor.p5js.org/jwglazebrook/sketches/p2pnhPSZE
The Problem:
The issue with your code is that you need to store the offset from the initial mouse click to the new dragged point.
The Solution:
To fix the jerky behavior we just have to store the previous mouse angle and box angle and compare the difference with the dragged mouse angle.
The Code:
let angle = 0;
function setup() {
angleMode(DEGREES);
createCanvas(400, 400);
}
function draw() {
background(220);
push();
translate(150, 150);
rotate(angle);
stroke(0);
strokeWeight(2);
rect(-100, -75, 200, 150);
stroke(255, 0, 0);
strokeWeight(5);
line(-100, -75, 100, -75);
stroke(0, 255, 0);
point(0, 0);
pop();
}
let c_angle = 0;
let q_angle = 0;
function mousePressed() {
c_angle = atan2(mouseY - 150, mouseX - 150); //The initial mouse rotation
q_angle = angle; //Initial box rotation
}
function mouseDragged() {
m_angle = atan2(mouseY - 150, mouseX - 150);
let dangle = m_angle - c_angle; //How much the box needs to be rotated
if (dangle>=360) dangle-=360; //clamping
if (dangle<0) dangle+=360; //clamping
angle = q_angle + dangle; //Apply the rotation
if (angle>=360) angle -= 360; //clamping
}
Related
Here is a code I wrote in which I made two different arcs inside a circle. As of now both the arcs changes color at the same time when clicked inside the circle.
I cannot find a way to change the color of the specific arc which is getting clicked on.
Code
function setup() {
createCanvas(500, 500);
r = random(255);
g = random(255);
b = random(255);
}
function draw() {
background(255);
stroke(0);
strokeWeight(10);
fill(r, g, b, 127);
arc(200, 200, 200, 200, HALF_PI, PI*1.75);
stroke(0);
strokeWeight(10);
fill(r-200, g-20, b-55, 200);
arc(200, 200, 200, 200, 5.50, HALF_PI);
fill(255);
ellipse(200, 200, 150, 150);
}
function mousePressed() {
let d = dist(mouseX, mouseY, 200, 200);
if (d < 100) {
// Pick new random color values
r = random(255);
g = random(255);
b = random(255);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.0.0/p5.min.js"></script>
You need 2 colors. I recommend to use color():
let color1, color2;
function setup() {
createCanvas(500, 500);
color1 = color(random(255), random(255), random(255), 127);
color2 = color(random(255), random(255), random(255), 200);
}
function draw() {
// [...]
fill(color1);
arc(200, 200, 200, 200, startAngle, endAngle);
// [...]
fill(color2);
arc(200, 200, 200, 200, endAngle, startAngle);
}
Define a start angle and end angle:
let startAngle = Math.PI/2;
let endAngle = Math.PI*1.75;
Compute the angle of the vector form the center of the arc to the mouse:
let angle = Math.atan2(mouseY - 200, mouseX - 200);
if (angle < 0) angle += Math.PI*2;
Change one of the colors accordingly:
if (d < 100 && d > 75) {
if (angle > startAngle && angle < endAngle) {
color1 = color(random(255), random(255), random(255), 127);
} else {
color2 = color(random(255), random(255), random(255), 127);
}
}
let color1, color2;
let startAngle = Math.PI/2;
let endAngle = Math.PI*1.75;
function setup() {
createCanvas(500, 500);
color1 = color(random(255), random(255), random(255), 127);
color2 = color(random(255), random(255), random(255), 200);
}
function draw() {
background(255);
stroke(0);
strokeWeight(10);
fill(color1);
arc(200, 200, 200, 200, startAngle, endAngle);
stroke(0);
strokeWeight(10);
fill(color2);
arc(200, 200, 200, 200, endAngle, startAngle);
fill(255);
ellipse(200, 200, 150, 150);
}
function mousePressed() {
let d = dist(mouseX, mouseY, 200, 200);
let angle = Math.atan2(mouseY - 200, mouseX - 200);
if (angle < 0) angle += Math.PI*2;
if (d < 100 && d > 75) {
if (angle > startAngle && angle < endAngle) {
color1 = color(random(255), random(255), random(255), 127);
} else {
color2 = color(random(255), random(255), random(255), 127);
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.0.0/p5.min.js"></script>
I want to make a rectangle rotate around its center as in this code. The problem is that the rectangle rotates on mouse drag on any area.
I want the rectangle to rotate on its position when the mouse drags it only not any mouse drag rotates it.
I am using the p5.js library.
If there any code that rotates rectangle around its center on the mouse drag that please share it with me.
Link of code: https://editor.p5js.org/jwglazebrook/sketches/p2pnhPSZE
let angle = 0;
function setup() {
createCanvas(400, 400);
}
function draw() {
background(220);
push();
translate(150, 150);
rotate(angle);
stroke(0);
strokeWeight(2);
rect(-100, -75, 200, 150);
stroke(255, 0, 0);
strokeWeight(5);
line(-100, -75, 100, -75);
stroke(0, 255, 0);
point(0, 0);
pop();
}
function mouseDragged() {
m_angle = atan2(mouseY - 150, mouseX - 150);
angle = /* MAGIC FORMULA HERE */ m_angle;
}
Code of 2 circle
let angle = 0.6;
function setup() {
createCanvas(400, 400);
}
function draw() {
background(204, 226, 225); // Light blue color
fill(204, 226, 225); // Blue color
push();
translate(150, 150);
rotate(angle);
circle(-50,0,100);
circle(50,0,100);
pop();
line(100, 100, 200, 200);
}
function mouseDragged() {
m_angle = atan2(mouseY - 150, mouseX - 150);
angle = m_angle;
}
I am using p5.js to draw a simple line.
function setup() {
//createCanvas(windowWidth, windowHeight);
createCanvas(400, 200);
}
function draw() {
background(255, 255, 255);
fill(255, 0, 0);
stroke(255, 0, 0);
strokeWeight(1);
line(0, 0, 250, 100);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.10.2/p5.js"></script>
But the line drawn suddenly at once.
How can I draw the line slowly / gradually? (i.e in 300 milliseconds).
That it looks like animating from point(0,0) to point(250,100).
I had a quick look at p5 and it looks like it calls the draw method at intervals. If you want movement to happen you just need to program it.
I've put together a quick example below. I think it's drawing a lot slower than you want but I'm not sure how often p5 calls draw.
var position = 0,
end = 300;
function setup() {
//createCanvas(windowWidth, windowHeight);
createCanvas(400, 200);
}
function draw() {
background(255, 255, 255);
fill(255, 0, 0);
stroke(255, 0, 0);
strokeWeight(1);
var xEnd = 250,
yEnd = 100;
// Got to the end yet?
if (position < end) {
// Work out positions.
xEnd = (xEnd / end) * position;
yEnd = (yEnd / end) * position;
}
line(0, 0, xEnd, yEnd);
// Increment position.
position++;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.10.2/p5.js"></script>
FrameRate can be used to adjust the speed of a drawing. This sketch draws a diagonal line that begins slowly at point 0,0 and then speeds up until it reaches point 250, 100.
var x = 0;
function setup() {
createCanvas(400, 200);
frameRate(10);
}
function draw() {
background(255, 255, 255);
fill(255, 0, 0);
stroke(255, 0, 0);
strokeWeight(1);
// y = mx + b
line(0, 0, x, 100/250*x);
x++;
if (x > 50){
frameRate(30);
}
if (x > 250){
noLoop();
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/p5.min.js"></script>
I currently have a canvas that has an element drawn on it that I draw using a custom function and the onload function I would like to know how to be able to rotate this canvas around by following the mouse 360 degrees like turning a wheel. The code is as follows
<!DOCTYPE html>
<html>
<head>
<title>Help</title>
</head>
<body>
<canvas id="MyCanvas" width="500" height="500"></canvas>
<script>
var ctx = document.getElementById("MyCanvas").getContext("2d");
ctx.translate(250,250);
function draw(){
ctx.arc(0,0,100,0,Math.PI*2,false); // x, y, radius, start angle, end angle, false/true
ctx.stroke();
ctx.beginPath();
ctx.moveTo(-100,0);
ctx.lineTo(100,0);
ctx.moveTo(100,0);
ctx.lineTo(60,-80);
ctx.moveTo(60,-80);
ctx.lineTo(-100,0);
ctx.stroke();
}
window.onload=draw;
</script>
</body>
</html>
Does anyone know how this would be possible I have tried multiple different functions. however, they do not seem to be able to do anything.
help will be very appreciated.
Edited but with slight issue
<!DOCTYPE html>
<html>
<head>
<title>Help</title>
</head>
<style>
canvas{
border: 2px solid black;
}
</style>
<body>
<canvas id="Canvas" height="300"></canvas>
<script>
const ctx = canvas.getContext("2d");
const mouse = { x: 0, y: 0 };
function mouseEvents(e) {
const bounds = canvas.getBoundingClientRect();
mouse.x = e.pageX - bounds.left - scrollX;
mouse.y = e.pageY - bounds.top - scrollY;
}
document.addEventListener("mousemove", mouseEvents);
function drawRotated(x, y, angle) {
ctx.setTransform(1, 0, 0, 1, x, y);
ctx.rotate(angle);
ctx.beginPath();
ctx.arc(0, 0, 100, 0, Math.PI * 2);
ctx.moveTo(-100, 0);
ctx.lineTo(100, 0);
ctx.lineTo(60, -80);
ctx.closePath();
ctx.stroke();
}
function update(timer) {
ctx.setTransform(1, 0, 0, 1, 0, 0); // reset transform
ctx.clearRect(0, 0, 300, 300);
var angle = Math.atan2(mouse.y - 150, mouse.x - 150);
drawRotated(150, 150, angle);
requestAnimationFrame(update);
}
requestAnimationFrame(update);
</script>
</body>
</html>
You need to create a mouse move listener, and an animation loop.
In the animation loop get the mouse position and use Math.atan2( to get the direction from the center canvas to the mouse.
Then set the transform with ctx.setTransform to scale and position the designs rotation center, and then use ctx.rotate to rotate the transform to point along the angle computed.
See snippet for more details
const ctx = canvas.getContext("2d");
// create mouse event listener
const mouse = { x: 0, y: 0 };
function mouseEvents(e) {
const bounds = canvas.getBoundingClientRect();
mouse.x = e.pageX - bounds.left - scrollX;
mouse.y = e.pageY - bounds.top - scrollY;
}
document.addEventListener("mousemove", mouseEvents);
// draw design at x,y and rotated by angle
function drawRotated(x, y, angle) {
ctx.setTransform(1, 0, 0, 1, x, y);
ctx.rotate(angle);
ctx.beginPath();
ctx.arc(0, 0, 100, 0, Math.PI * 2);
ctx.moveTo(-100, 0);
ctx.lineTo(100, 0);
ctx.lineTo(60, -80);
ctx.closePath();
ctx.stroke();
}
// render loop called 60 times a second
function update(timer) {
ctx.setTransform(1, 0, 0, 1, 0, 0); // reset transform
ctx.clearRect(0, 0, 300, 300);
// get angle from center to mouse
var angle = Math.atan2(mouse.y - 150, mouse.x - 150);
// draw rotated design
drawRotated(150, 150, angle);
requestAnimationFrame(update);
}
requestAnimationFrame(update);
canvas {
border: 2px solid black;
}
<canvas id="canvas" height=300></canvas>
I'm making my way through JavaScript tutorials (using p5.js) and was interested in coding a responsive screen with four shapes that scale down and stick next to each other while doing so.
Is defining a separate variable for y enough, or would it be better to redefine all the shapes by a new set of x and y variables? Window height/width seems like it should be the correct code to use.
My code:
function setup() {
createCanvas(window.innerWidth, window.innerHeight);
}
function draw() {
background(200);
noStroke();
var labelw = window.innerWidth/8;
var labelh = labelw/4;
var sectionw = window.innerWidth;
var sectionh = window.innerHeight;
// Red
if(window.innerWidth/2 < window.innerHeight){
fill(200, 50, 50);
rect(0, 0, sectionw/2, sectionw/4)
}
// Blue
if(window.innerWidth/2 < window.innerHeight){
fill(50, 50, 200);
rect(sectionw/2, 0, sectionw/2, sectionw/4)
}
// Green
if(window.innerWidth/2 < window.innerHeight){
fill(130, 230, 130);
rect(0, sectionh/2, sectionw/2, sectionw/4)
}
// Purple
if(window.innerWidth/2 < window.innerHeight){
fill(190, 100, 230);
rect(sectionw/2, sectionh/2, sectionw/2, sectionw/4)
}
// label1
fill(50)
rect(0, 0, labelw, labelh)
fill(255);
textSize(labelw/10);
text("Test Label\nTestIdeo, 19xx-20xx",0, 0, 200, 200);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.16/p5.js"></script>
<html>
<head></head>
<body></body>
</html>
You need to do two things:
First, you need to detect when the screen is resized, and resize the canvas when that happens. The windowResized() and resizeCanvas() functions come in handy for that. See the reference for more info.
Second, you just need to use the width and height variables to draw your shapes. The width and height variables are automatically updated when you resize the canvas.
Putting it all together, it would look like this:
function setup() {
createCanvas(windowWidth, windowHeight);
}
function draw() {
fill(255, 0, 0);
rect(0, 0, width/2, height/2);
fill(0, 255, 0);
rect(width/2, 0, width/2, height/2);
fill(0, 0, 255);
rect(0, height/2, width/2, height/2);
fill(255, 255, 0);
rect(width/2, height/2, width/2, height/2);
}
function windowResized() {
resizeCanvas(windowWidth, windowHeight);
}