拉斐尔js。沿曲线填充颜色 [英] Raphael js. Fill color along a curve

查看:98
本文介绍了拉斐尔js。沿曲线填充颜色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个圆圈,我可以在圆圈周围选择两个点。

I have created a circle in which I can choose two points along the circumference of of circle.

我想填充这两个点之间的部分。

I want to fill the portion between those two points.

演示

如果您看到演示,我想填补两点之间的角度。

If you see the demo, I want to fill the angle between two 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 a = 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();

            for (var i = 0; i < 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 a  = 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;
  }

更新:

在Chris的帮助下,

With Chris's help,

我取得了一些成功。


参见 演示


错误:

1.如果你先开始绿色,红色突破,

2.如果你先开始红色并使角度大于180度,当绿色减少到180度以下时,它再次破裂。



更新2

DEMO

BUGS:

1.如果你先开始红色并制作大于180度的角度,当绿色降低到180度以下时,它会再次破裂。

2.有时弧线方向相反。

I have got some success.

See Demo

Bugs :
1. If you start green first, red breaks,
2. If you start red first and makes angle of greater than 180 degree and when green reduces that below 180 degree, it breaks again.

UPDATE 2
DEMO
BUGS:
1. If you start red first and makes angle of greater than 180 degree and when green reduces that below 180 degree, it breaks again.
2. Sometimes arcs in opposite direction.

推荐答案

以下是可行的解决方案:

Here's working solution:

演示

(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 a = 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();
            for (var i = 0; i < 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: 1,
                "stroke-width": w3
            }));
            t.startCursor.push(t.startCursor[0].clone().attr({
                stroke: "#00A0C6",
                fill : "#8fd117", 
                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: 1,
                "stroke-width": w3,

            }));

            t.endCursor.push(t.endCursor[0].clone().attr({
                stroke: "#F96E5B",
                fill : "#8fd117",
                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]});

            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.initX0 = t.x0;
            t.initY0 = t.y0;
            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.initX1 = t.x1;
            t.initY1 = t.y1;
            var path = "M" + t.x0 + "," + t.y0 + "A" + t.R1 + "," + t.R1 + " 50 0,1 " + t.x1 + "," + t.y1;

            t.arc = r.path(path)
            .attr({
                stroke: "#009900",
                "stroke-width": 10
            });


            t.startCursor.drag(function (dx, dy, x, y) {
                   t.docOnMove(dx, dy, x, y,'startCursor');
                }, function (x, y) { 
                    t.setH(x - t.x - t.size2, y - t.y - t.size2,'startCursor');
                }, function () { 

            }); 

            t.endCursor.drag(function (dx, dy, x, y) {
                   t.docOnMove(dx, dy, x, y,'endCursor');
                }, function (x, y) { 
                    t.setH(x - t.x - t.size2, y - t.y - t.size2,'endCursor');
                }, function () { 

            }); 

            t.startCursor.toFront();
            t.endCursor.toFront();
        },
        proto = ColorWheel.prototype;

    proto.setH = function (x, y,cursor) {  
        var d = Raphael.angle(x, y, 0, 0);
        if(d > 270) {
            d = d - 270;
        }
        else {
            d = d + 90;
        } 

        if((cursor === 'startCursor' && d > this.endCursor[0]._.deg) || (cursor === 'endCursor' && d <= this.startCursor[0]._.deg)) {
            return;
        }

        if(cursor === 'startCursor') {
            this.startCursor.attr({transform: "r" + [d, this.size2, this.size2]});
        }
        else {
            this.endCursor.attr({transform: "r" + [d, this.size2, this.size2]});
        }   

        var m = this.startCursor[0]._.deg ;
        var n = this.endCursor[0]._.deg;
        var t = this;        
        var flag = 0;

        if(m > 360) {
            m = m - 360;
            flag = 1;  
        }

        if( n > 360 ) {
            n = n - 360;
        } 


        var diff = Math.abs(m - n); 

        if (diff > 180) { 
            flag = 1;
        }

        var path = "";
        var sweep = 1; 

        if(cursor === 'endCursor') { 
            t.x1 = t.initX0 + t.R1 * Math.sin(n * Math.PI / 180);
            t.y1 = t.initY0 + t.R1 - t.R1 * Math.cos(n * Math.PI / 180);
        }
        else { 
            t.x0 = t.initX0 + t.R1 * Math.sin(m * Math.PI / 180);
            t.y0 = t.initY0 + t.R1 - t.R1 * Math.cos(m * Math.PI / 180);
        }

        console.log(m,t.x0,t.y0,t.x1,t.y1);

        path = "M" + t.x0 + "," + t.y0 + "A" + t.R1 + "," + t.R1 + " " +  diff + " " +  flag + "," + sweep + " " + t.x1 + "," + t.y1;

        t.arc = t.arc.attr("path", path );

        this.onchange(m,n,diff);
    };

    proto.docOnMove = function (dx, dy, x, y,cursor) {
        this.setH(x - this.x - this.size2, y - this.y - this.size2,cursor);

    };

})(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;


    }
};

这篇关于拉斐尔js。沿曲线填充颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆