简体   繁体   中英

How can I add inner shadow to Raphael.js object?

I found some drop shadows plugins based on blur or glow, also stroke opacity, but this is only simulation, and can't be used in case of inner shadow.

Also there is no simple filter in SVG specification, so you can't simply take advantage on it.

I wrote my own plugin based on this two links:

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

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

HTML code (usage):

<!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>

Plugin code:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM