Commit | Line | Data |
---|---|---|
fa726f85 CE |
1 | (function (Raphael) { |
2 | Raphael.colorwheel = function (x, y, size, initcolor, element) { | |
3 | return new ColorWheel(x, y, size, initcolor, element); | |
4 | }; | |
5 | var pi = Math.PI, | |
6 | doc = document, | |
7 | win = window, | |
8 | ColorWheel = function (x, y, size, initcolor, element) { | |
9 | size = size || 200; | |
10 | var w3 = 3 * size / 200, | |
11 | w1 = size / 200, | |
12 | fi = 1.6180339887, | |
13 | segments = pi * size / 5, | |
14 | size20 = size / 20, | |
15 | size2 = size / 2, | |
16 | padding = 2 * size / 200, | |
17 | t = this; | |
18 | ||
19 | var H = 1, S = 1, B = 1, s = size - (size20 * 4); | |
20 | var r = element ? Raphael(element, size, size) : Raphael(x, y, size, size), | |
21 | xy = s / 6 + size20 * 2 + padding, | |
22 | wh = s * 2 / 3 - padding * 2; | |
23 | w1 < 1 && (w1 = 1); | |
24 | w3 < 1 && (w3 = 1); | |
25 | ||
26 | ||
27 | // ring drawing | |
28 | var a = pi / 2 - pi * 2 / segments * 1.3, | |
29 | R = size2 - padding, | |
30 | R2 = size2 - padding - size20 * 2, | |
31 | path = ["M", size2, padding, "A", R, R, 0, 0, 1, R * Math.cos(a) + R + padding, R - R * Math.sin(a) + padding, "L", R2 * Math.cos(a) + R + padding, R - R2 * Math.sin(a) + padding, "A", R2, R2, 0, 0, 0, size2, padding + size20 * 2, "z"].join(); | |
32 | for (var i = 0; i < segments; i++) { | |
33 | r.path(path).attr({ | |
34 | stroke: "none", | |
35 | fill: "hsb(" + i * (255 / segments) / 255 + ", 1, 0.78)", | |
36 | transform: "r" + [(360 / segments) * i, size2, size2] | |
37 | }); | |
38 | } | |
39 | r.path(["M", size2, padding, "A", R, R, 0, 1, 1, size2 - 1, padding, "l1,0", "M", size2, padding + size20 * 2, "A", R2, R2, 0, 1, 1, size2 - 1, padding + size20 * 2, "l1,0"]).attr({ | |
40 | "stroke-width": w3, | |
41 | stroke: "#fff" | |
42 | }); | |
43 | t.cursorhsb = r.set(); | |
44 | var h = size20 * 2 + 2; | |
45 | t.cursorhsb.push(r.rect(size2 - h / fi / 2, padding - 1, h / fi, h, 3 * size / 200).attr({ | |
46 | stroke: "#000", | |
47 | opacity: .5, | |
48 | "stroke-width": w3 | |
49 | })); | |
50 | t.cursorhsb.push(t.cursorhsb[0].clone().attr({ | |
51 | stroke: "#fff", | |
52 | opacity: 1, | |
53 | "stroke-width": w1 | |
54 | })); | |
55 | t.ring = r.path(["M", size2, padding, "A", R, R, 0, 1, 1, size2 - 1, padding, "l1,0M", size2, padding + size20 * 2, "A", R2, R2, 0, 1, 1, size2 - 1, padding + size20 * 2, "l1,0"]).attr({ | |
56 | fill: "#000", | |
57 | opacity: 0, | |
58 | stroke: "none" | |
59 | }); | |
60 | ||
61 | // rect drawing | |
62 | t.main = r.rect(xy, xy, wh, wh).attr({ | |
63 | stroke: "none", | |
64 | fill: "#f00", | |
65 | opacity: 1 | |
66 | }); | |
67 | t.main.clone().attr({ | |
68 | stroke: "none", | |
69 | fill: "0-#fff-#fff", | |
70 | opacity: 0 | |
71 | }); | |
72 | t.square = r.rect(xy - 1, xy - 1, wh + 2, wh + 2).attr({ | |
73 | r: 2, | |
74 | stroke: "#fff", | |
75 | "stroke-width": w3, | |
76 | fill: "90-#000-#000", | |
77 | opacity: 0, | |
78 | cursor: "crosshair" | |
79 | }); | |
80 | t.cursor = r.set(); | |
81 | t.cursor.push(r.circle(size2, size2, size20 / 2).attr({ | |
82 | stroke: "#000", | |
83 | opacity: .5, | |
84 | "stroke-width": w3 | |
85 | })); | |
86 | t.cursor.push(t.cursor[0].clone().attr({ | |
87 | stroke: "#fff", | |
88 | opacity: 1, | |
89 | "stroke-width": w1 | |
90 | })); | |
91 | t.H = t.S = t.B = 1; | |
92 | t.raphael = r; | |
93 | t.size2 = size2; | |
94 | t.wh = wh; | |
95 | t.x = x; | |
96 | t.xy = xy; | |
97 | t.y = y; | |
98 | ||
99 | // events | |
100 | t.ring.drag(function (dx, dy, x, y) { | |
101 | t.docOnMove(dx, dy, x, y); | |
102 | }, function (x, y) { | |
103 | t.hsbOnTheMove = true; | |
104 | t.setH(x - t.x - t.size2, y - t.y - t.size2); | |
105 | }, function () { | |
106 | t.hsbOnTheMove = false; | |
107 | }); | |
108 | t.square.drag(function (dx, dy, x, y) { | |
109 | t.docOnMove(dx, dy, x, y); | |
110 | }, function (x, y) { | |
111 | t.clrOnTheMove = true; | |
112 | t.setSB(x - t.x, y - t.y); | |
113 | }, function () { | |
114 | t.clrOnTheMove = false; | |
115 | }); | |
116 | ||
117 | t.color(initcolor || "#f00"); | |
118 | this.onchanged && this.onchanged(this.color()); | |
119 | }, | |
120 | proto = ColorWheel.prototype; | |
121 | proto.setH = function (x, y) { | |
122 | var d = Raphael.angle(x, y, 0, 0), | |
123 | rd = Raphael.rad(d); | |
124 | this.cursorhsb.attr({transform: "r" + [d + 90, this.size2, this.size2]}); | |
125 | this.H = (d + 90) / 360; | |
126 | this.main.attr({fill: "hsb(" + this.H + ",1,1)"}); | |
127 | this.onchange && this.onchange(this.color()); | |
128 | }; | |
129 | proto.setSB = function (x, y) { | |
130 | var me = this; | |
131 | x < me.size2 - me.wh / 2 && (x = me.size2 - me.wh / 2); | |
132 | x > me.size2 + me.wh / 2 && (x = me.size2 + me.wh / 2); | |
133 | y < me.size2 - me.wh / 2 && (y = me.size2 - me.wh / 2); | |
134 | y > me.size2 + me.wh / 2 && (y = me.size2 + me.wh / 2); | |
135 | me.cursor.attr({cx: x, cy: y}); | |
136 | me.B = 1 - (y - me.xy) / me.wh; | |
137 | me.S = (x - me.xy) / me.wh; | |
138 | me.onchange && me.onchange(me.color()); | |
139 | }; | |
140 | proto.docOnMove = function (dx, dy, x, y) { | |
141 | if (this.hsbOnTheMove) { | |
142 | this.setH(x - this.x - this.size2, y - this.y - this.size2); | |
143 | } | |
144 | if (this.clrOnTheMove) { | |
145 | this.setSB(x - this.x, y - this.y); | |
146 | } | |
147 | }; | |
148 | proto.remove = function () { | |
149 | this.raphael.remove(); | |
150 | this.color = function () { | |
151 | return false; | |
152 | }; | |
153 | }; | |
154 | proto.color = function (color) { | |
155 | if (color) { | |
156 | color = Raphael.color(color); | |
157 | var d = color.h * 360; | |
158 | this.H = color.h; | |
159 | this.S = color.s; | |
160 | this.B = color.v; | |
161 | this.cursorhsb.attr({transform: "r" + [d, this.size2, this.size2]}); | |
162 | this.main.attr({fill: "hsb(" + this.H + ",1,1)"}); | |
163 | var x = this.S * this.wh + this.xy, | |
164 | y = (1 - this.B) * this.wh + this.xy; | |
165 | this.cursor.attr({cx: x, cy: y}); | |
166 | return this; | |
167 | } else { | |
168 | return Raphael.hsb2rgb(this.H, this.S, this.B).hex; | |
169 | } | |
170 | }; | |
171 | })(window.Raphael); |