Skip to content

Instantly share code, notes, and snippets.

@Morpholux
Last active June 21, 2018 01:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Morpholux/1da21f553391deff56411423800fed57 to your computer and use it in GitHub Desktop.
Save Morpholux/1da21f553391deff56411423800fed57 to your computer and use it in GitHub Desktop.
Rectangle scaling interface
// renaud.jean-francois(arobas)uqam(point)ca
// Syntaxe Processing version 3.3.7
// mardi, 19 juin 2018
// Rectangle scaling interface :
// Click and drag a pseudo cursor from any corners to change size accordingly.
// There is also a corner snap effect for the pseudo cursor,
// and some limitations (min-max) for the expanding or the contract size.
// Set variables to your needs
float size = 200, newSize = size;
float sizeMin = size * 0.25, sizeMax = size * 2.5;
float tresholdDist = 20;
int sizeCursor = 12;
// Other global variables
float scale;
int startX, startY, currentX, currentY;
int centerSqX, centerSqY;
float diagTranslate;
int cornerId = -1;
void setup() {
size(600, 600);
background(0);
fill(255);
noStroke();
rectMode(CENTER);
noCursor();
centerSqX = width/2;
centerSqY = height/2;
}
void draw() {
background(0);
// Square:
rect(centerSqX, centerSqX, newSize, newSize);
// Pseudo cursor:
pushStyle();
fill(255, 0, 0);
noStroke();
// Snapping effect for pseudo cursor
if (cornerId >= 0) {
// Force position of pseudo cursor to be relative to one corner, if one is picked
switch (cornerId) {
case 0:
ellipse(centerSqX+(newSize*0.5), centerSqY+(newSize*0.5), sizeCursor, sizeCursor);
break;
case 1:
ellipse(centerSqX-(newSize*0.5), centerSqY+(newSize*0.5), sizeCursor, sizeCursor);
break;
case 2:
ellipse(centerSqX-(newSize*0.5), centerSqY-(newSize*0.5), sizeCursor, sizeCursor);
break;
case 3:
ellipse(centerSqX+(newSize*0.5), centerSqY-(newSize*0.5), sizeCursor, sizeCursor);
break;
}
} else {
// Snap to corner when mouse is not pressed and simply move around
if (dist(mouseX, mouseY, centerSqX+(newSize*0.5), centerSqY+(newSize*0.5))<tresholdDist) { // Near bottom right corner
ellipse(centerSqX+(newSize*0.5), centerSqY+(newSize*0.5), sizeCursor, sizeCursor);
} else if (dist(mouseX, mouseY, centerSqX-(newSize*0.5), centerSqY+(newSize*0.5))<tresholdDist) { // Near bottom left corner
ellipse(centerSqX-(newSize*0.5), centerSqY+(newSize*0.5), sizeCursor, sizeCursor);
} else if (dist(mouseX, mouseY, centerSqX-(newSize*0.5), centerSqY-(newSize*0.5))<tresholdDist) { // Near up left corner
ellipse(centerSqX-(newSize*0.5), centerSqY-(newSize*0.5), sizeCursor, sizeCursor);
} else if (dist(mouseX, mouseY, centerSqX+(newSize*0.5), centerSqY-(newSize*0.5))<tresholdDist) { // Near up right corner
ellipse(centerSqX+(newSize*0.5), centerSqY-(newSize*0.5), sizeCursor, sizeCursor);
} else {
ellipse(mouseX, mouseY, sizeCursor, sizeCursor); // Anywhere else in the sketch
}
}
popStyle();
}
void mousePressed() {
startX = mouseX;
startY = mouseY;
// Guess if we click near any corner,
// using the same distance filter as snapping method.
// mousePressed is applied during one frame only, and corner id will be kept until mouseReleased.
if (dist(mouseX, mouseY, centerSqX+(newSize*0.5), centerSqY+(newSize*0.5))<tresholdDist) { // Near bottom right corner
cornerId = 0;
} else if (dist(mouseX, mouseY, centerSqX-(newSize*0.5), centerSqY+(newSize*0.5))<tresholdDist) { // Near bottom left corner
cornerId = 1;
} else if (dist(mouseX, mouseY, centerSqX-(newSize*0.5), centerSqY-(newSize*0.5))<tresholdDist) { // Near up left corner
cornerId = 2;
} else if (dist(mouseX, mouseY, centerSqX+(newSize*0.5), centerSqY-(newSize*0.5))<tresholdDist) { // Near up right corner
cornerId = 3;
}
//println(cornerId);
}
void mouseDragged() {
currentX = mouseX;
currentY = mouseY;
// Formula that will make the diagonal translation proportionnal
// to the combine translations of x and y, whatever the directions.
//diagTranslate = cos(radians(45))*(currentX-startX)+sin(radians(45))*(currentY-startY);
// Position of mousePressed relative to quadrant of square
if ((startX > centerSqX)&&(startY > centerSqY)) { // quadrant inférieur droit
currentX = constrain(currentX, centerSqX, width);
currentY = constrain(currentY, centerSqY, height);
diagTranslate = cos(radians(45))*(currentX-startX)+sin(radians(45))*(currentY-startY);
} else if ((startX < centerSqX)&&(startY > centerSqY)) { // quadrant inférieur gauche
currentX = constrain(currentX, 0, centerSqX);
currentY = constrain(currentY, centerSqY, height);
diagTranslate = -cos(radians(45))*(currentX-startX)+sin(radians(45))*(currentY-startY);
} else if ((startX < centerSqX)&&(startY < centerSqY)) {// quadrant supérieur gauche
currentX = constrain(currentX, 0, centerSqX);
currentY = constrain(currentY, 0, centerSqY);
diagTranslate = -cos(radians(45))*(currentX-startX)-sin(radians(45))*(currentY-startY);
} else if ((startX > centerSqX)&&(startY < centerSqY)) {// quadrant supérieur droit
currentX = constrain(currentX, centerSqX, width);
currentY = constrain(currentY, 0, centerSqY);
diagTranslate = cos(radians(45))*(currentX-startX)-sin(radians(45))*(currentY-startY);
}
// Second part of formula, to calculate the appropriate scaling factor
scale = 1+(diagTranslate/((size*0.5)*sqrt(2)));
//println(scale);
// Scale affect new size, by a factor relative to original size
newSize = size*scale;
newSize = constrain(newSize, sizeMin, sizeMax);
}
void mouseReleased() {
// update de size value with new one
size = newSize;
// reset cornerId to none
cornerId = -1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment