Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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?

share|improve this question
    
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. –  rm -rf Nov 7 '12 at 22:40
    
Texture was an option i did not think of, clever! For this purpose the answer for cormullion does the trick. –  A. Goossens Nov 8 '12 at 14:52
    
@J.M. Thanks for the edit. Had a hard time formatting the code in a nice way... –  A. Goossens Nov 8 '12 at 14:53
add comment

2 Answers 2

up vote 4 down vote accepted

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

share|improve this answer
    
nice! but its missing the shadow :-) –  chris Nov 8 '12 at 8:46
    
@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. –  cormullion Nov 8 '12 at 9:10
1  
very smart indeed. I should learn that trick from you. –  chris Nov 8 '12 at 9:10
    
Thanks a lot cormullion! This really is what i was looking for. I'll post my switch as soon as i'm completely finished. –  A. Goossens Nov 8 '12 at 14:54
    
Cool. So, are you porting Mathematica to the iPhone‽ :) –  cormullion Nov 8 '12 at 15:16
add comment

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

share|improve this answer
    
I could not reproduce the issue you mentioned of. –  PlatoManiac Nov 8 '12 at 17:49
    
@PlatoManiac: Thanks for the added image. I can reproduce the error by calling SwitcheriOS with an already defined variable. –  A. Goossens Nov 8 '12 at 18:48
    
You are welcome! Try to change the borders with some shadow and then you are done 100%. –  PlatoManiac Nov 8 '12 at 18:52
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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