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); } }