如何向Raphael.js对象添加内部阴影?

时间:2013-01-21 01:12:21

标签: javascript jquery svg raphael

我发现了一些基于模糊或发光的阴影插件,还有笔触不透明度,但这只是模拟,不能在内阴影的情况下使用。

SVG规范中也没有简单的过滤器,所以你不能简单地利用它。

1 个答案:

答案 0 :(得分:0)

我根据这两个链接编写了自己的插件:

https://github.com/dahoo/raphael.dropshadow.js

http://svgquickref.com/properties/filter/inner-shadow/index.html

HTML代码(用法):

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta charset="utf-8">
        <title>Raphael Test</title>

        <script type="text/javascript" src="js/libs/jquery.js"></script>
        <script type="text/javascript" src="js/libs/raphael.js"></script>
        <script type="text/javascript" src="js/libs/raphael.innershadow.js"></script>
    </head>
    <body>
        <div id="raphael"></div>
        <script type="text/javascript">
            $(document).ready(function() {
                var raphael, path, pattern;
                raphael = Raphael(document.getElementById('raphael'), 500, 500);
                path = raphael.circle(200, 200, 180);
                path.attr('fill', 'red');
                path.innerShadow(50, 0, 0, "green", 0.5);
            });
        </script>
    </body>
</html>

插件代码:

(function() {
    if(Raphael.vml) {
        Raphael.el.innerShadow = function (size, offsetX, offsetY, color, opacity, filter_id, input) {
            // not supporting VML yet
            return this; // maintain chainability
        }
    } else {
        var $ = function(el, attr) {
            if(attr) {
                for(var key in attr)
                if(attr.hasOwnProperty(key)) {
                    el.setAttribute(key, attr[key]);
                }
            } else {
                return document.createElementNS("http://www.w3.org/2000/svg", el);
            }
        };
        Raphael.el.innerShadow = function(size, offsetX, offsetY, color, opacity, filter_id, input) {

            opacity = opacity || 1;
            filter_id = filter_id || "innershadow";
            input = input || "SourceGraphic";

            if(size != "none") {
                var fltr = $("filter"),
                    offset = $("feOffset"), // offset
                    blur = $("feGaussianBlur"), // shadow bluer
                    composite1 = $("feComposite"), // invert drop shadow to create inner shadow
                    flood = $("feFlood"), // color & opacity
                    composite2 = $("feComposite"), // clip color inside shadow
                    composite3 = $("feComposite") // put shadow over original object

                fltr.id = filter_id;

                $(fltr, {
                        "height" : "150%",
                        "width" : "150%"
                });

                $(offset, {
                    dx: offsetX,
                    dy: offsetY
                });

                $(blur, {
                    stdDeviation: +size,
                    result: "offset-blur"
                });

                $(composite1, {
                    operator: "out",
                    "in": "SourceGraphic",
                    in2: "offset-blur",
                    result: "inverse"
                });

                $(flood, {
                    "flood-color": color,
                    "flood-opacity": opacity,
                    result: "color"
                });

                $(composite2, {
                    operator: "in",
                    "in": "color",
                    in2: "inverse",
                    result: "shadow"
                });

                $(composite3, {
                    operator: "over",
                    "in": "shadow",
                    in2: input
                });

                fltr.appendChild(offset);
                fltr.appendChild(blur);
                fltr.appendChild(composite1);
                fltr.appendChild(flood);
                fltr.appendChild(composite2);
                fltr.appendChild(composite3);

                this.paper.defs.appendChild(fltr);
                this._blur = fltr;

                $(this.node, {
                    "filter" : "url(#" + filter_id + ")"
                });

            } else {
                if(this._blur) {
                    this._blur.parentNode.removeChild(this._blur);
                    delete this._blur;
                }
                this.node.removeAttribute("filter");
            }
            return this;  // maintain chainability
        };
    }

    Raphael.st.innerShadow = function(size, offsetX, offsetY, color, opacity, filter_id, input) {
        return this.forEach(function(el) {
            el.innerShadow(size, offsetX, offsetY, color, opacity, filter_id, input);
        });
    };
})();