javascript - Raphael js. Fill color along a curve -
i have created circle in can choose 2 points along circumference of of circle.
i want fill portion between 2 points.
if see demo, want fill angle between 2 points.
js:
(function (raphael) { raphael.colorwheel = function (x, y, size, initcolor, element) { return new colorwheel(x, y, size, initcolor, element); }; var pi = math.pi, doc = document, win = window, colorwheel = function (x, y, size, initcolor, element) { size = size || 200; var w3 = 3 * size / 200, w1 = size / 200, fi = 1.6180339887, segments = 3,//pi * size / 50, size20 = size / 20, size2 = size / 2, padding = 2 * size / 200, t = this; var h = 1, s = 1, b = 1, s = size - (size20 * 4); var r = element ? raphael(element, size, size) : raphael(x, y, size, size), xy = s / 6 + size20 * 2 + padding, wh = s * 2 / 3 - padding * 2; w1 < 1 && (w1 = 1); w3 < 1 && (w3 = 1); // ring drawing var = pi / 2 - pi * 2 / segments * 1.3, r = size2 - padding, r2 = size2 - padding - size20 * 2, 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(); (var = 0; < segments; i++) { r.path(path).attr({ stroke: "none", fill: "#8fd117", transform: "r" + [(360 / segments) * i, size2, size2] }); } 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({ "stroke-width": w3, stroke: "#fff" }); t.startcursor = r.set(); var h = size20 * 2 + 2; t.startcursor.push(r.rect(size2 - h / fi / 2, padding - 1, h / fi, h, 3 * size / 200).attr({ stroke: "#00a0c6", opacity: .5, "stroke-width": w3 })); t.startcursor.push(t.startcursor[0].clone().attr({ stroke: "#00a0c6", opacity: 1, "stroke-width": w1 })); t.endcursor = r.set(); var h = size20 * 2 + 2; t.endcursor.push(r.rect(size2 - h / fi / 2, padding - 1, h / fi, h, 3 * size / 200).attr({ stroke: "#f96e5b", opacity: .5, "stroke-width": w3 })); t.endcursor.push(t.endcursor[0].clone().attr({ stroke: "#f96e5b", opacity: 1, "stroke-width": w1 })); 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({ fill: "#000", opacity: 0, stroke: "none" }); t.h = t.s = t.b = 1; t.raphael = r; t.size2 = size2; t.wh = wh; t.x = x; t.xy = xy; t.y = y; t.endcursor.attr({transform: "r" + [50, t.size2, t.size2]}); // events t.ring.drag(function (dx, dy, x, y) { t.doconmove(dx, dy, x, y); }, function (x, y) { // rotate on click t.seth(x - t.x - t.size2, y - t.y - t.size2); }, function () { }); }, proto = colorwheel.prototype; proto.seth = function (x, y) { var d = raphael.angle(x, y, 0, 0); this.h = (d + 90) / 360; var = 0; if(d > 270) { d = d - 270; } else { d = d + 90; } var m = math.abs(d - this.startcursor[0]._.deg); var n = math.abs(d - this.endcursor[0]._.deg); if(m > 180) { m = 360 - m ; } if(n > 180) { n = 360 - n; } if( m <= n) { this.startcursor.attr({transform: "r" + [d, this.size2, this.size2]}); } else { this.endcursor.attr({transform: "r" + [d, this.size2, this.size2]}); } m = this.startcursor[0]._.deg ; n = this.endcursor[0]._.deg; if(m > 360) { m = m - 360; } if( n > 360 ) { n = n - 360; } var diff = m > n ? m - n : n - m; this.onchange(m,n,diff); }; proto.doconmove = function (dx, dy, x, y) { this.seth(x - this.x - this.size2, y - this.y - this.size2); }; })(window.raphael); window.onload = function () { var cp2 = raphael.colorwheel(60, 20, 200, "#eee"); var x = document.getelementbyid('x'); var y = document.getelementbyid('y'); var angle = document.getelementbyid('angle'); cp2.onchange = function (x, y, ang) { x.innerhtml = math.round(x * 100) / 100; y.innerhtml = math.round(y * 100) / 100; angle.innerhtml = math.round(ang * 100) / 100; } };
html:
<div id="wrapper">x : <span id="x">0</span> <br>y: <span id="y">50</span> <br>angle: <span id="angle">50</span> </div>
css:
body { background: #e6e6e6; } #wrapper { position: absolute; top: 240px; left: 100px; }
update:
with chris's help,
i have got success.
see demo
bugs :
1. if start green first, red breaks,
2. if start red first , makes angle of greater 180 degree , when green reduces below 180 degree, breaks again.
update 2
demo
bugs:
1. if start red first , makes angle of greater 180 degree , when green reduces below 180 degree, breaks again.
2. arcs in opposite direction.
cool project. need add elliptical arc color wheel , redraw path on onchange event.
i got half way here: works if move orange cursor, breaks if move blue cursor.
to start:
t.x0 = t.startcursor[0].attr("x") + t.startcursor[0].attr("width") / 2; t.y0 = t.startcursor[0].attr("y") + t.startcursor[0].attr("height") / 2; t.r1 = (r2 + r) / 2; t.x1 = t.x0 + t.r1 * math.sin(50 * math.pi / 180); t.y1 = t.y0 + t.r1 - t.r1 * math.cos(50 * math.pi / 180); t.arc = r.path("m" + t.x0 + "," + t.y0 + "a" + t.r1 + "," + t.r1 + " 50 0,1 " + t.x1 + "," + t.y1) .attr({ stroke: "#009900", "stroke-width": 10 });
on update:
if (n > 180) { flag = 1; } var diff = m > n ? m - n : n - m; t.x0 = t.x0 + t.r1 * math.sin(m * math.pi / 180); t.y0 = t.y0 + t.r1 - t.r1 * math.cos(m * math.pi / 180); t.x1 = t.x0 + t.r1 * math.sin(diff * math.pi / 180); t.y1 = t.y0 + t.r1 - t.r1 * math.cos(diff * math.pi / 180); t.arc = t.arc.attr("path", "m" + t.x0 + "," + t.y0 + "a" + t.r1 + "," + t.r1 + " " + diff + " " + flag + ",1 " + t.x1 + "," + t.y1);
should able take here.
update, may 8:
you can fix first problem changing flag on diff, not on second angle:
if (diff > 180) { flag = 1; }
the event that's triggering second problem second angle (the red handle) passing 0-degree mark. easiest way catch add 360 angle if it's less first angle:
var m = this.startcursor[0]._.deg ; var n = this.endcursor[0]._.deg; var t = this; var flag = 0; var sweep = 1; var path = ""; if (n < m) { m += 360; } var diff = math.abs(m - n); if (diff > 180) { flag = 1; }
note: catching situations (n > 360)
, (m > 360)
, doesn't appear necessary -- angles arrive @ point in code set below 360, @ least in chrome.
Comments
Post a Comment