Difference between revisions of "Widget:Logo"
(update font size + color) |
m (now ''really'' centered it) |
||
(39 intermediate revisions by the same user not shown) | |||
Line 24: | Line 24: | ||
}}<br/> | }}<br/> | ||
'''Notes''' | '''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. | * '''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'' | *: 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.) | * 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 == | ||
Line 38: | Line 47: | ||
"use strict"; | "use strict"; | ||
+ | var timer = null; | ||
var start = null; | var start = null; | ||
var oldTimestamp = null; | var oldTimestamp = null; | ||
Line 66: | Line 76: | ||
var nToggle = 0; | var nToggle = 0; | ||
var treeLights = [ | var treeLights = [ | ||
− | { | + | { 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 oldTimestamp = null; | var oldTimestamp = null; | ||
Line 82: | Line 94: | ||
if ( ( progress / 500 ) > snowFlakes.length && ( _timestamp - oldTimestamp < 50 ) ) | if ( ( progress / 500 ) > snowFlakes.length && ( _timestamp - oldTimestamp < 50 ) ) | ||
− | snowFlakes.push( { | + | snowFlakes.push( { x: ( Math.random( ) * width ) | 0, y: 0, c:snow.slice() } ); |
oldTimestamp = _timestamp; | oldTimestamp = _timestamp; | ||
Line 110: | Line 122: | ||
dynamicImage.data[ pixelPos + 1 ] = flake.c[1]; | dynamicImage.data[ pixelPos + 1 ] = flake.c[1]; | ||
dynamicImage.data[ pixelPos + 2 ] = flake.c[2]; | dynamicImage.data[ pixelPos + 2 ] = flake.c[2]; | ||
− | dynamicImage.data[ pixelPos + 3 ] = | + | dynamicImage.data[ pixelPos + 3 ] = 254; |
// Generate new flake | // Generate new flake | ||
− | flake = { | + | flake = { x: ( Math.random( ) * width ) | 0, y: 0, c:snow.slice() }; |
} | } | ||
Line 145: | Line 157: | ||
// Draw the glowing ACK bit | // Draw the glowing ACK bit | ||
− | ctx.strokeStyle = ctx.shadowColor = ' | + | 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.globalAlpha = 1; | ||
ctx.lineWidth = 10; | ctx.lineWidth = 10; | ||
Line 152: | Line 165: | ||
{ | { | ||
ctx.beginPath(); | ctx.beginPath(); | ||
− | ctx.rect( | + | ctx.rect( 287, 88 + offsetY, 8, 7 ); |
ctx.stroke(); | ctx.stroke(); | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
Line 185: | Line 188: | ||
if( wheelPos < 85 ) | if( wheelPos < 85 ) | ||
{ | { | ||
− | return [ (255 - wheelPos * | + | return [ (255 - wheelPos * 2), 85, (85 + wheelPos * 2) ]; |
} | } | ||
Line 191: | Line 194: | ||
{ | { | ||
wheelPos -= 85; | wheelPos -= 85; | ||
− | return [ | + | return [ 85, (85 + wheelPos * 2), (255 - wheelPos * 2) ]; |
} | } | ||
wheelPos -= 170; | wheelPos -= 170; | ||
− | return [ (wheelPos * | + | return [ (85 + wheelPos * 2), (255 - wheelPos * 2), 85 ]; |
} | } | ||
function drawTreeLight( _treeLight, _glow ) | function drawTreeLight( _treeLight, _glow ) | ||
{ | { | ||
− | ctx.strokeStyle = ctx.shadowColor = _treeLight. | + | ctx.strokeStyle = ctx.shadowColor = 'rgb(' + _treeLight.c[0] + ',' + _treeLight.c[1] + ',' + _treeLight.c[2] + ')'; |
if ( !_glow ) | if ( !_glow ) | ||
Line 216: | Line 219: | ||
for ( var n = 0; n < 20; n++ ) | for ( var n = 0; n < 20; n++ ) | ||
{ | { | ||
− | ctx.globalAlpha = n / 30; | + | ctx.globalAlpha = (n / 30) * (0.00130 * _treeLight.c[0] + 0.00196 * _treeLight.c[1] + 0.00063 * _treeLight.c[2]); |
ctx.beginPath(); | ctx.beginPath(); | ||
ctx.arc( _treeLight.x, _treeLight.y + offsetY, 22 - n, 0, 2 * Math.PI ); | ctx.arc( _treeLight.x, _treeLight.y + offsetY, 22 - n, 0, 2 * Math.PI ); | ||
ctx.stroke(); | ctx.stroke(); | ||
} | } | ||
+ | ctx.globalAlpha = 1; | ||
} | } | ||
else | else | ||
Line 286: | Line 290: | ||
return null; | return null; | ||
− | var newFlake = { | + | if ( debug ) |
+ | { | ||
+ | // Make sure we're not colliding with other flakes | ||
+ | for ( var nFlake = 0; nFlake < snowFlakes.length; ++nFlake ) | ||
+ | { | ||
+ | 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) | // Check the alpha channel (apparently, our logo has opacity < 250) | ||
Line 308: | Line 323: | ||
function window_load() | function window_load() | ||
{ | { | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
var logo = document.getElementById( "logo" ); | var logo = document.getElementById( "logo" ); | ||
ctx = logo.getContext("2d"); | ctx = logo.getContext("2d"); | ||
Line 332: | Line 341: | ||
height = logo.height; | height = logo.height; | ||
dynamicImage = ctx.getImageData( 0, 0, width, height ); | 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] } ); | ||
+ | }; | ||
+ | |||
+ | logo.addEventListener( "touchdown", function(e){ e.preventDefault(); e.stopPropagation(); }, { passive: false }); | ||
+ | logo.addEventListener( "touchmove", function(e){ e.preventDefault(); e.stopPropagation(); }, { passive: false }); | ||
+ | logo.addEventListener( "mousemove", function( _event ) | ||
+ | { | ||
+ | if ( _event.buttons !== 1 || _event.which !== 1 ) | ||
+ | return; | ||
+ | |||
+ | if ( window.x === null ) | ||
+ | { | ||
+ | window.x = _event.offsetX; | ||
+ | window.y = _event.offsetY; | ||
+ | } | ||
+ | |||
+ | // horizontal? | ||
+ | if ( Math.abs(window.x - _event.offsetX) > Math.abs(window.y - _event.offsetY) ) | ||
+ | { | ||
+ | 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 ); | ||
+ | } | ||
+ | |||
if ( is_winter() ) | if ( is_winter() ) | ||
{ | { | ||
window.requestAnimationFrame( snowFall ); | window.requestAnimationFrame( snowFall ); | ||
− | setInterval( blink, 1500 ); | + | timer = setInterval( blink, 1500 ); |
} | } | ||
} | } | ||
+ | |||
+ | function drawSnow( _x, _y ) | ||
+ | { | ||
+ | if ( dynamicImage.data[ ( _x + width * _y ) * 4 + 0 ] === 255 | ||
+ | && dynamicImage.data[ ( _x + width * _y ) * 4 + 1 ] === 255 | ||
+ | && dynamicImage.data[ ( _x + width * _y ) * 4 + 2 ] === 255 | ||
+ | && dynamicImage.data[ ( _x + width * _y ) * 4 + 3 ] === 254 ) | ||
+ | { | ||
+ | dynamicImage.data[ ( _x + width * _y ) * 4 + 2 ] = 0; | ||
+ | dynamicImage.data[ ( _x + width * _y ) * 4 + 3 ] = 220; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | document.addEventListener("data", function( e ) | ||
+ | { | ||
+ | if ( timer ) | ||
+ | { | ||
+ | clearInterval( timer ); | ||
+ | timer = null; | ||
+ | } | ||
+ | |||
+ | 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.addEventListener( "load", window_load, false ); | ||
+ | window.x = window.y = null; | ||
}( )); | }( )); | ||
</script> | </script> | ||
</includeonly> | </includeonly> |
Latest revision as of 13: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:
- FlutLogo app connector extension.crx: the extension that listens to the UDP connector app and drives the logo "LEDs" (source available, but it needs a static ID for the connector app)
- FlutLogo UDP connector app the app that listens to UDP ART-net packets and connects to the browser extension
- 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 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.