-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathex1.cljs
105 lines (91 loc) · 3.83 KB
/
ex1.cljs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
(ns dots-game.ex1
(:require
[cljs.core.async :as async
:refer [<! >! chan close! sliding-buffer put! alts! timeout]]
[jayq.core :refer [$ append ajax html css $deferred
done resolve pipe on bind attr
offset] :as jq]
[jayq.util :refer [log]]
[crate.core :as crate]
[goog.object :as gobj])
(:require-macros [cljs.core.async.macros :as m :refer [go]]))
(enable-console-print!)
(defn is-bad-ie? []
(let [browser (gobj/get js/$ "browser")]
(and (gobj/get browser "msie")
(> 10 (gobj/get browser "version")))))
(defn xy-message [ch msg-name xy-obj]
(put! ch [msg-name {:x (gobj/get xy-obj "pageX")
:y (gobj/get xy-obj "pageY")}]))
(defn touch-xy-message [ch msg-name xy-obj]
(xy-message ch msg-name
(-> xy-obj
(gobj/get "originalEvent")
(gobj/get "touches")
(aget 0))))
(defn mousemove-handler [in-chan jqevent]
(if (pos? (if (nil? (gobj/get jqevent "buttons"))
(gobj/get jqevent "which")
(gobj/get jqevent "buttons")))
(xy-message in-chan :draw jqevent)
(put! in-chan [:drawend])))
(defn nice-mouse-event-capture [in-chan selector end-handler]
(bind ($ selector) "mousemove" #(mousemove-handler in-chan %))
(bind ($ selector) "mousedown" #(xy-message in-chan :draw %))
(bind ($ selector) "mouseup" end-handler))
(defn ie-mouse-event-capture [in-chan selector end-handler]
(bind ($ selector) "mousemove" #(xy-message in-chan :draw %))
(bind ($ "body") "mousedown" #(xy-message in-chan :drawstart %))
(bind ($ "body") "mouseup" end-handler))
(defn draw-event-capture [in-chan selector]
(let [end-handler (fn [_] (put! in-chan [:drawend]))]
(if (is-bad-ie?)
(ie-mouse-event-capture in-chan selector end-handler)
(nice-mouse-event-capture in-chan selector end-handler))
(bind ($ selector) "touchmove" #(touch-xy-message in-chan :draw %))
(bind ($ selector) "touchend" end-handler)))
(defn get-drawing [input-chan out-chan]
(go (loop [msg (<! input-chan)]
(put! out-chan msg)
(when (= (first msg) :draw)
(recur (<! input-chan))))))
(defn draw-chan [selector]
(let [input-chan (chan)
out-chan (chan)
start-message (if (is-bad-ie?) :drawstart :draw)]
(draw-event-capture input-chan selector)
(go (loop [[msg-name msg-data :as msg] (<! input-chan)]
(when (= msg-name start-message)
(put! out-chan [:draw msg-data])
(<! (get-drawing input-chan out-chan)))
(recur (<! input-chan))))
out-chan))
(defn draw-point [selector color coord {:keys [top left]}]
(append ($ selector)
(crate/html [:div {:class (str "point " (name color))
:style (str "top: " (- (coord :y) top 5) "px;"
"left: " (- (coord :x) left 5) "px;")}])))
(defn draw-points [selector drawing-chan color]
(let [offset (offset ($ selector))
width (+ (.width ($ selector)) (offset :left))
height (+ (.height ($ selector)) (offset :top))
in-range #(and (< (offset :top) (% :y) height)
(< (offset :left) (% :x) width))]
(go
(loop [[msg-name xy-obj] (<! drawing-chan)]
(when (= msg-name :draw)
(if (in-range xy-obj)
(draw-point selector color xy-obj offset))
(recur (<! drawing-chan)))))))
(defn drawing-loop [selector]
(let [drawing-chan (draw-chan selector)]
(go
(loop [[msg-name msg-data] (<! drawing-chan)
color-i 0]
(if (= :draw msg-name)
(<! (draw-points selector
drawing-chan
(get [:red :green :blue] (mod color-i 3)))))
(recur (<! drawing-chan) (inc color-i))))))
(defn example-1 [selector]
(drawing-loop selector))