cdglabs / apparatus

A hybrid graphics editor and programming environment for creating interactive diagrams.
http://aprt.us/
MIT License
1.04k stars 59 forks source link

How do I constrain variables? #12

Open jaredly opened 9 years ago

jaredly commented 9 years ago

In the slider example, I'd like to constrain the value of the value variable to between, for example, 0 and 1. I can't figure out how to do it :( I tried making the x coord of the handle be max(0, min(1, value)), but then the handle is just unresponsive.

Really awesome project! Thanks for sharing.

electronicwhisper commented 9 years ago

Yes, there is currently no way to do it. It is a very necessary feature, e.g. for making sliders that you can't drag off their track!

Luckily, the architecture will support it nicely. There are already "constraints" in the form of precision constraints. When you adjust a value (either by scrubbing or dragging geometry), attributes always keep their precision (digits after the decimal point). This is accomplished here in the code, https://github.com/cdglabs/apparatus/blob/master/src/View/Canvas.coffee#L326-L335

So at this point if you were to also constrain the value between bounds (with max and min) you'd get nicely working constraints. Even more powerful, maybe you would write your own function for how the attribute should be constrained. That is, write a custom function from a solvedValue to a writtenValue. For example to implement bounds,

function (solvedValue) {
  return max(0, min(1, solvedValue));
}

(Are there other compelling examples where you'd want to write your own function? Bounds seems like the 90% use case...)

The missing piece is the UI for specifying that you want a attribute to be constrained and the bounds to constrain it to or the function to use as the constrainer. Maybe there is a disclosure triangle that shows you additional information about an attribute, including this option. This area could also be used to reset an attribute as in #7.

Anyhow, that is the design I currently imagine, but I'd be happy to hear other ideas or look at mockups.

Thanks for reporting @jaredly, glad you like the project!

mgold commented 9 years ago

One solution is to place clamp(min, val, max) in scope, implemented with min and max as you suggest.