Difference between revisions of "Widget:Logo"

From Hackerspace ACKspace
Jump to: navigation, search
(created initial logo widget)
 
m (now ''really'' centered it)
 
(70 intermediate revisions by the same user not shown)
Line 8: Line 8:
  
 
  <nowiki>{{#widget:</nowiki>{{PAGENAME}}<nowiki>
 
  <nowiki>{{#widget:</nowiki>{{PAGENAME}}<nowiki>
|image=https://ackspace.nl/w/images/thumb/8/83/ACKlogo.png/600px-ACKlogo.png
+
|image=/w/images/e/e9/ACKsmass_logo.png
|width=260px
+
|width=600px
|height=20px
+
|height=200px
 
|padding=8px
 
|padding=8px
 
|float=right
 
|float=right
Line 17: Line 17:
 
This will give the following result:<br/>
 
This will give the following result:<br/>
 
{{#widget:{{PAGENAME}}
 
{{#widget:{{PAGENAME}}
|image=https://ackspace.nl/w/images/thumb/8/83/ACKlogo.png/600px-ACKlogo.png
+
|image=/w/images/e/e9/ACKsmass_logo.png
|width=260px
+
|width=600px
|height=20px
+
|height=200px
 
|padding=8px
 
|padding=8px
 
|float=right
 
|float=right
 
}}<br/>
 
}}<br/>
Note that '''image''' is mandatory, the rest is optional. Also, you must provide a unit for the sizes (i.e. px, %, etc.)
+
'''Notes'''
 +
* it will display snow in December - March and will show Christmas lights between 7 December and 7 January
 +
* '''image''' is mandatory, the rest is optional.
 +
*: it also must be written without protocol since colon (''':''') is not allowed, and may be relative, for example: ''//ackspace.nl/w/images/e/e9/ACKsmass_logo.png'' or ''/w/images/e/e9/ACKsmass_logo.png''
 +
* You must provide a unit for the sizes (i.e. px, %, etc.)
 +
 
 +
Also note that there is a chain of browser extensions and apps within the [[GitHub::https://github.com/ACKspace/espixelflut|espixelflut github repo]]:
 +
* [https://github.com/ACKspace/espixelflut/blob/master/chrome/FlutLogo%20app%20connector%20extension.crx FlutLogo app connector extension.crx]: the extension that listens to the UDP connector app and drives the logo "LEDs" ([https://github.com/ACKspace/espixelflut/tree/master/chrome/FlutLogo%20app%20connector%20extension source available], but it needs a static ID for the connector app)
 +
* [https://github.com/ACKspace/espixelflut/tree/master/chrome/FlutLogo%20UDP%20connector%20app FlutLogo UDP connector app] the app that listens to UDP ART-net packets and connects to the browser extension
 +
* [https://github.com/ACKspace/espixelflut/tree/master/chrome/FlutArt FlutArt]: an ART-net app that can be used to control lights (which also works on the browser extension)
 +
 
 +
Note that if you want to use the [[LED sleeve]] [[GitHub::https://github.com/AlbertVos/bitlair-ohm2013-ledstrip-contol|python code from bitlair]], you have to provide a different listening port to avoid conflicts, like this:
 +
<code>./fire2.py port=0 addr='[("127.0.0.1",6454)]'</code>
  
 
== Copy to your site ==
 
== Copy to your site ==
 
To use this widget on your site, just install [http://www.mediawiki.org/wiki/Extension:Widgets MediaWiki Widgets extension] and copy [{{fullurl:{{FULLPAGENAME}}|action=edit}} full source code] of this page to your wiki as '''{{FULLPAGENAME}}''' article.
 
To use this widget on your site, just install [http://www.mediawiki.org/wiki/Extension:Widgets MediaWiki Widgets extension] and copy [{{fullurl:{{FULLPAGENAME}}|action=edit}} full source code] of this page to your wiki as '''{{FULLPAGENAME}}''' article.
[[Category:SpaceAPI]]
+
 
</noinclude><includeonly><script type="text/javascript">
+
</noinclude><includeonly>
 +
<canvas id="logo" width="<!--{$width|escape:html|default:auto}-->" height="<!--{$height|escape:html|default:auto}-->" style="float:<!--{$float|escape:html|default:none}-->"><img id="img" src="<!--{$image|escape:urlpathinfo}-->"/></canvas>
 +
<script type="text/javascript">
 
(function( )
 
(function( )
 
{
 
{
 
     "use strict";
 
     "use strict";
  
strict";
+
    var timer = null;
 +
    var start = null;
 +
    var oldTimestamp = null;
 +
    var maxFlakes = 200;
 +
    var snowFlakes = [];
 +
    var dynamicImage = null;
 +
    var width = null;
 +
    var height = null;
 +
    var ctx = null;
 +
    var offsetY = 50;
 +
    var alphaDir = 0.01;
 +
    var alpha = 0;
 +
    var buffer;
 +
    var bufferContext;
 +
    var hashParams = location.hash.split("#").slice(1);
 +
    var debug = ( hashParams.indexOf("debug") !== -1 );
 +
    //mw.config.set("debug", true)
  
var start = null;
+
    function blink()
var oldTimestamp = null;
+
    {
var maxFlakes = 200;
+
        treeLights[ nToggle ].on = !treeLights[ nToggle ].on;
var snowFlakes = [];
 
var dynamicImage = null;
 
var width = null;
 
var height = null;
 
var ctx = null;
 
var offsetY = 50;
 
var alphaDir = 0.01;
 
var alpha = 0;
 
  
function blink()
+
        nToggle++;
{
+
        if ( nToggle >= treeLights.length )
    treeLights[ nToggle ].on = !treeLights[ nToggle ].on;
+
            nToggle = 0;
 +
    }
  
     nToggle++;
+
     var nToggle = 0;
     if ( nToggle >= treeLights.length )
+
     var treeLights = [
         nToggle = 0;
+
        { x:  84, y: 16, c: [0xff,0x00,0x00], on: false },
}
+
        { x: 101, y: 40, c: [0xff,0xa5,0x00], on: false },
 +
        { x:  87, y: 60, c: [0xff,0xc0,0xcb], on: false },
 +
        { x:  64, y: 79, c: [0x33,0x66,0xff], on: false },
 +
         { x: 119, y: 91, c: [0xff,0xff,0x00], on: false }
 +
    ];
 +
    var snow = [255,255,255];
 +
    var ackbit = [255,0,0];
  
var nToggle = 0;
+
     var oldTimestamp = null;
var treeLights = [
+
    function snowFall( _timestamp )
    { "x" :  84, "y": 16, "color" : "red",    "on" : false },
 
    { "x" : 101, "y": 40, "color" : "orange", "on" : false },
 
    { "x" :  87, "y": 60, "color" : "pink",  "on" : false },
 
    { "x" :  64, "y": 79, "color" : "#36f",  "on" : false },
 
     { "x" : 119, "y": 91, "color" : "yellow", "on" : false }
 
];
 
 
 
var oldTimestamp = null;
 
function snowFall( _timestamp )
 
{
 
    // Smooth progress
 
    if ( !start )
 
        start = _timestamp;
 
    var progress = _timestamp - start;
 
 
 
    if ( ( progress / 500 ) > snowFlakes.length && ( _timestamp - oldTimestamp < 50 ) )
 
        snowFlakes.push( { "x" : ( Math.random( ) * width ) | 0, "y" : 0 } );
 
    oldTimestamp = _timestamp;
 
 
 
    if ( snowFlakes.length )
 
 
     {
 
     {
         // Fetch a random flake
+
         // Smooth progress
         var pixelPos;
+
         if ( !start )
         var nFlakeNot = ( Math.random( ) * snowFlakes.length ) | 0;
+
            start = _timestamp;
 +
         var progress = _timestamp - start;
  
         var delta = _timestamp - oldTimestamp;
+
         if ( ( progress / 500 ) > snowFlakes.length && ( _timestamp - oldTimestamp < 50 ) )
 +
            snowFlakes.push( { x: ( Math.random( ) * width ) | 0, y: 0, c:snow.slice() } );
 
         oldTimestamp = _timestamp;
 
         oldTimestamp = _timestamp;
  
         for ( var nFlake = 0; nFlake < snowFlakes.length; nFlake++ )
+
         if ( snowFlakes.length )
 
         {
 
         {
             // Skip some flakes
+
             // Fetch a random flake
             if ( Math.random() > 0.8 )
+
             var pixelPos;
                continue;
+
            var nFlakeNot = ( Math.random( ) * snowFlakes.length ) | 0;
 +
 
 +
            var delta = _timestamp - oldTimestamp;
 +
            oldTimestamp = _timestamp;
  
             var flake = snowFlakes[ nFlake ];
+
             for ( var nFlake = 0; nFlake < snowFlakes.length; nFlake++ )
            // Calculate the new position of the flake.
 
            // If it can't move anywhere down (3 positions): fixate it in the dynamic image and reset the flake
 
            if ( !updateFlake( flake, dynamicImage ) )
 
 
             {
 
             {
                 // Fixate flake
+
                 // Skip some flakes
                pixelPos = ( flake.x + width * flake.y ) * 4;
+
                if ( Math.random() > 0.8 )
                dynamicImage.data[ pixelPos + 0 ] = 255;
+
                    continue;
                dynamicImage.data[ pixelPos + 1 ] = 255;
+
 
                dynamicImage.data[ pixelPos + 2 ] = 255;
+
                var flake = snowFlakes[ nFlake ];
                dynamicImage.data[ pixelPos + 3 ] = 255;
+
                // Calculate the new position of the flake.
 +
                // If it can't move anywhere down (3 positions): fixate it in the dynamic image and reset the flake
 +
                if ( !updateFlake( flake, dynamicImage ) )
 +
                {
 +
                    // Fixate flake
 +
                    pixelPos = ( flake.x + width * flake.y ) * 4;
 +
                    dynamicImage.data[ pixelPos + 0 ] = flake.c[0];
 +
                    dynamicImage.data[ pixelPos + 1 ] = flake.c[1];
 +
                    dynamicImage.data[ pixelPos + 2 ] = flake.c[2];
 +
                    dynamicImage.data[ pixelPos + 3 ] = 254;
 +
 
 +
                    // Generate new flake
 +
                    flake = { x: ( Math.random( ) * width ) | 0, y: 0, c:snow.slice() };
 +
                }
 +
 
 +
                // Store the updated or newly created flake.
 +
                snowFlakes[ nFlake ] = flake;
  
                // Generate new flake
 
                flake = { "x" : ( Math.random( ) * width ) | 0, "y" : 0 };
 
 
             }
 
             }
  
             // Store the updated or newly created flake.
+
             // Clear the current frame
            snowFlakes[ nFlake ] = flake;
 
  
 
             // Draw the dynamic image
 
             // Draw the dynamic image
 
             ctx.putImageData( dynamicImage, 0, 0 );
 
             ctx.putImageData( dynamicImage, 0, 0 );
 +
 +
            // Draw all flakes
 +
            ctx.fillStyle = 'white';
 +
            ctx.shadowBlur = 0;
 +
 +
            for ( nFlake = 0; nFlake < snowFlakes.length; nFlake++ )
 +
            {
 +
                flake = snowFlakes[ nFlake ];
 +
                ctx.fillStyle = 'rgb(' + flake.c[0] + ',' + flake.c[1] + ',' + flake.c[2] + ')';
 +
                ctx.fillRect( flake.x, flake.y, 1, 1 );
 +
            }
 +
 +
            // Draw all tree lights (only during holiday season
 +
            if ( is_winter_holiday() )
 +
            {
 +
                for ( var t = 0; t < treeLights.length; t++ )
 +
                    drawTreeLight( treeLights[t], false );
 +
            }
 +
 +
            // Draw the glowing ACK bit
 +
            ctx.strokeStyle = 'rgb(' + ackbit[0] + ',' + ackbit[1] + ',' + ackbit[2] + ')';
 +
            ctx.shadowColor = 'rgba(' + ackbit[0] + ',' + ackbit[1] + ',' + ackbit[2] + ',' + (0.00130 * ackbit[0] + 0.00196 * ackbit[1] + 0.00063 * ackbit[2]) + ')';
 +
            ctx.globalAlpha = 1;
 +
            ctx.lineWidth = 10;
 +
            ctx.shadowBlur = 70;
 +
            for ( var n = 0; n < 10; n++ )
 +
            {
 +
                ctx.beginPath();
 +
                ctx.rect( 287, 88 + offsetY, 8, 7 );
 +
                ctx.stroke();
 +
            }
 +
 +
            // Draw all tree lights overlay: either on or off
 +
            ctx.shadowBlur = 0;
 +
            // Draw all tree lights (only during holiday season
 +
            if ( is_winter_holiday() )
 +
            {
 +
                for ( var t = 0; t < treeLights.length; t++ )
 +
                    drawTreeLight( treeLights[t], true );
 +
            }
 
         }
 
         }
  
         // Draw all flakes
+
         window.requestAnimationFrame( snowFall );
        ctx.fillStyle = 'white';
+
    }
        ctx.shadowBlur = 0;
 
  
         for ( nFlake = 0; nFlake < snowFlakes.length; nFlake++ )
+
    function getRndColor()
 +
    {
 +
         // Thanks to Adafruit's NeoPixel lib
 +
        var wheelPos = Math.random() * 255 | 0;
 +
        if( wheelPos < 85 )
 
         {
 
         {
             flake = snowFlakes[ nFlake ];
+
             return [ (255 - wheelPos * 2), 85, (85 + wheelPos * 2) ];
            ctx.fillRect( flake.x, flake.y, 1, 1 );
 
 
         }
 
         }
  
         // Draw all tree lights
+
         if( wheelPos < 170 )
         for ( var t = 0; t < treeLights.length; t++ )
+
         {
            drawTreeLight( treeLights[t], false );
+
            wheelPos -= 85;
 +
            return [ 85, (85 + wheelPos * 2), (255 - wheelPos * 2) ];
 +
        }
 +
        wheelPos -= 170;
 +
        return [ (85 + wheelPos * 2), (255 - wheelPos * 2), 85 ];
 +
    }
 +
 
 +
    function drawTreeLight( _treeLight, _glow )
 +
    {
 +
        ctx.strokeStyle = ctx.shadowColor = 'rgb(' + _treeLight.c[0] + ',' + _treeLight.c[1] + ',' + _treeLight.c[2] + ')';
  
         // Draw the glowing ACK bit
+
         if ( !_glow )
        ctx.strokeStyle = ctx.shadowColor = 'red';
 
        ctx.globalAlpha = 1;
 
        ctx.lineWidth = 10;
 
        ctx.shadowBlur = 70;
 
        for ( var n = 0; n < 10; n++ )
 
 
         {
 
         {
 +
            // Draw the light
 +
            ctx.lineWidth = 3;
 +
            ctx.globalAlpha = 1;
 
             ctx.beginPath();
 
             ctx.beginPath();
             ctx.rect( 292, 92 + offsetY, 1, 1 );
+
             ctx.arc( _treeLight.x, _treeLight.y + offsetY, 2, 0, 2 * Math.PI );
 
             ctx.stroke();
 
             ctx.stroke();
 +
        }
 +
        else if ( _treeLight.on )
 +
        {
 +
            // Let it glow!
 +
            ctx.lineWidth = 1;
 +
            for ( var n = 0; n < 20; n++ )
 +
            {
 +
                ctx.globalAlpha = (n / 30) * (0.00130 * _treeLight.c[0] + 0.00196 * _treeLight.c[1] + 0.00063 * _treeLight.c[2]);               
 +
                ctx.beginPath();
 +
                ctx.arc( _treeLight.x, _treeLight.y + offsetY, 22 - n, 0, 2 * Math.PI );
 +
                ctx.stroke();
 +
            }
 +
            ctx.globalAlpha = 1;
 +
        }
 +
        else
 +
        {
 +
            // Add dark 'off' mask
 +
            ctx.strokeStyle = ctx.shadowColor = "rgba( 0,0,0,0.3)";
 +
            ctx.lineWidth = 3;
 +
            ctx.globalAlpha = 1;
 +
            ctx.beginPath();
 +
            ctx.arc( _treeLight.x, _treeLight.y + offsetY, 2, 0, 2 * Math.PI );
 +
            ctx.stroke();
 +
        }
 +
    }
 +
 +
    function updateFlake( _flake, _dynamicImage )
 +
    {
 +
        var newFlake;
 +
 +
        // Check each next possible 'y' pixel, and add it to the list of possibilities
 +
        var possibilities = [];
 +
 +
        // Try three flake possibilities
 +
        for ( var n = -1; n <= 1; n++ )
 +
        {
 +
            newFlake = tryCreateFlake( _flake, n, 1, _dynamicImage );
 +
            if ( newFlake )
 +
                possibilities.push( newFlake );
 
         }
 
         }
  
         // Draw all tree lights overlay: either on or off
+
         if ( !possibilities.length )
         ctx.shadowBlur = 0;
+
         {
        for ( var t = 0; t < treeLights.length; t++ )
+
            newFlake = tryCreateFlake( _flake, -2, 1, _dynamicImage );
             drawTreeLight( treeLights[t], true );
+
            if ( newFlake )
    }
+
                possibilities.push( newFlake );
 +
 
 +
            newFlake = tryCreateFlake( _flake, 2, 1, _dynamicImage );
 +
             if ( newFlake )
 +
                possibilities.push( newFlake );
 +
        }
  
    window.requestAnimationFrame( snowFall );
+
        // No possibilities means, no update: will fixate this flake
}
+
        if ( !possibilities.length )
 +
            return false;
  
function drawTreeLight( _treeLight, _glow )
+
        // Pick a flake
{
+
        var newFlake = possibilities[ ( Math.random( ) * possibilities.length ) | 0 ];
    ctx.strokeStyle = ctx.shadowColor = _treeLight.color;
+
        _flake.x = newFlake.x;
 +
        _flake.y = newFlake.y;
  
    if ( !_glow )
+
         // Flake updated
    {
+
         return true;
         // Draw the light
 
        ctx.lineWidth = 3;
 
        ctx.globalAlpha = 1;
 
        ctx.beginPath();
 
        ctx.arc( _treeLight.x, _treeLight.y + offsetY, 2, 0, 2 * Math.PI );
 
         ctx.stroke();
 
 
     }
 
     }
     else if ( _treeLight.on )
+
 
 +
     function tryCreateFlake( _flake, _x, _y, _dynamicImage )
 
     {
 
     {
         // Let it glow!
+
         // Don't create flake if we're off the bottom of the screen
         ctx.lineWidth = 1;
+
         if ( ( _flake.y + _y ) >= height )
         for ( var n = 0; n < 20; n++ )
+
            return null;
 +
 
 +
        // Don't allow to go off the sides of the screen
 +
         if ( ( _flake.x + _x ) < 0 )
 +
            return null;
 +
 
 +
        if ( ( _flake.x + _x ) >= width )
 +
            return null;
 +
 
 +
        if ( debug )
 
         {
 
         {
             ctx.globalAlpha = n / 30;
+
             // Make sure we're not colliding with other flakes
             ctx.beginPath();
+
             for ( var nFlake = 0; nFlake < snowFlakes.length; ++nFlake )
            ctx.arc( _treeLight.x, _treeLight.y + offsetY, 22 - n, 0, 2 * Math.PI );
+
            {
             ctx.stroke();
+
                var f = snowFlakes[ nFlake ];
 +
                if ( f.x === _x && f.y === _y )
 +
                    return null;
 +
             }
 
         }
 
         }
 +
 +
        var newFlake = { x: _flake.x + _x, y: _flake.y + _y, c: _flake.c };
 +
 +
        // Check the alpha channel (apparently, our logo has opacity < 250)
 +
        if ( _dynamicImage.data[ ( newFlake.x + width * newFlake.y ) * 4 + 3 ] > 220 )
 +
            return null;
 +
 +
        // All test cases valid, return the resulting flake
 +
        return newFlake;
 
     }
 
     }
     else
+
 
 +
     function is_winter()
 
     {
 
     {
         // Add dark 'off' mask
+
         return (new Date( "1 april " + (new Date() ).getFullYear() )).valueOf() > Date.now() || (new Date( "1 december " + (new Date() ).getFullYear() )).valueOf() < Date.now();
        ctx.strokeStyle = ctx.shadowColor = "rgba( 0,0,0,0.3)";
 
        ctx.lineWidth = 3;
 
        ctx.globalAlpha = 1;
 
        ctx.beginPath();
 
        ctx.arc( _treeLight.x, _treeLight.y + offsetY, 2, 0, 2 * Math.PI );
 
        ctx.stroke();
 
 
     }
 
     }
}
 
 
function updateFlake( _flake, _dynamicImage )
 
{
 
    var newFlake;
 
 
    // Check each next possible 'y' pixel, and add it to the list of possibilities
 
    var possibilities = [];
 
  
     // Try three flake possibilities
+
     function is_winter_holiday()
    for ( var n = -1; n <= 1; n++ )
 
 
     {
 
     {
         newFlake = tryCreateFlake( _flake, n, 1, _dynamicImage );
+
         return (new Date( "7 january " + (new Date() ).getFullYear() )).valueOf() > Date.now() || (new Date( "7 december " + (new Date() ).getFullYear() )).valueOf() < Date.now();
        if ( newFlake )
 
            possibilities.push( newFlake );
 
 
     }
 
     }
  
     // No possibilities means, no update: will fixate this flake
+
     function window_load()
     if ( !possibilities.length )
+
     {
         return false;
+
        var logo = document.getElementById( "logo" );
 +
         ctx = logo.getContext("2d");
  
    // Pick a flake
+
        buffer = document.createElement('canvas');
    var newFlake = possibilities[ ( Math.random( ) * possibilities.length ) | 0 ];
+
        buffer.width = logo.width;
    _flake.x = newFlake.x;
+
        buffer.height = logo.height;
    _flake.y = newFlake.y;
+
        bufferContext = buffer.getContext('2d');
  
    // Flake updated
+
        var img = document.getElementById("img");
    return true;
+
        ctx.drawImage( img, 0, offsetY );
}
 
  
function tryCreateFlake( _flake, _x, _y, _dynamicImage )
+
        bufferContext.drawImage( img, 0, offsetY );
{
+
        bufferContext.fillStyle = 'white';
    // Don't create flake if we're off the bottom of the screen
+
        bufferContext.shadowBlur = 0;
    if ( ( _flake.y + _y ) >= height )
 
        return null;
 
  
    // Don't allow to go off the sides of the screen
+
        width = logo.width;
    if ( ( _flake.x + _x ) < 0 )
+
        height = logo.height;
        return null;
+
        dynamicImage = ctx.getImageData( 0, 0, width, height );
 +
        if ( debug )
 +
        {
 +
            console && console.log( "winter:", is_winter() );
 +
            console && console.log( "winter holiday:", is_winter_holiday() );
 +
            window.snowBump = function( _n )
 +
            {
 +
                for (;--_n;)
 +
                    snowFlakes.push( { x: ( Math.random( ) * width ) | 0, y: 0, c:[255,255,255] } );
 +
            };
  
    if ( ( _flake.x + _x ) >= width )
+
            logo.addEventListener( "touchdown", function(e){ e.preventDefault(); e.stopPropagation(); }, { passive: false });
        return null;
+
            logo.addEventListener( "touchmove", function(e){ e.preventDefault(); e.stopPropagation(); }, { passive: false });
 +
            logo.addEventListener( "mousemove", function( _event )
 +
            {
 +
                if ( _event.buttons !== 1 || _event.which !== 1 )
 +
                    return;
  
    var newFlake = { "x" : _flake.x + _x, "y" : _flake.y + _y };
+
                if ( window.x === null )
 +
                {
 +
                    window.x = _event.offsetX;
 +
                    window.y = _event.offsetY;
 +
                }
  
    // Check the alpha channel (apparently, our logo has opacity < 250)
+
                // horizontal?
    if ( _dynamicImage.data[ ( newFlake.x + width * newFlake.y ) * 4 + 3 ] > 220 )
+
                if ( Math.abs(window.x - _event.offsetX) > Math.abs(window.y - _event.offsetY) )
         return null;
+
                {
 +
                    var yInc = (_event.offsetY - window.y) / Math.abs(window.x - _event.offsetX);
 +
                    for ( ; window.x !== _event.offsetX; window.x += (_event.offsetX > window.x ? 1 : -1) )
 +
                    {
 +
                        window.y += yInc;
 +
                        drawSnow( window.x, Math.round( window.y ) )
 +
                    }
 +
                    window.y = Math.round( window.y );
 +
                }
 +
                else
 +
                {
 +
                    var xInc = (_event.offsetX - window.x) / Math.abs(window.y - _event.offsetY);
 +
                    for ( ; window.y !== _event.offsetY; window.y += (_event.offsetY > window.y ? 1 : -1) )
 +
                    {
 +
                        window.x += xInc;
 +
                        drawSnow( Math.round( window.x ), window.y )
 +
                    }
 +
                    window.x = Math.round( window.x );
 +
                }
 +
            }, false );
 +
         }
  
    // All test cases valid, return the resulting flake
+
        if ( is_winter() )
     return newFlake;
+
        {
}
+
            window.requestAnimationFrame( snowFall );
 +
            timer = setInterval( blink, 1500 );
 +
        }
 +
     }
  
     var logo = document.getElementById( "logo" );
+
     function drawSnow( _x, _y )
     ctx = logo.getContext("2d");
+
     {
    var img = document.getElementById("img");
+
        if ( dynamicImage.data[ ( _x + width * _y ) * 4 + 0 ] === 255
    ctx.drawImage( img, 0, offsetY );
+
          && dynamicImage.data[ ( _x + width * _y ) * 4 + 1 ] === 255
    width = logo.width;
+
          && dynamicImage.data[ ( _x + width * _y ) * 4 + 2 ] === 255
    height = logo.height;
+
          && dynamicImage.data[ ( _x + width * _y ) * 4 + 3 ] === 254 )
    dynamicImage = ctx.getImageData( 0, 0, width, height );
+
        {
    window.requestAnimationFrame( snowFall );
+
            dynamicImage.data[ ( _x + width * _y ) * 4 + 2 ] = 0;
     setInterval( blink, 1500 );
+
            dynamicImage.data[ ( _x + width * _y ) * 4 + 3 ] = 220;
 +
        }
 +
     }
  
 +
    document.addEventListener("data", function( e )
 +
    {
 +
        if ( timer )
 +
        {
 +
            clearInterval( timer );
 +
            timer = null;
 +
        }
  
//<!--{$url|validate:url}-->
+
        if ( !e.detail || !e.detail.length )
 +
          return;
 +
        var d = e.detail;
 +
        var l = d.length;
 +
        var m = treeLights.length;
 +
        var o = 74;
 +
        for ( var n=0; n < m; ++n )
 +
        {
 +
            treeLights[n].c = d.slice(3*(n+o),3+3*(n+o));
 +
            treeLights[n].on = true;
 +
        }
 +
        m = (m+o)*3;
 +
        if ( l > m )
 +
            ackbit = d.slice(m,m+=3);
 +
        if ( debug && l == 255 )
 +
            snow = d.slice(252,255);
 +
    });
  
 +
    window.addEventListener( "load", window_load, false );
 +
    window.x = window.y = null;
 
}( ));
 
}( ));
 
</script>
 
</script>
<canvas id="" width="<!--{$width|escape:html|default:auto}-->" height="<!--{$height|escape:html|default:auto}-->" style="float:<!--{$float|escape:html|default:none}-->"></canvas>
 
 
</includeonly>
 
</includeonly>

Latest revision as of 14:24, 28 November 2021

This widget creates an animated themed ACKspace logo.

Created by xopr

Using this widget

To insert this widget, use the following code:

{{#widget:Logo
|image=/w/images/e/e9/ACKsmass_logo.png
|width=600px
|height=200px
|padding=8px
|float=right
}}

This will give the following result:

Notes

  • it will display snow in December - March and will show Christmas lights between 7 December and 7 January
  • image is mandatory, the rest is optional.
    it also must be written without protocol since colon (:) is not allowed, and may be relative, for example: //ackspace.nl/w/images/e/e9/ACKsmass_logo.png or /w/images/e/e9/ACKsmass_logo.png
  • You must provide a unit for the sizes (i.e. px, %, etc.)

Also note that there is a chain of browser extensions and apps within the espixelflut github repo:

Note that if you want to use the LED sleeve python code from bitlair, you have to provide a different listening port to avoid conflicts, like this: ./fire2.py port=0 addr='[("127.0.0.1",6454)]'

Copy to your site

To use this widget on your site, just install MediaWiki Widgets extension and copy full source code of this page to your wiki as Widget:Logo article.