Last active
June 21, 2018 01:51
-
-
Save Morpholux/1da21f553391deff56411423800fed57 to your computer and use it in GitHub Desktop.
Rectangle scaling interface
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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