#lang syndicate ;; Compare to "ezd" clock-face example from: J. F. Bartlett, “Don’t ;; Fidget with Widgets, Draw!,” Palo Alto, California, DEC WRL ;; Research Report 91/6, May 1991. (require lang/posn) (require 2htdp/image) (require (only-in racket/math pi)) (require racket/date) (require "../2d.rkt") (define hand (polygon (list (make-posn 0 0) (make-posn 30 10) (make-posn 100 0) (make-posn 30 -10)) "solid" "black")) (define (fmod a b) (- a (* b (truncate (/ a b))))) (define (hand-sprite id layer angle-field length) (sprite #:id id layer `((translate 100 100) (rotate ,(fmod (- 90 (angle-field)) 360)) (scale ,length ,(/ length 5)) (translate 0 -0.5) (touchable ,id ,in-unit-square?) (texture ,hand)))) (define (text-sprite layer x y content) (define i (text content 24 "green")) (simple-sprite layer x y (image-width i) (image-height i) i)) (spawn (field [minute-angle 0] [hour-angle 0] [start-time (current-inexact-milliseconds)] [elapsed-seconds 0] [displacement (let ((now (current-date))) (* 6 (+ (* 60 (date-hour now)) (date-minute now))))]) (assert (outbound (simple-sprite 10 0 0 200 200 (circle 100 "solid" "blue")))) (assert (outbound (hand-sprite 'minute 9 minute-angle 95))) (assert (outbound (text-sprite 8 40 40 "time"))) (assert (outbound (text-sprite 8 110 80 "drifts"))) (assert (outbound (text-sprite 8 40 120 "by"))) (assert (outbound (hand-sprite 'hour 7 hour-angle 65))) (assert (outbound (simple-sprite 6 95 95 10 10 (circle 5 "solid" "black")))) (define (respond-to-drags id scale) (define/query-value touching? #f (inbound (touching id)) #t) (on #:when (touching?) (message (inbound (mouse-event 'left-down (mouse-state $mx $my _ _ _)))) (start-time #f) (elapsed-seconds 0) (update-displacement! mx my scale) (react (stop-when (message (inbound (mouse-event 'left-up _)))) (stop-when (message (inbound (mouse-event 'leave _)))) (on-stop (start-time (current-inexact-milliseconds))) (on (message (inbound (mouse-event 'motion (mouse-state $mx $my _ _ _)))) (update-displacement! mx my scale))))) (define (update-displacement! mx my scale) (define angle (- 90 (* (/ 180 pi) (atan (- 100 my) (- mx 100))))) (define delta0 (fmod (- (* scale angle) (displacement)) 360)) (define delta (if (<= delta0 -180) (+ delta0 360) delta0)) (displacement (+ (displacement) delta))) (respond-to-drags 'minute 1) (respond-to-drags 'hour 12) (begin/dataflow (define angle (+ (/ (elapsed-seconds) 1000 10) (displacement))) (minute-angle angle) (hour-angle (/ angle 12))) (on (message (inbound (frame-event _ _ _ _))) (when (start-time) (elapsed-seconds (- (current-inexact-milliseconds) (start-time))))) (on (message (inbound (key-event #\q #t _))) (assert! (outbound 'stop)))) (module+ main (current-ground-dataspace (2d-dataspace #:label "Syndicate Clock" #:width 200 #:height 200)))