An Introduction To Programming With Processing

Setting up regional constraints

Slider Overshoot
As we have seen from previous examples the constrain() function can be used to setup a maximum and minimum value that can be used to determine the limits of another value. This provides a convenient solution for working with the buttonXPos value of which we'd like it's minimum value mapped to the left edge of the sliderBd object and it's maximum value mapped to the right edge of the sliderBd object minus the width of the slider button (sliderFd). We need to minus the width of the slider button (sliderFd) because the top left hand corner of the slider button image is the point that will be able to move to the maximum value specified in the constrain() function, as a result of using the default setting for imageMode() which is CORNER. If this point was matched to the right edge of sliderBd the results would look like the following image:
As you can see the slider button has gone too far past the right edge of the sliderBd image, subtracting the sliderFd's width from the right edge of sliderBd will solve this. Modify the if() statement to include the following else clause:
else{
    buttonXPos = constrain(buttonXPos, width/2 -  sliderBk.width/2, width/2 + sliderBk.width/2 - sliderFd.width);
  }
The minimum value for the constrain() function is the center of the Display Window minus half of the width of the slider background image (sliderBd). The maximum value for the constrain function is the center of the Display Window plus half of the width of the slider background image (sliderBd) minus sliderFd's width.
Slider Markers
With this information in mind finishing the if() structure is just a matter of copy and paste with one minor modification. Although the modification is minor it's addition to the sketch will be what finally gives the user the results they were looking for. The value we are constraining in this case is going to be mouseX. The following if() statement demonstrates this:
if(buttonDrag){
    buttonXPos = constrain(mouseX - sliderFd.width/2, width/2 -  sliderBk.width/2, width/2 + sliderBk.width/2 -  sliderFd.width);
  }else{
    buttonXPos = constrain(buttonXPos, width/2 - sliderBk.width/2, width/2 + sliderBk.width/2 - sliderFd.width);
  } 

Finishing the slider

The third issue with the slider is to get it to stop dragging once the mouse has been released. For this we're going to use the mouseReleased() function. The mouseReleased() function should be placed directly below the mouseDragged() function for the purpose of readability. However to Processing it does not make a difference if the function is before or after mouseDragged(). The mouseReleased() function is pretty simple, all it does is run the function once every time the mouse button is released in the Display Window. In our case the function will check if buttonDrag is set to true, if it is then we can be sure that the slider button is being dragged. As the function is run when the mouse has been released, we can be certain that the user no longer wants to drag the button, as a result the function then sets the buttonDrag variable back to false. This means that the conditional using this variable in the draw() structure will evaluate to false, so that mouseX will no longer be used to determine the value of buttonXPos. The mouseReleased() function should look like the following code listing:

void mouseReleased(){
  if(buttonDrag){
    buttonDrag = false;
  }
}