Create new effects with jSignage

From SpinetiX Support Wiki

Jump to: navigation, search

This page is related to jSignage effects.

Description

It is possible to define new effects and to add them to the API. A set of helper functions are available in the jSignage API to reach this aim. Creating new effects boils down to adding a new jSignage method that will take care to add custom SVG code for the effect - such an example can be found in the JSignage Custom Effects plugin.

Effects and SVG

All effects in jSignage follow the same SVG pattern. An effect is applied by wrapping the SVG code for a layer somewhere inside a <g> element.

All the code for producing the effect is added as children of this element. It must have an spx:effect-target-id attribute to be recognized as an effect by the jSignage API. This attribute contains the id of the layer. When multiple effects are applied they are chained by the effect-target-id attribute.

For example, this is the SVG code generated by applying a fade in effect to a video. Notice how the effect is composed of an additional group around the media and chained to the media, the effect-target-id attribute acting like a pointer.

 <g xml:id='fadein' spx:effect-target-id='media'>
   <animate attributeName='opacity' from='0' to='1' dur='1' begin='media.begin'/>
   <video xml:id='media' href='clip.mp4' width='160' height='90' begin='0'/>
 </g>

For example, this is the SVG code generated by applying both a fade in and fade out effect to a video. Notice how the two effects are chained together and then to the media, the effect-target-id attribute acting like a pointer.

 <g xml:id='fadeout' spx:effect-target-id='fadein'>
   <animate attributeName='opacity' from='1' to='0' dur='1' begin='media.end-1'/>
   <g xml:id='fadein' spx:effect-target-id='media'>
     <animate attributeName='opacity' from='0' to='1' dur='1' begin='media.begin'/>
     <video xml:id='media' href='clip.mp4' width='160' height='90' begin='0'/>
   </g>
 </g>

Creating new effects boils down to adding a new jSignage method that will take care of the wrapping and add custom SVG code for the effect.

Helper functions

The following helper functions are provided to simplify the writing of the effect methods. Additional helper functions can be found under JSignage utilities methods.

effectIn / effectOut

.effectIn( callback )
.effectOut( dur, callback )

These methods take care of wrapping all the selected elements in a jSignage object in a <g> element for the effect, then replace the selection in the jSignage object with those wrapped elements and arrange for the provided callback to be called. The callback may be deferred until the layout of the layer has been resolved, typically until the layer is added to the rendering tree. effectIn will pass a trigger parameter to the callback for the beginning of the media while effectOut will pass a trigger for the end of the media.

Callbacks

callback( trigger, inner, width, height, left, top, bbw, bbh )

In the callback, this refers to the wrapping <g> element. The arguments supplied are:

  • trigger
    trigger for animations - this is typically used as the begin attribute for animations
  • inner
    DOM element which is next in the effect stack; either the <g> of the next effect or the element of the layer
  • width, height
    width and height of the layer in pixels
  • left, top
    left and top position of the layer inside its parent layer in pixels
  • bbw, bbh
    width and height of the parent layer in pixels

The callback must not modify the attributes of this or inner but should instead add SVG animation elements under this which target either. When entering the callback, inner is a direct child of this. It can be relocated as a deeper child, but this is not recommended.

Creating effects

To create a new effect, the jSignage object prototype must be extended with a new method:

jSignage.fn.myEffectIn = function( args ) { 
   // Parse the arguments
   ...
   // add the effect
   return this.effectIn( function( trigger, inner, width, height ) {
     // describe the effect. The trigger can be used to control the begin element.
     ...
   });
};
jSignage.fn.myEffectOut = function( args ) { 
   // Parse the arguments
   ...
   // add the effect
   var dur = jSignage.durInSeconds( args && args.dur, 1 ); 
   return this.effectOut( dur, function( trigger, inner, width, height ) {
     // describe the effect. The trigger can be used to control the begin element.
     ...
   });
};

Note that:

  • this is a jSignage object representing the layer on which the effect is applied.
  • The .effectIn() and .effectOut() helper method is used to wrap the target layer(s) into a <g> element.
  • this is returned so other jSignage methods can be called on the result.

Examples

Audio fade in

Here is the code for creating an audio fade in effect:

$.fn.audioFadeIn = function( args ) {
    var dur = jSignage.durInSeconds( args && args.dur, 1 );
    return this.effectIn( function( trigger ) {
        jSignage.svgAnimation( this, 'animate', {
            attributeName: 'audio-level',
            from: '0',
            to: '1',
            begin: trigger,
            dur: dur
        });
    });
};

Notice how it extends the jSignage object prototype with a new method which:

  • Converts the time parameters to numerical values in seconds with the $.durInSeconds helper function.
  • Use the .effectIn helper method to wrap the target layer(s) into a <g> element.
  • Adds a simple animation to produce the effect.
  • Returns this so other jSignage methods can be called on the result.

Audio fade out

Here is the code for an audio fade out effect:

$.fn.audioFadeOut = function( args ) {
    var dur = jSignage.durInSeconds( args && args.dur, 1 );
    return this.effectOut( dur, function( trigger ) {
        jSignage.svgAnimation( this, 'animate', {
            attributeName: 'audio-level',
            from: '1',
            to: '0',
            begin: trigger,
            dur: dur
        });
    });
};

Rotate

Example of code to rotate (360 degree) the media as an input effect.

jSignage.fn.rotate= function( args ) {
   var dur = jSignage.durInSeconds( args && args.dur, 0.5 );
   return this.effectIn( function( trigger, inner, width, height ) {
        jSignage.svgAnimation( this, 'animateTransform', {
          attributeName: 'transform',
          additive: 'sum', type: 'rotate',
          from: '0,'+ width/2 +',' + height/2 ,
          to: '360,'+ width/2 +',' + height/2,
          begin: trigger,
          dur: dur
        });
   });
};

The effect adds an animateTransformon the media with type rotate from 0 to 360, center in the middle of the media.

Combining effects

It is also possible to combine existing effects:

jSignage.fn.myEffect = function( args ) { 
   var d = $.durInSeconds( args && args.dur, 1 )
   return this.flyIn( { dur: d, direction: 'leftToRight' } ).fadeIn( { dur: d } );
}

The new effect will combine a flyIn effect from left to right and a fade in effect.

This page was last modified on 7 January 2021, at 17:56.