Oh ok a thought about that but I wasn’t sure
This is my take on this, it took a little bit to figure out the trigonometry behind it but it works fine. This solution involve classes, if you don’t know about them it’s a key feature in the Java laguage to structure your project :
The idea is that by computing the difference between the previous mouse position (pmouseX
and pmouseY
) and the current mouse position, you get the movement of the mouse.
Now it works when the slider doesn’t have an angle but when there’s one, basically we compute the difference in X and Y, multiply them respectively by the cosine and the sine of the rotation of the button and then add them.
It looks like this :
float diff = cos(rotation) * (mouseX - pmouseX) + sin(rotation) * (mouseY - pmouseY);
Now if rotation = 0
then cos(0) = 1
and sin(0) = 0
so only the X location of the mouse is contributing to the movement of the slider. If the angle increase to 45° then it’s going to be half of the difference on each coordinates of the mouse and so on…
This is the full code :
CircleButton button;
void setup() {
size(500, 500);
button = new CircleButton(width/2, height/2, 300, 50);
}
void draw() {
background(255);
button.display();
// Rotate the button
button.rotation += 0.01;
}
// For each of the mouse actions, we delegate it to the button instance
void mousePressed() {
button.mousePressed();
}
void mouseReleased() {
button.mouseReleased();
}
void mouseDragged() {
button.mouseDragged();
}
class Slider {
// The diameter of the slider
int diameter;
// The position of the slider between 0 and 1
float position = 1;
Slider(int diameter) {
this.diameter = diameter;
}
void display() {
stroke(0);
strokeWeight(3);
fill(255, 0, 0);
ellipse(0, 0, diameter, diameter);
}
// Add an offset to the position of the slider
// Constrain it between [0, 1]
void addOffset(float offset) {
this.position = constrain(position + offset, 0, 1);
}
}
class CircleButton {
// The position of the button
int x, y;
// The diamater of the button
int diameter;
// It's rotation in radians
float rotation = 0;
// The slider
Slider slider;
int mouseClickedX, mouseClickedY;
boolean clicked = false;
CircleButton(int x, int y, int diameter, int sliderDiameter) {
this.x = x;
this.y = y;
this.diameter = diameter;
// Create the slider
this.slider = new Slider(sliderDiameter);
}
void display() {
pushMatrix();
// Translate to its location and rotate
translate(x, y);
rotate(rotation);
// Display the circle
stroke(0);
strokeWeight(2);
fill(100);
ellipse(0, 0, diameter, diameter);
// Display the line
stroke(#239BBF);
strokeWeight(20);
line(0, 0, diameter/2 * slider.position, 0);
stroke(20);
line(diameter/2 * slider.position, 0, diameter/2, 0);
// Display the slider
// Translate to it's position
translate(slider.position * diameter / 2, 0);
slider.display();
popMatrix();
// Text for the slider position
stroke(0);
text("Slider position : " + slider.position, 50, 20);
text("Mouse clicked : " + clicked, 50, 40);
text("Rotation : " + floor(degrees(rotation)) + " °", 50, 60);
}
// Return the X slider coordinate
float getSliderX() {
return x + cos(rotation) * slider.position * diameter/2;
}
// Return the Y slider coordinate
float getSliderY() {
return y + sin(rotation) * slider.position * diameter/2;
}
void mousePressed() {
// If the mouse is inside the slider
if (dist(mouseX, mouseY, getSliderX(), getSliderY()) < slider.diameter/2) {
// Set clicked to true
clicked = true;
}
}
void mouseReleased() {
// Set clicked to false
clicked = false;
}
void mouseDragged() {
// If we already clicked
if (clicked) {
// Compute the offset based on the previous mouse position
float diff = cos(rotation) * (mouseX - pmouseX) + sin(rotation) * (mouseY - pmouseY);
// Add the offset to the position of the slider
slider.addOffset(map(diff, 0, diameter/2, 0, 1));
}
}
}
Feel free to ask questions if you need!