7
$\begingroup$

My goal is to make an iOS-like enable/disable switch like this:

iOS sliders

I use a LocatorPane for the slider with so-called "jumps" to only make two settings possible:

LocatorPane[Dynamic[pt], Graphics[{LightGray, Rectangle[{-.5, -.5}, {1.5, .5}]}],
            {{0, 0}, {1, 0}, {1, 1}},
            Appearance -> ImageResize[Graphics[{Gray, Disk[]},
                                               Background -> None], Scaled[.25]]]

Now, I want make the 'slider' better looking by adding a gradient to it but i cannot make it work. ColorFunction (probably the only way to add gradients in Mathematica) seems not available to Disk. I tried using Heike's solution for gradients in this question, but pasting the graphics from her function into my code does not work: the size of these graphics is way too large and rescaling it (using ImageResize) adds a white background which I cannot remove. I tried making a disk with a gradient myself using Raster and ImageAdd, but here the same problem of a none-removable background occurs again:

ImageAdd[
Graphics[Raster[Table[i, {i, 100}, {j, 200}],
         {Scaled[{0, 0}], Scaled[{1, 1}]}, {1, 100}, ColorFunction -> "GrayTones"]],
Graphics[Disk[]]]

Can anyone give some tips about how to add gradients to disks?

$\endgroup$
3
  • $\begingroup$ Hmmm... possibly a duplicate of mathematica.stackexchange.com/q/7657/5. Silvia's answer is probably what you're looking for. In short, generate the gradient using any of the plotting functions, set an alpha channel and clip it to a disk region and texturize a polygon with that. $\endgroup$
    – rm -rf
    Nov 7, 2012 at 22:40
  • $\begingroup$ Texture was an option i did not think of, clever! For this purpose the answer for cormullion does the trick. $\endgroup$ Nov 8, 2012 at 14:52
  • $\begingroup$ @J.M. Thanks for the edit. Had a hard time formatting the code in a nice way... $\endgroup$ Nov 8, 2012 at 14:53

2 Answers 2

5
$\begingroup$

Seems a bit clumsy, but how about this:

shiny[z_] := GrayLevel[1 - z/4];

gradient = 
  Image[DensityPlot[y^2, {x, -2, 2}, {y, -2, 2}, 
    PlotRangePadding -> 0, Frame -> None, ColorFunction -> shiny, 
    ColorFunctionScaling -> True]];
diskAlpha = 
  Image[Graphics[Disk[], Background -> None], 
   ImageSize -> ImageDimensions[gradient]];
d = SetAlphaChannel[gradient, AlphaChannel[diskAlpha]];

LocatorPane[Dynamic[pt],
 Graphics[{
   Blue, 
   Rectangle[{-.25, -.25}, {1.25, .25}, RoundingRadius -> 0.25],
   White,
   Style[Text["ON", {0.25, 0}], 64, Bold, 
    FontFamily -> "Helvetica"]}], 
 {{0, 0}, {1, 0}, {1, 1}},
 Appearance -> ImageResize[d, Scaled[.3]]]

attempt

$\endgroup$
5
  • $\begingroup$ nice! but its missing the shadow :-) $\endgroup$
    – chris
    Nov 8, 2012 at 8:46
  • $\begingroup$ @chris :) and the highlight round the edge, and the black rim, and the shiny reflection, and the text shadow, and many other things besides...! I went to bed instead. $\endgroup$
    – cormullion
    Nov 8, 2012 at 9:10
  • 1
    $\begingroup$ very smart indeed. I should learn that trick from you. $\endgroup$
    – chris
    Nov 8, 2012 at 9:10
  • $\begingroup$ Thanks a lot cormullion! This really is what i was looking for. I'll post my switch as soon as i'm completely finished. $\endgroup$ Nov 8, 2012 at 14:54
  • $\begingroup$ Cool. So, are you porting Mathematica to the iPhone‽ :) $\endgroup$
    – cormullion
    Nov 8, 2012 at 15:16
4
$\begingroup$

Well, this is the switcher I made using the answer from cormullion. Just one thing: it sort of works, but not quite yet... After defining the function SwitcheriOS twice in one session I get a Set::setraw which I cannot repair. I am unable to figure out what is wrong...

But apart from this 'minor' issue it works like a charm!

The code:

SwitcheriOS[var_] := Module[{gradient, coord, img, rastimg},
shiny[z_] := GrayLevel[1 - z/4]; 
gradient = 
 Image[DensityPlot[y^2, {x, -.75, .75}, {y, -.25, 25}, 
   PlotRangePadding -> 0, Frame -> None, ColorFunction -> shiny, 
   ColorFunctionScaling -> True]];
coord = 
 Block[{n = 100}, 
  Table[{Cos[2 \[Pi] k/n], Sin[2 \[Pi] k/n]}, {k, 0, n - 1}]];
img = Graphics[{Texture@gradient, EdgeForm@None, 
 Polygon[coord, VertexTextureCoordinates -> (coord/2 + .5)], 
  LightGray, Thickness[.05], Circle[]}, ImageSize -> 28, 
  Background -> None];
rastimg = Rasterize[img, RasterSize -> 100, Background -> None];
LocatorPane[Dynamic[var], 
 Graphics[{Dynamic[
    Which[var[[1]] == -.75, Lighter[Gray, .8], var[[1]] == .75, 
     Lighter[Blue, .3]]], 
   Rectangle[{-1.25, -.5}, {1.25, .5}, RoundingRadius -> .5], 
   Dynamic[Which[var[[1]] == -.75, Opacity[.6, White], 
     var[[1]] == .75, Opacity[.2, White]]], 
   Rectangle[{-1, -.5}, {1, 0}, RoundingRadius -> .25], 
   Opacity[.9, White], 
   Dynamic[Text[
     Style[Which[var[[1]] == -.75, "OFF", var[[1]] == .75, "ON"], 
      Which[var[[1]] == -.75, Gray, var[[1]] == .75, White], 13, 
      FontFamily -> "DejaVu Sans", Bold], 
     Which[var[[1]] == -.75, {.5, 0}, var[[1]] == .75, {-.5, 0}]]], 
   EdgeForm[{Lighter[Gray, .3], Thickness[.025]}], Transparent, 
   Rectangle[{-1.25, -.5}, {1.25, .5}, RoundingRadius -> .5]}, 
  ImageSize -> 75], {{-.75, -0}, {.75, -0}, {1.5, 1}}, 
 Appearance -> rastimg]]

enter image description here

$\endgroup$
3
  • $\begingroup$ I could not reproduce the issue you mentioned of. $\endgroup$ Nov 8, 2012 at 17:49
  • $\begingroup$ @PlatoManiac: Thanks for the added image. I can reproduce the error by calling SwitcheriOS with an already defined variable. $\endgroup$ Nov 8, 2012 at 18:48
  • $\begingroup$ You are welcome! Try to change the borders with some shadow and then you are done 100%. $\endgroup$ Nov 8, 2012 at 18:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.