Merge pull request #1235 from daslyfe/orgin/daslyfe/keydown

Add onKey function for custom key commands for patterns
This commit is contained in:
Jade (Rose) Rowland 2025-01-14 00:11:10 -05:00 committed by GitHub
commit c5de21ef61
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 117 additions and 1 deletions

View File

@ -138,6 +138,18 @@ pnpm --filter "./packages/**" publish --access public
To manually publish a single package, increase the version in the `package.json`, then run `pnpm publish`. To manually publish a single package, increase the version in the `package.json`, then run `pnpm publish`.
Important: Always publish with `pnpm`, as `npm` does not support overriding main files in `publishConfig`, which is done in all the packages. Important: Always publish with `pnpm`, as `npm` does not support overriding main files in `publishConfig`, which is done in all the packages.
## useful commands
```sh
#regenerate the test snapshots (ex: when updating or creating new pattern functions)
pnpm snapshot
#start the OSC server
pnpm run osc
#build the standalone version
pnpm tauri build
```
## Have Fun ## Have Fun
Remember to have fun, and that this project is driven by the passion of volunteers! Remember to have fun, and that this project is driven by the passion of volunteers!

View File

@ -7,7 +7,8 @@ This program is free software: you can redistribute it and/or modify it under th
import { Hap } from './hap.mjs'; import { Hap } from './hap.mjs';
import { Pattern, fastcat, reify, silence, stack, register } from './pattern.mjs'; import { Pattern, fastcat, reify, silence, stack, register } from './pattern.mjs';
import Fraction from './fraction.mjs'; import Fraction from './fraction.mjs';
import { id, _mod } from './util.mjs';
import { id, keyAlias, getCurrentKeyboardState } from './util.mjs';
export function steady(value) { export function steady(value) {
// A continuous value // A continuous value
@ -639,3 +640,48 @@ export const never = register('never', function (_, pat) {
export const always = register('always', function (func, pat) { export const always = register('always', function (func, pat) {
return func(pat); return func(pat);
}); });
//keyname: string | Array<string>
//keyname reference: https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values
export function _keyDown(keyname) {
if (Array.isArray(keyname) === false) {
keyname = [keyname];
}
const keyState = getCurrentKeyboardState();
return keyname.every((x) => {
const keyName = keyAlias.get(x) ?? x;
return keyState[keyName];
});
}
/**
*
* Do something on a keypress, or array of keypresses
* [Key name reference](https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values)
*
* @name whenKey
* @memberof Pattern
* @returns Pattern
* @example
* s("bd(5,8)").whenKey("Control:j", x => x.segment(16).color("red")).whenKey("Control:i", x => x.fast(2).color("blue"))
*/
export const whenKey = register('whenKey', function (input, func, pat) {
return pat.when(_keyDown(input), func);
});
/**
*
* returns true when a key or array of keys is held
* [Key name reference](https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values)
*
* @name keyDown
* @memberof Pattern
* @returns Pattern
* @example
* keyDown("Control:j").pick([s("bd(5,8)"), s("cp(3,8)")])
*/
export const keyDown = register('keyDown', function (pat) {
return pat.fmap(_keyDown);
});

View File

@ -434,6 +434,38 @@ function getUnixTimeSeconds() {
return Date.now() * 0.001; return Date.now() * 0.001;
} }
export const keyAlias = new Map([
['control', 'Control'],
['ctrl', 'Control'],
['alt', 'Alt'],
['shift', 'Shift'],
['down', 'ArrowDown'],
['up', 'ArrowUp'],
['left', 'ArrowLeft'],
['right', 'ArrowRight'],
]);
let keyState;
export function getCurrentKeyboardState() {
if (keyState == null) {
if (typeof window === 'undefined') {
return;
}
keyState = {};
// Listen for the keydown event to mark the key as pressed
window.addEventListener('keydown', (event) => {
keyState[event.key] = true; // Mark the key as pressed
});
// Listen for the keyup event to mark the key as released
window.addEventListener('keyup', (event) => {
keyState[event.key] = false; // Mark the key as released
});
}
return { ...keyState }; // Return a shallow copy of the key state object
}
// Floating point versions, see Fraction for rational versions // Floating point versions, see Fraction for rational versions
// // greatest common divisor // // greatest common divisor
// export const gcd = function (x, y, ...z) { // export const gcd = function (x, y, ...z) {

22
pnpm-lock.yaml generated
View File

@ -331,6 +331,19 @@ importers:
specifier: ^2.1.3 specifier: ^2.1.3
version: 2.1.3(@types/node@22.7.6)(@vitest/ui@2.1.3)(terser@5.36.0) version: 2.1.3(@types/node@22.7.6)(@vitest/ui@2.1.3)(terser@5.36.0)
packages/mqtt:
dependencies:
'@strudel/core':
specifier: workspace:*
version: link:../core
paho-mqtt:
specifier: ^1.1.0
version: 1.1.0
devDependencies:
vite:
specifier: ^5.0.10
version: 5.4.9(@types/node@22.7.6)(terser@5.36.0)
packages/osc: packages/osc:
dependencies: dependencies:
'@strudel/core': '@strudel/core':
@ -623,6 +636,9 @@ importers:
'@strudel/mini': '@strudel/mini':
specifier: workspace:* specifier: workspace:*
version: link:../packages/mini version: link:../packages/mini
'@strudel/mqtt':
specifier: workspace:*
version: link:../packages/mqtt
'@strudel/osc': '@strudel/osc':
specifier: workspace:* specifier: workspace:*
version: link:../packages/osc version: link:../packages/osc
@ -5991,6 +6007,9 @@ packages:
engines: {node: ^16.14.0 || >=18.0.0} engines: {node: ^16.14.0 || >=18.0.0}
hasBin: true hasBin: true
paho-mqtt@1.1.0:
resolution: {integrity: sha512-KPbL9KAB0ASvhSDbOrZBaccXS+/s7/LIofbPyERww8hM5Ko71GUJQ6Nmg0BWqj8phAIT8zdf/Sd/RftHU9i2HA==}
parent-module@1.0.1: parent-module@1.0.1:
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
engines: {node: '>=6'} engines: {node: '>=6'}
@ -7740,6 +7759,7 @@ packages:
workbox-google-analytics@7.0.0: workbox-google-analytics@7.0.0:
resolution: {integrity: sha512-MEYM1JTn/qiC3DbpvP2BVhyIH+dV/5BjHk756u9VbwuAhu0QHyKscTnisQuz21lfRpOwiS9z4XdqeVAKol0bzg==} resolution: {integrity: sha512-MEYM1JTn/qiC3DbpvP2BVhyIH+dV/5BjHk756u9VbwuAhu0QHyKscTnisQuz21lfRpOwiS9z4XdqeVAKol0bzg==}
deprecated: It is not compatible with newer versions of GA starting with v4, as long as you are using GAv3 it should be ok, but the package is not longer being maintained
workbox-navigation-preload@7.0.0: workbox-navigation-preload@7.0.0:
resolution: {integrity: sha512-juWCSrxo/fiMz3RsvDspeSLGmbgC0U9tKqcUPZBCf35s64wlaLXyn2KdHHXVQrb2cqF7I0Hc9siQalainmnXJA==} resolution: {integrity: sha512-juWCSrxo/fiMz3RsvDspeSLGmbgC0U9tKqcUPZBCf35s64wlaLXyn2KdHHXVQrb2cqF7I0Hc9siQalainmnXJA==}
@ -14686,6 +14706,8 @@ snapshots:
- bluebird - bluebird
- supports-color - supports-color
paho-mqtt@1.1.0: {}
parent-module@1.0.1: parent-module@1.0.1:
dependencies: dependencies:
callsites: 3.1.0 callsites: 3.1.0

View File

@ -4065,6 +4065,8 @@ exports[`runs examples > example "juxBy" example index 0 1`] = `
] ]
`; `;
exports[`runs examples > example "keyDown" example index 0 1`] = `[]`;
exports[`runs examples > example "lastOf" example index 0 1`] = ` exports[`runs examples > example "lastOf" example index 0 1`] = `
[ [
"[ 0/1 → 1/4 | note:c3 ]", "[ 0/1 → 1/4 | note:c3 ]",
@ -8832,6 +8834,8 @@ exports[`runs examples > example "when" example index 0 1`] = `
] ]
`; `;
exports[`runs examples > example "whenKey" example index 0 1`] = `[]`;
exports[`runs examples > example "withValue" example index 0 1`] = ` exports[`runs examples > example "withValue" example index 0 1`] = `
[ [
"[ 0/1 → 1/3 | 10 ]", "[ 0/1 → 1/3 | 10 ]",