Skip to content

Commit

Permalink
The CSS Update Part 3 - A bunch of fixes and tweaks
Browse files Browse the repository at this point in the history
yeah
  • Loading branch information
spessasus committed Jul 7, 2024
1 parent 9f710e4 commit b8b99d3
Show file tree
Hide file tree
Showing 19 changed files with 351 additions and 251 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "SpessaSynth",
"version": "3.2.25",
"version": "3.2.27",
"type": "module",
"scripts": {
"start": "node src/website/server/server.js",
Expand Down
2 changes: 2 additions & 0 deletions src/website/css/keyboard.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
background: black;
width: 100%;
transition: var(--music-mode-transition) transform;
touch-action: none;
}

#keyboard.out_animation{
Expand All @@ -20,6 +21,7 @@
{
-webkit-user-select: none;
user-select: none;
touch-action: none;

flex: 1;
transition: transform 0.1s ease;
Expand Down
5 changes: 3 additions & 2 deletions src/website/css/synthesizer_ui/synthesizer_ui.css
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,11 @@
display: flex;
align-items: stretch;
flex-wrap: wrap;
transition: 0.2s ease;
}

.no_voices {
filter: brightness(80%);
.channel_controller.no_voices{
filter: brightness(0.8);
}

.mute_button
Expand Down
21 changes: 21 additions & 0 deletions src/website/js/keybinds.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* @enum {string}
*/
export const keybinds = {
synthesizerUIShow: "s",
settingsShow: "r",

blackMidiMode: "b",
midiPanic: "backspace",

playPause: " ",
toggleLoop: "l",
toggleLyrics: "t",
seekBackwards: "arrowleft",
seekForwards: "arrowright",
previousSong: "[",
nextSong: "]",

cinematicMode: "c",
videoMode: "v"
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {Synthetizer} from "../../spessasynth_lib/synthetizer/synthetizer.js";
import { midiControllers } from '../../spessasynth_lib/midi_parser/midi_message.js'
import { isMobile } from './utils/is_mobile.js'
import {Synthetizer} from "../../../spessasynth_lib/synthetizer/synthetizer.js";
import { midiControllers } from '../../../spessasynth_lib/midi_parser/midi_message.js'
import { _handlePointers } from './pointer_handling.js'

/**
* midi_keyboard.js
Expand All @@ -9,7 +9,7 @@ import { isMobile } from './utils/is_mobile.js'

const GLOW_PX = 150;

export class MidiKeyboard
class MidiKeyboard
{
/**
* Creates a new midi keyboard(keyboard)
Expand All @@ -18,13 +18,15 @@ export class MidiKeyboard
*/
constructor(channelColors, synth) {
this.mouseHeld = false;
this.lastKeyPressed = -1;
this.heldKeys = [];
/**
* @type {Set<number>}
*/
this.pressedKeys = new Set();
/**
* @type {"light"|"dark"}
*/
this.mode = "light";
this.enableDebugging = true;
this.enableDebugging = false;

/**
* @type {{min: number, max: number}}
Expand All @@ -35,20 +37,6 @@ export class MidiKeyboard
max: 127
};

document.onpointerdown = () => {
this.mouseHeld = true;
}
document.onpointerup = () => {
this.mouseHeld = false;
this.lastKeyPressed = -1;
for(let key of this.heldKeys)
{
// user note off
this.releaseNote(key, this.channel);
this.synth.noteOff(this.channel, key);
}
}

// hold pedal on
document.addEventListener("keydown", e =>{
if(e.key === "Shift")
Expand Down Expand Up @@ -126,77 +114,7 @@ export class MidiKeyboard
this.keys.push(keyElement);
}

/**
* @param keyElement {HTMLDivElement}
* @param e {PointerEvent}
*/
const noteOnHandler = (keyElement, e) => {
if (!this.mouseHeld)
{
return;
}

e.stopPropagation();
e.preventDefault();
const midiNote = parseInt(keyElement.id.replace("note", ""));

if(this.lastKeyPressed === midiNote || isNaN(midiNote))
{
return;
}

if(this.lastKeyPressed !== -1)
{
// user note off
this.heldKeys.splice(this.heldKeys.indexOf(this.lastKeyPressed), 1);
this.releaseNote(this.lastKeyPressed, this.channel);
this.synth.noteOff(this.channel, this.lastKeyPressed);
}

this.lastKeyPressed = midiNote;

// user note on
if (!this.heldKeys.includes(midiNote))
{
this.heldKeys.push(midiNote);
}

let velocity ;
if (isMobile)
{
// ignore precise key velocity on mobile (keys are too small anyways)
velocity = 127;
}
else
{
// determine velocity. lower = more velocity
const rect = keyElement.getBoundingClientRect();
const relativeY = e.clientY; // Handle both mouse and touch events
const relativeMouseY = relativeY - rect.top;
const keyHeight = rect.height;
velocity = Math.floor(relativeMouseY / keyHeight * 127);
}
this.synth.noteOn(this.channel, midiNote, velocity, this.enableDebugging);
};

// POINTER HANDLING
this.keyboard.onpointerdown = e => {
this.mouseHeld = true;
noteOnHandler(document.elementFromPoint(e.clientX, e.clientY), e);
}

this.keyboard.onpointermove = e => {
noteOnHandler(document.elementFromPoint(e.clientX, e.clientY), e);
};

this.keyboard.onpointerleave = () => {
const midiNote = this.lastKeyPressed;
// user note off
this.heldKeys.splice(this.heldKeys.indexOf(midiNote), 1);
this.releaseNote(midiNote, this.channel);
this.synth.noteOff(this.channel, midiNote);
this.lastKeyPressed = -1;
};
this._handlePointers();
}

/**
Expand Down Expand Up @@ -412,4 +330,6 @@ export class MidiKeyboard
this.keyColors[index] = [];
})
}
}
}
MidiKeyboard.prototype._handlePointers = _handlePointers;
export { MidiKeyboard };
103 changes: 103 additions & 0 deletions src/website/js/midi_keyboard/pointer_handling.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { isMobile } from '../utils/is_mobile.js'

/**
* @this {MidiKeyboard}
* @private
*/
export function _handlePointers()
{
// POINTER HANDLING
const userNoteOff = note => {
this.pressedKeys.delete(note)
this.releaseNote(note, this.channel);
this.synth.noteOff(this.channel, note);
}

const userNoteOn = (note, clientY) => {
// user note on
this.pressedKeys.add(note);

let velocity;
if (isMobile)
{
// ignore precise key velocity on mobile (keys are too small anyways)
velocity = 127;
}
else
{
// determine velocity. lower = more velocity
const keyElement = this.keys[note];
const rect = keyElement.getBoundingClientRect();
// Handle both mouse and touch events
const relativeMouseY = clientY - rect.top;
const keyHeight = rect.height;
velocity = Math.floor(relativeMouseY / keyHeight * 127);
}
this.synth.noteOn(this.channel, note, velocity, this.enableDebugging);
}

/**
* @param e {MouseEvent|TouchEvent}
*/
const moveHandler = e => {
// all currently pressed keys are stored in this.pressedKeys
/**
* @type {Touch[]|MouseEvent[]}
*/
const touches = e.touches ? Array.from(e.touches) : [e];
/**
* @type {Set<number>}
*/
const currentlyTouchedKeys = new Set();
touches.forEach(touch => {
const targetKey = document.elementFromPoint(touch.clientX, touch.clientY);
const midiNote = parseInt(targetKey.id.replace("note", ""));
currentlyTouchedKeys.add(midiNote);
if(isNaN(midiNote) || midiNote < 0 || this.pressedKeys.has(midiNote))
{
// pressed outside of bounds or already pressed
return;
}
userNoteOn(midiNote, touch.clientY);
});
this.pressedKeys.forEach(key => {
if(!currentlyTouchedKeys.has(key))
{
userNoteOff(key);
}
});
};

// mouse
document.addEventListener("mousedown", e => {
this.mouseHeld = true;
moveHandler(e);
});
document.addEventListener("mouseup", () => {
this.mouseHeld = false;
this.pressedKeys.forEach(key => {
userNoteOff(key);
});
});
this.keyboard.onmousemove = e => {
if(this.mouseHeld) moveHandler(e);
};
this.keyboard.onmouseleave = () => {
this.pressedKeys.forEach(key => {
userNoteOff(key);
});
}

// touch
this.keyboard.ontouchstart = e => {
moveHandler(e);
};
this.keyboard.ontouchend = () => {
this.pressedKeys.forEach(key => {
userNoteOff(key);
});
};
this.keyboard.addEventListener("touchmove", e => {
moveHandler(e);
});
}
2 changes: 1 addition & 1 deletion src/website/js/notification.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const NOTIFICATION_TIME = 7000;
const NOTIFICATION_TIME = 13000;
/**
* @param title {string}
* @param message {string}
Expand Down
15 changes: 8 additions & 7 deletions src/website/js/sequencer_ui/sequencer_ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { supportedEncodings } from '../utils/encodings.js'
import { getBackwardSvg, getForwardSvg, getLoopSvg, getPauseSvg, getPlaySvg, getTextSvg } from '../icons.js'
import { messageTypes } from '../../../spessasynth_lib/midi_parser/midi_message.js'
import { getSeqUIButton } from './sequi_button.js'
import { keybinds } from '../keybinds.js'

/**
* sequencer_ui.js
Expand Down Expand Up @@ -398,17 +399,17 @@ export class SequencerUI
document.addEventListener("keypress", event => {
switch(event.key.toLowerCase())
{
case " ":
case keybinds.playPause:
event.preventDefault();
togglePlayback();
break;

case "l":
case keybinds.toggleLoop:
event.preventDefault();
toggleLoop();
break;

case "t":
case keybinds.toggleLyrics:
event.preventDefault();
toggleLyrics();
break;
Expand All @@ -435,23 +436,23 @@ export class SequencerUI

switch (e.key.toLowerCase())
{
case "arrowleft":
case keybinds.seekBackwards:
e.preventDefault();
this.seq.currentTime -= 5;
playPauseButton.innerHTML = getPauseSvg(ICON_SIZE);
break;

case "arrowright":
case keybinds.seekForwards:
e.preventDefault();
this.seq.currentTime += 5;
playPauseButton.innerHTML = getPauseSvg(ICON_SIZE);
break;

case "[":
case keybinds.previousSong:
this.switchToPreviousSong();
break;

case "]":
case keybinds.nextSong:
this.switchToNextSong();
break;

Expand Down
Loading

0 comments on commit b8b99d3

Please sign in to comment.