import javafx.ui.*; import javafx.ui.canvas.*; import java.util.Date; import java.lang.Math; /** Fxclock - based on the Clock.fx by Augusto Sellhorn http://sellmic.com SVG (?) hands with shading Carsten Saager http://saager.org */ public class Timer { private attribute elapsed: Number; public attribute minutes: Number; public attribute seconds: Number; public attribute hours: Number; public attribute running: Boolean; } attribute Timer.elapsed = bind if running then [1..60] dur 60000 linear while running continue if true else 0; trigger on Timer.elapsed = value { var now = new Date(); minutes = now.getMinutes(); seconds = now.getSeconds() + [.35,0.34 .. 0.0] dur 350 + (now.getTime() % 1000)/1000; hours = now.getHours(); } public class Clock extends CompositeNode { public attribute ticking: Boolean; } operation Clock.composeNode() { var t = Timer {running: bind ticking}; return Group { transform: [translate(5,5),scale(1,1)] var secs = bind t.seconds var mins = bind t.minutes + secs/60 var hrs = bind t.hours + mins/60 var shade = bind Math.sin((secs+7)/60*2*Math.PI)*40 var mshade = bind Math.sin((mins+7)/60*2*Math.PI)*30+20 var hshade = bind Math.sin((hrs+1.5)/24*2*Math.PI)*30+20 content: [ Rect { height: 200 width: 200 fill: white }, ImageView { transform: [] image: Image {url: "http://sellmic.com/lab/dev/jfx/clock/images/clock_face.png"} }, Group { var hourHand =Group {transform: bind rotate(hrs*30,255,245) content :[ Path { fill:bind new Color(200-hshade, 200-hshade, 200-hshade, 0xff) d:[ MoveTo {x: 254, y: 270}, LineTo {x: 265, y: 270}, LineTo {x: 256, y: 100}, LineTo {x: 254, y: 100}, ClosePath {} ] }, Path { fill:bind new Color(200+hshade, 200+hshade,200+hshade, 0xff) d:[ MoveTo {x: 245, y: 270}, LineTo {x: 255, y: 270}, LineTo {x: 255, y: 100}, LineTo {x: 253, y: 100}, ClosePath {} ] }] } var minuteHand = Group {transform: bind rotate(mins * 6,255,245) content :[ Path { fill:bind new Color(200-mshade, 200-mshade, 200-mshade, 0xff) d:[ MoveTo {x: 254, y: 290}, LineTo {x: 262, y: 290}, LineTo {x: 255, y: 85}, LineTo {x: 254, y: 85}, ClosePath {} ] }, Path { fill:bind new Color(200+mshade, 200+mshade,200+mshade, 0xff) d:[ MoveTo {x: 248, y: 290}, LineTo {x: 255, y: 290}, LineTo {x: 255, y: 85}, LineTo {x: 253, y: 85}, ClosePath {} ] }] } var secondHand = Group {transform: bind rotate(t.seconds * 6,255,245) content :[ Path { fill:bind new Color(120-shade, 20, 0x08, 0xff) d:[ MoveTo {x: 254, y: 300}, LineTo {x: 260, y: 300}, LineTo {x: 254, y: 50}, ClosePath {} ] }, Path { fill:bind new Color(120+shade, 20, 0x08, 0xff) d:[ MoveTo {x: 250, y: 300}, LineTo {x: 255, y: 300}, LineTo {x: 255, y: 50}, ClosePath {} ] }] } content: [hourHand, minuteHand, secondHand] }, ImageView { transform: translate(1,-2) image: Image {url: "http://sellmic.com/lab/dev/jfx/clock/images/pin.png"} }] }; } Clock {ticking: true}