Sliders are one of those those things that are deceptively finickey. This is a p5.js script for making a simple slider object. The sliders above were made with the code below. At the bottom is the same code for Processing.
Features:
x, y, length of slider, start value, end value, step value, float or int, sticky true or false, show values true or false
Features:
- Easily change the high and low values.
- Easily change the size and location of the slider.
- Fancy rollover knob color!
- You can make the slider snap to a line or not
- Return an int or float variable
x, y, length of slider, start value, end value, step value, float or int, sticky true or false, show values true or false
What follows is the code for the sliders seen above. It is p5.js.
var MP;
var slider, slider2;
function setup() {
createCanvas(600, 200);
smooth();
// x, y, length of slider, start value, end value, step value, float?, sticky, show all values
slider = new SliderClass(20, 40, 300, 0, 2000, 100, false, false, false);
slider2 = new SliderClass(20, 120, 300, 0, 5, 0.5, true, true, true);
rectMode(CENTER);
textAlign(CENTER);
}
function draw() {
background(255);
slider.move();
slider.display();
slider2.move();
slider2.display();
}
function mousePressed() {
MP = true;
}
function mouseReleased() {
MP = false;
}
function SliderClass(_x, _y, _length, _startValue, _endValue, _varerval, _vars, _sticky, _showValues) {
this.clicked = false;
this.sticky = false;
this.knobWidth = 12;
this.knobHeight = 20;
this.sliderValue = 0.00;
this.sliderValueInt = 0;
this.fade = 255; // for knob color
this.xDif = 0.0;
this.screenInterval = 0;
this.x = _x;
this.y = _y;
this.xEnd = this.x + _length;
this.xStart = this.x;
this.startValue = _startValue;
this.endValue = _endValue;
this.vars = _vars;
this.varerval = _varerval;
this.totalLength = _length;
this.sticky = _sticky;
this.showValues = _showValues;
this.move = function() {
// check to see if it's clicked
if (dist(mouseX, mouseY, this.x, this.y) < this.knobWidth) { // use this if you want a round knob on the slider
if (MP && this.clicked == false) { // if mouse was pressed
this.xDif = mouseX - this.x;
this.clicked = true;
}
this.fade = 100; // mouseOver but not clicked
} else {
this.fade = 0;
}
if (this.clicked == true) {
this.fade = 255;
}
if (MP == false && this.clicked == true) { // if the mouse was just released
this.clicked = false;
if (this.sticky) { // if you set it to jump to the closest line
var modDif = this.sliderValue % this.varerval; // value to show how close it is to last line
var div = int(this.sliderValue / this.varerval); // vlaue to show how MANY varervals it's passed
if (modDif < this.varerval / 2) { // so it goes to closest line not just lower
this.x = this.xStart + (div * this.screenInterval);
} else {
this.x = this.xStart + ((div + 1) * this.screenInterval);
}
}
}
if (this.clicked) {
this.x = mouseX - this.xDif; // so the slider doens't "jump" to the mouse x.
this.x = constrain(this.x, this.xStart, this.xEnd); // keep the knob on the slider
}
this.sliderValue = map(this.x, this.xStart, this.xEnd, this.startValue, this.endValue); // get the slider position relative to the values
this.sliderValueInt = int(this.sliderValue); // make that number an var
}
this.display = function() {
stroke(1);
this.screenInterval = map(this.varerval, 0, this.endValue - this.startValue, 0, this.totalLength); // get the createCanvas of the gaps for the screen relative to the varervals
var counter = 0;
for (var i = int(this.screenInterval); i < this.totalLength; i += this.screenInterval) { // go from the first gap to the end of slider by the screenInterval
line(i + this.xStart, this.y + 12, i + this.xStart, this.y - 12); // draw lines
if(this.showValues){
counter ++;
text( nfc(counter * this.varerval,1,1), i + this.xStart, this.y + 30);
}
}
line(this.xStart, this.y + 12, this.xStart, this.y - 12); // draw first line (optional)
line(this.xEnd, this.y + 12, this.xEnd, this.y - 12); // draw last line (optional)
line(this.xStart, this.y, this.xEnd, this.y); // draw center line
fill(255);
rect(this.x, this.y, this.knobWidth, this.knobHeight); // so it's opaque
fill(100, 120, 160, this.fade);
rect(this.x, this.y, this.knobWidth, this.knobHeight); // add color
fill(1);
if (this.vars) {
text( nfc(this.sliderValue,1,1), this.x, this.y - 20);
} else {
text(this.sliderValueInt, this.x, this.y - 20);
}
text(int (this.startValue), this.xStart, this.y + 30);
text(int (this.endValue), this.xEnd, this.y + 30);
}
}
What follows is the code for the sliders using Processing. (I would put the class in it's own tab, but it's here as one long file for ease in copy/pasting)
boolean MP;
SliderClass slider;
void setup() {
size(600, 400);
smooth();
// x, y, length of slider, start value, end value, step value, int or float, sticky
slider = new SliderClass(20, 40, 300, 0, 200, 20, false, true);
rectMode(CENTER);
textAlign(CENTER);
}
void draw() {
background(255);
slider.move();
slider.display();
}
void mousePressed() {
MP = true;
}
void mouseReleased() {
MP = false;
}
/*
Needs a global boolean called MP and two scripts to catch the mousepress and release.
void mousePressed() {
MP = true;
}
void mouseReleased() {
MP = false;
}
*/
class SliderClass {
float x, y, xEnd, xStart, xDif;
float sliderValue, startValue, endValue, interval, totalLength, screenInterval;
color sliderColor = color(100, 120, 160, 255);
int knobWidth = 12;
int knobHeight = 20;
float fade = 255; // for knob color
boolean clicked, floats, sticky;
int sliderValueInt;
// x, y, length of slider, start value, end value, step value, int or float, sticky
SliderClass(float _x, float _y, int _length, int _startValue, int _endValue, int _interval, boolean _floats, boolean _sticky) {
x = _x;
y = _y;
xEnd = x + _length;
xStart = x;
startValue = _startValue;
endValue = _endValue;
floats = _floats;
interval = _interval;
totalLength = _length;
sticky = _sticky;
}
void move() {
// check to see if it's clicked
if (dist(mouseX, mouseY, x, y) < knobWidth) { // use this if you want a round knob on the slider
//if (mouseX > x - (knobWidth/2) && mouseX < x + knobWidth/2
// && mouseY > y - (knobHeight/2) && mouseY < y + knobHeight /2) {
if (MP && clicked == false) { // if mouse was pressed
xDif = mouseX - x;
clicked = true;
}
fade = 100; // mouseOver but not clicked
} else {
fade = 0;
}
if (clicked == true) {
fade = 255;
}
if (MP == false && clicked == true) { // if the mouse was just released
clicked = false;
if (sticky) { // if you set it to jump to the closest line
float modDif = sliderValue % interval; // value to show how close it is to last line
int div = int(sliderValue/interval); // vlaue to show how MANY intervals it's passed
if (modDif < interval/2) { // so it goes to closest line not just lower
x = xStart + (div * screenInterval);
} else {
x = xStart + ((div + 1) * screenInterval);
}
}
}
if (clicked) {
x = mouseX - xDif; // so the slider doens't "jump" to the mouse x.
x = constrain(x, xStart, xEnd); // keep the knob on the slider
}
sliderValue = map(x, xStart, xEnd, startValue, endValue); // get the slider position relative to the values
sliderValueInt = int(sliderValue); // make that number an int
}
void display() {
stroke(1);
screenInterval = map(interval, 0, endValue - startValue, 0, totalLength); // get the size of the gaps for the screen relative to the intervals
for (int i = int(screenInterval); i < totalLength; i += screenInterval) { // go from the first gap to the end of slider by the screenInterval
line(i + xStart, y+12, i + xStart, y-12); // draw lines
}
line(xStart, y+12, xStart, y-12); // draw first line (optional)
line(xEnd, y+12, xEnd, y-12); // draw last line (optional)
line(xStart, y, xEnd, y); // draw center line
sliderColor = color(red(sliderColor), green(sliderColor), blue(sliderColor), fade);
fill(255);
//ellipse (x, y, knobWidth, knobWidth);
rect(x, y, knobWidth, knobHeight); // so it's opaque
fill(sliderColor);
//ellipse (x, y, knobWidth, knobWidth);
rect(x, y, knobWidth, knobHeight); // add color
fill(1);
if (floats) {
text(sliderValue, x, y+30);
} else {
text(sliderValueInt, x, y+30);
}
text(int(startValue), xStart, y+30);
text(int(endValue), xEnd, y+30);
}
}