2

I am trying to add a glow effect using snap SVG. Unlike raphael.js, I believe Snap doesn't support glow by default. However, there is a shadow effect. I tried to apply the shadow using set interval so that it mimics the behavior of a glow. But it is not working as it is intended to work. I want the shadow to fade-in and out say for 4-5 times making it loo like a glow. Here I invoke the shadow but it remains there irrespective of adding it to a setinterval code. Here is the JS FIDDLE

CODE

var s = Snap("#main");
var thinkers = s.select("#lastImage");
var light = s.select("#look2");

// setinterval with counter
function setIntervalX(callback, delay, repetitions) {
    var x = 0;
    var intervalID = window.setInterval(function () {

        callback();

        if (++x === repetitions) {
            window.clearInterval(intervalID);
        }
    }, delay);
}
// function to add glow

function addShadow() {
    var f = s.filter(Snap.filter.shadow(2, 2, 10, "#ffffff"));
    light.attr({
        filter: f
    });
}
// remove glow/shadow
function removeShadow() {
    var k = s.filter(Snap.filter.shadow(0, 0, 0, "#ffffff"));
    light.attr({
        filter: k
    });
}
setTimeout(shadow, 500)

function shadow() {
    setIntervalX(addShadow, 1000, 4);
}
Thomas Sebastian
  • 1,582
  • 5
  • 18
  • 38

2 Answers2

2

I'm going to show a slightly different way of doing a filter, which I think should work for any filter, as you can just dictate it via normal svg markup which then opens up a few more filters that you may find out there on the internet to use.

So it will allow you to choose any filter, any combination, and change any attribute of that filter (you can combine them).

Lets suppose you find some svg filter effect, create a string with it, eg...

var myFilter = '<filter id="glow" x="-30%" y="-30%" width="160%" height="160%"><feGaussianBlur id="gauss" stdDeviation="10 10" result="glow"/><feMerge><feMergeNode in="glow"/><feMergeNode in="glow"/><feMergeNode in="glow"/></feMerge></filter>';

Create your filter with Snap, (it will be a fragment, so we need to append it to the paper)... We can access any of the elements if we have given them an id, or via css selectors with Snap( someCssselector ) as below.

s.append( Snap.parse(myFilter) );
var glowFilter = Snap('#glow');
var gaussian = Snap('#gauss');

var t = s.rect(100,100,100,100).attr({ stroke: 'yellow', fill: 'orange', filter: glowFilter }); 

Then we can create an animate function with a callback, and vary the parameter on any of the filters...

var onOff = 1;

function animGlow() {

    var start = 0; var end = 10;
    if( onOff ) { start = 10; end = 0 };
    onOff = onOff ? 0 : 1; 
    Snap.animate(start,end,function( amount ) {        
        gaussian.attr({ stdDeviation: amount + ' ' + amount });
    }, 800, mina.linear, animGlow);
}

animGlow();

jsfiddle or jsfiddle with a slightly different effect

This will hopefully give some ideas. There are simpler ways if you just want a Snap shadow, but I'm just trying to highlight alternative routes.

Ian
  • 13,724
  • 4
  • 52
  • 75
  • Filter's doesn't work on IE9 if I remember right? Are you sure this will work on IE9. Beacuse I want IE9+ support. – Thomas Sebastian May 06 '15 at 04:49
  • Possibly not, but in that case, I'm not sure why filters are used in the question. – Ian May 06 '15 at 06:25
  • I was looking for something like adding a shadow and that was what I got from their documentation. Can we achieve this using shadow? Since I misled you, I am accepting your answer. – Thomas Sebastian May 06 '15 at 06:30
  • Problem is, shadow to my knowledge is just a filter also. Also css filters aren't supported in CSS in IE (to my knowledge). I think you may need to look into IE filters maybe ? Its a bit of a minefield with support though (maybe there is some library with support for this). Out of interest, ignoring the fact its a filter, is it visually ok? (I just have another backup idea I may have a play with and post if it works) – Ian May 06 '15 at 08:37
  • I meant something like box shadow which has IE9 support ..However, I convinced them to make use of filters.. Thanks.. Whatever your plan is, I would totally love to see that. Post a fiddle if you are free. – Thomas Sebastian May 06 '15 at 08:42
  • Basically I was wondering about faking it, ignoring filters altogether, and using either a hard baked glow which scales in/out behind the main object. Here is a version showing the essence of what I mean just using opacity and strokeWidth. http://jsfiddle.net/5fjj98a5/12/ – Ian May 06 '15 at 08:56
  • hahaha cool. May be a little blur ;) Better to stick to the original though :P – Thomas Sebastian May 06 '15 at 09:32
0

To KISS for glow(not as good as Raphael glow) and add drag, try this:

var s = Snap("#svgTest");

//set up a shadow for hover over images shadow(dx, dy, 'color', opacity??? 3 seems darkest)
var glow = s.filter(Snap.filter.shadow(0, 2, 'yellow', .8));

//rect1 has glow
var rect1 = s.rect(10,10,50,50).attr({ fill: 'green', filter: glow });
//rect2 only has glow on hover
var rect2 = s.rect(100,100,50,50)
    .attr({ fill: 'green' })
    .hover(function() {
        //on hover..add fn glow above
        this.attr({filter : glow});
        },
        function() { 
            //on hover out, set filter to null..delete glow
            this.attr({filter : ''});
        }
    ); //end hover

// make all  dragable
var move = function(dx,dy) {
//console.log("dx: " +dx + " dy: " + dy);
        this.attr({
                    transform: this.data('origTransform') + (this.data('origTransform') ? "T" : "t") + [dx, dy]
                });
}

var start = function() {
        this.data('origTransform', this.transform().local );
}
var stop = function() { //do nothing
}
var selectAll = s.group(rect1, rect2);
selectAll.drag(move, start, stop );