diff --git a/POC/ts/examples/fire.ts b/POC/ts/examples/fire.ts new file mode 100644 index 0000000..fc5e005 --- /dev/null +++ b/POC/ts/examples/fire.ts @@ -0,0 +1,177 @@ +import { Keyboard, KeyInfo, ChannelState } from "../../../src"; +import { allColor } from "./all-color"; + +function shuffle(array: any): any { + var currentIndex = array.length, temporaryValue, randomIndex; + while (0 !== currentIndex) { + randomIndex = Math.floor(Math.random() * currentIndex); + currentIndex -= 1; + temporaryValue = array[currentIndex]; + array[currentIndex] = array[randomIndex]; + array[randomIndex] = temporaryValue; + } + return array; +} + +function rangeBetween(startNo:number, endNo:number) { + var rangeArray = []; + if (startNo > endNo) { + for (var i = startNo; i >= endNo; i--) { + rangeArray.push(i); + } + } else { + for (var i = startNo; i <= endNo; i++) { + rangeArray.push(i); + } + } + return rangeArray; +} + +export function fire(keyboard: Keyboard, region: string) { + + if (region == 'uk') { + var ki = Object.keys(KeyInfo["en-GB"]); + } else { + var ki = Object.keys(KeyInfo["en-US"]); + } + + // hand picked flame colours, from base to top + var colorArray = [ + "194,99,15", + "213,57,11", + "255,47,10", + "98,20,9", + "35,12,9", + "10,10,10", + "6,6,6" + ]; + + allColor(keyboard, "#FF2F0A"); // light furnace + + let baseRow = rangeBetween(145,166); + shuffle(baseRow); + type channel = "red" | "green" | "blue"; + let baseRed: number = 0; + let baseGreen: number = 0; + let baseBlue: number = 0; + let highRed: number = 255; + let highGreen: number = 255; + let highBlue: number = 255; + let redRange: number = 0; + let greenRange: number = 0; + let blueRange: number = 0; + let maxLevel: number = 255; + let minLevel: number = 0; + let increment: number = 1; + let incDelay: number = 1; + let currentRow = 0; + let maxDiff: number = 0; + let delay: number = 0; + + while (baseRow.length > 0) { // loop through bottom row of keys + let downHoldDelay = Math.floor(Math.random()*25+10); // realistic + let upHoldDelay = Math.floor(Math.random()*110+30); // realistic + // let downHoldDelay = Math.floor(Math.random()*75+50); // relaxing + // let upHoldDelay = Math.floor(Math.random()*550+200); // relaxing + let startKey = baseRow.pop(); + currentRow = 0; + delay = 0; // reset delay so we start with a flare of fire + while((startKey != undefined)&&(startKey >= 25)) { // loop up keyboard from bottom key (set column of keys) + var test = 0; + maxDiff = 0; + for (var i = ki.length - 1; i >= 0; i--) { + if (KeyInfo["en-GB"][ki[i]].ledIds[0].id == startKey) { + var test = i; + break; + } + } + var baseColour = colorArray[currentRow].split(','); + // console.log(baseColour); + baseRed = Number(baseColour[0]); + baseGreen = Number(baseColour[1]); + baseBlue = Number(baseColour[2]); + + currentRow++; // each key takes a base colour (current row of colorarray), then we increment and take the row above for the alt colour, the key then cycles between them + + var highColour = colorArray[currentRow].split(','); + // console.log(highColour); + highRed = Number(highColour[0]); + highGreen = Number(highColour[1]); + highBlue = Number(highColour[2]); + + // this code calcs which channel has the biggest change + if (highRed > baseRed ) { + redRange = highRed - baseRed; + } else { + redRange = baseRed - highRed; + } + maxDiff = redRange; + + if (highGreen > baseGreen ) { + greenRange = highGreen - baseGreen; + } else { + greenRange = baseGreen - highGreen; + } + if (greenRange > maxDiff) { + maxDiff = greenRange; + } + + if (highBlue > baseBlue ) { + blueRange = highBlue - baseBlue; + } else { + blueRange = baseBlue - highBlue; + } + if (blueRange > maxDiff) { + maxDiff = blueRange; + } + + if (test > 0) { // only apply if key exists + var key = KeyInfo["en-GB"][ki[i]]; + for (var chan = 0; chan < 3; chan++) { + + let chanName: channel = "red"; + // this code sets the colour values for the appropriate channel and adds incrementdelays to channels with smaller changes. + if (chan == 1) { + chanName = "green"; + maxLevel = highGreen; + minLevel = baseGreen; + incDelay = Math.round(maxDiff/greenRange); // this is sloppy, I feel that it should still go out of sync without remainders being accounted for but for some reason it works fine? + } else if (chan == 2) { + chanName = "blue"; + maxLevel = highBlue; + minLevel = baseBlue; + incDelay = Math.round(maxDiff/blueRange); + } else { + maxLevel = highRed; + minLevel = baseRed; + incDelay = Math.round(maxDiff/redRange); + } + + if (incDelay == Infinity) { // difference can be zero + incDelay = 0; + } + + keyboard.setKeyColorChannel(new ChannelState(key, chanName) + .setUpHoldLevel(maxLevel) + .setUpMaximumLevel(maxLevel) + .setDownHoldLevel(minLevel) + .setDownMinimumLevel(minLevel) + .setUpIncrement(increment) + .setUpIncrementDelay(incDelay) + .setDownDecrement(increment) + .setDownDecrementDelay(incDelay) + .setUpHoldDelay(upHoldDelay) + .setDownHoldDelay(downHoldDelay) + .setStartDelay(delay) + .setTransition(true) + .setDecrementIncrement() + .setApplyDelayed() + ) + } + } + startKey -= 24; // key above current key + delay += 1; // flame rise rate + } + } + console.log('flame on'); +} diff --git a/POC/ts/examples/matrix.ts b/POC/ts/examples/matrix.ts new file mode 100644 index 0000000..8f52f08 --- /dev/null +++ b/POC/ts/examples/matrix.ts @@ -0,0 +1,121 @@ +import { Keyboard, KeyInfo, KeyState } from "../../../src"; +import { allColor } from "./all-color"; + +function shuffle(array: any): any { + var currentIndex = array.length, temporaryValue, randomIndex; + while (0 !== currentIndex) { + randomIndex = Math.floor(Math.random() * currentIndex); + currentIndex -= 1; + temporaryValue = array[currentIndex]; + array[currentIndex] = array[randomIndex]; + array[randomIndex] = temporaryValue; + } + return array; +} + +export function matrix(keyboard: Keyboard, region: string) { + + if (region == 'uk') { + var ki = Object.keys(KeyInfo["en-GB"]); + } else { + var ki = Object.keys(KeyInfo["en-US"]); + } + + var color = 'green'; + + switch (color) { + case "red": { + var to_color = "#FF0000"; + var from_color = "#080000"; + break; + } + + case 'blue': { + var to_color = "#0000FF"; + var from_color = "#000008"; + break; + } + + case 'pink': { + var to_color = "#FF00FF"; + var from_color = "#080008"; + break; + } + + case 'teal': { + var to_color = "#00FFFF"; + var from_color = "#000808"; + break; + } + + case 'yellow': { + var to_color = "#FFFF00"; + var from_color = "#080800"; + break; + } + + case 'lights': { + var to_color = "#FF8000"; + var from_color = "#080400"; + break; + } + + default: { + var to_color = "#00FF00"; + var from_color = "#000800"; + break; + } + } + + allColor(keyboard, from_color); + + var topRow = [0,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,71]; // top row id's + pipes + shuffle(topRow); + var masterdelay = 0; + while (topRow.length > 0) { + var delay = Math.floor(Math.random()*500+5) + masterdelay; + var multiplyer_A = Math.floor(Math.random()*5+1); + var multiplyer_B = Math.floor(Math.random()*5+1); + var multiplyer_C = Math.floor(Math.random()*5+1); + var multiplyer_D = Math.floor(Math.random()*50+1); + var startKey = topRow.pop(); + + // console.log('startKey:', startKey); + + while((startKey != undefined)&&(startKey < 216)) { // top left pipe is id 0 and typescript doesn't like that + + var test = 0; + for (var i = ki.length - 1; i >= 0; i--) { // ideally this would be cached ID => ki[?], but i'm sick of fighting ts + if (KeyInfo["en-GB"][ki[i]].ledIds[0].id == startKey) { + var test = i; + // console.log(test); + break; + } + } + if (test > 0) { // only apply if key exists + var key = KeyInfo["en-GB"][ki[i]]; + keyboard.setKeyState(new KeyState(key) + .setToColorHex(to_color) + .setFromColorHex(from_color) + .setDownMinimum(from_color) + .setUpIncrement(20 * multiplyer_A) + .setUpIncrementDelay(10 * multiplyer_B) + .setDownDecrement(5 * multiplyer_C) + .setDownDecrementDelay(1 * multiplyer_C) + .setUpHoldDelay(70) + .setDownHoldDelay(350) + .setStartDelay(delay) + .setTransitionReverse() + .setApplyDelayed() + ) + + } + startKey += 24; // key below current key + delay += 15; // fall rate + + } + // console.log('new key'); + masterdelay += 50; + } +} +console.log('started, note lots of long delays at the start for randomness') \ No newline at end of file diff --git a/POC/ts/examples/rainbow.ts b/POC/ts/examples/rainbow.ts new file mode 100644 index 0000000..2c7045e --- /dev/null +++ b/POC/ts/examples/rainbow.ts @@ -0,0 +1,131 @@ +import { Keyboard, KeyInfo, ChannelState } from "../../../src"; +import { allColor } from "./all-color"; + +// function range(size:number, startAt:number = 0):ReadonlyArray { +// return [...Array(size).keys()].map(i => i + startAt); +// } + +function rangeBetween(startNo:number, endNo:number) { + var rangeArray = []; + if (startNo > endNo) { + for (var i = startNo; i >= endNo; i--) { + rangeArray.push(i); + } + } else { + for (var i = startNo; i <= endNo; i++) { + rangeArray.push(i); + } + } + return rangeArray; +} + +export function rainbow(keyboard: Keyboard, region: string) { + + allColor(keyboard, "#000000"); // blackout keyboard + var multiplier = 25; // delay between rows + var maxLevel = 255; // channel goes to full brightness (note using more than 255 will work but spill over into brightness: breaking the brightness key at some level) + var minLevel = 0; // channel goes fully off + var increment = 1; // increment step up and down + var incDelay = 0; // hold time for each increment step + var holdfor = 255; // hold time at max/min levels + + // these values can be changed but have to sync up + // pattern = DOWN(for 255) -(255 transition)-> UP(for 255) -(255 transition)-> DOWN etc + // = 255 * 4 = 1020 (cycle time) + // 1024 / 3 = 340 (channel delay offset) + // if your (DOWN + GOING UP + UP + GOING DOWN) doesn't cleanly divide by 3 (RGB Channels) it will go out of sync and the colours will cycle unpredictably + + if (region == 'uk') { + var ki = Object.keys(KeyInfo["en-GB"]); + } else { + var ki = Object.keys(KeyInfo["en-US"]); + } + + var Lookup = []; + for (var i = 0; i < 215; i++) { + Lookup.push(215); + } + for (var i = ki.length - 1; i >= 0; i--) { // cache led_ID => ki[?] + let temp = KeyInfo["en-GB"][ki[i]].ledIds[0].id + Lookup[temp] = i; + } + // console.log(Lookup); + + var target_array = []; + var row = []; + var startDelay = 0; + + // array of led_IDs for each row + row.push(rangeBetween(145,166)); // row 0, contains spacebar + row.push(rangeBetween(121,142)); // row 1 + row.push(rangeBetween(97,118)); // row 2 + row.push(rangeBetween(73,94)); // row 3 + row.push(rangeBetween(49,70)); // row 4 + // row.push(rangeBetween(25,42)); // row 5 minus media keys and Q knob + row.push(rangeBetween(18,47)); // row 5 with media and Q knob + + // add lighpipes to row 5 + var leftPipe = [0, 24, 48, 72, 96, 120, 144, 168, 192]; + var rightPipe = [71, 95, 119, 143, 167, 191, 215]; + type channel = "red" | "green" | "blue"; + for (var i = leftPipe.length - 1; i >= 0; i--) { + row[5].push(leftPipe[i]); + } + for (var i = rightPipe.length - 1; i >= 0; i--) { + row[5].push(rightPipe[i]); + } + + // set up rows, bottom to top + for (var i = 0; i < row.length; i++) { + target_array.push(row[i]); + } + + // uncomment next line if you want animation to flow down keyboard instead of up + // target_array.reverse(); + + for (var index = 0; index < target_array.length; index++) { + // console.log('row: ', index); + var key_array = target_array[index]; + + for (var this_key = 0; this_key < key_array.length; this_key++) { + var target_key = key_array[this_key]; + // console.log("target_key: ", target_key); + var test = Lookup[target_key]; + if (test < 215) { // 215 means the key doesn't exist in culture code + // console.log(test); + var key = KeyInfo["en-GB"][ki[test]]; + if (key) { // only apply if key exists + // console.log("key: ", key); + for (var chan = 0; chan < 3; chan++) { + var delay = (340 * chan) + (index * multiplier); // delay offsets the channels + let chanName: channel = "red"; + if (chan == 1) { + chanName = "green"; + } else if (chan == 2) { + chanName = "blue"; + } + + keyboard.setKeyColorChannel(new ChannelState(key, chanName) + .setUpHoldLevel(maxLevel) + .setUpMaximumLevel(maxLevel) + .setDownHoldLevel(minLevel) + .setDownMinimumLevel(minLevel) + .setUpIncrement(increment) + .setUpIncrementDelay(incDelay) + .setDownDecrement(increment) + .setDownDecrementDelay(incDelay) + .setUpHoldDelay(holdfor) + .setDownHoldDelay(holdfor) + .setStartDelay(delay) + .setTransition(true) + .setDecrementIncrement() + // .enableTransition() + .setApplyDelayed() + ) + } + } + } + } + } + console.log('warming up keyboard...'); +} diff --git a/POC/ts/examples/xmas.ts b/POC/ts/examples/xmas.ts new file mode 100644 index 0000000..cc510bd --- /dev/null +++ b/POC/ts/examples/xmas.ts @@ -0,0 +1,52 @@ +import { Keyboard, KeyInfo, KeyState } from "../../../src"; +import { allColor } from "./all-color"; + +function shuffle(array: any): any { + var currentIndex = array.length, temporaryValue, randomIndex; + while (0 !== currentIndex) { + randomIndex = Math.floor(Math.random() * currentIndex); + currentIndex -= 1; + temporaryValue = array[currentIndex]; + array[currentIndex] = array[randomIndex]; + array[randomIndex] = temporaryValue; + } + return array; +} + +export function xmas(keyboard: Keyboard, region: string) { + // xmas lights, exploits firmware stupidity to cycle through unspecified colours + allColor(keyboard, "#000000"); + + if (region == 'uk') { + var ki = Object.keys(KeyInfo["en-GB"]); + } else { + var ki = Object.keys(KeyInfo["en-US"]); + } + + ki = shuffle(ki); + + var startDelay = 20; + + for (var i = 0; i < ki.length; i++) { + if (region == 'uk') { + var key = KeyInfo["en-GB"][ki[i]]; + } else { + var key = KeyInfo["en-US"][ki[i]]; + } + + keyboard.setKeyState(new KeyState(key) + .setToColorHex("#FF1010") + .setFromColorHex("#00FF00") + .setUpMaximum("#FF0000") + .setUpIncrement(50) + .setUpIncrementDelay(10) + .setDownDecrement(50) + .setDownDecrementDelay(5) + .setUpHoldDelay(250) + .setDownHoldDelay(250) + .setStartDelay(startDelay * i) + .setTransitionReverse() + .setApplyDelayed() + ); + } +} diff --git a/src/channel-state.ts b/src/channel-state.ts index 8722e4d..2617eb8 100644 --- a/src/channel-state.ts +++ b/src/channel-state.ts @@ -174,4 +174,4 @@ export class ChannelState { } -} +} \ No newline at end of file