一些关键事件阻止其他人开火
Some key events prevent others from firing
首先,这是我正在研究的实时应用程序:turbo_synth
我正在使用 VueJS 制作它,但是,我认为这个问题与 Vue 无关。
问题:
一切正常,花花公子,除非尝试弹奏某些音符组合,例如,尝试弹奏 Q、W 键,然后弹奏 2。您会注意到最后一个音符没有被弹奏,甚至没有显示为已按下,而您可以同时玩 Q、W、E、R 和 Y。所以好像没有我之前想的那样是有限制的?
代码:我正在使用vue-keypress来轻松全局处理按键事件。
模板部分
<template>
<div id="app">
<h1>Basic oscillator test</h1>
<label for="waveType">Choose a wave type:</label>
<select
name="waveType"
id="waveType"
v-model="wave"
>
<option value="sine">sine</option>
<option value="square">square</option>
<option value="triangle">triangle</option>
<option value="sawtooth">sawtooth</option>
</select>
<hr>
<ul class="keyboard">
<li
v-for="note in testBoard"
:key="note.id"
:class="[note.class, getKeyByValue(testBoard, note).charAt(0), {'pressed': pressedNotes.includes(note.freq)}]"
@mousedown="playSound(note.freq, 1)"
>
<p>{{getKeyByValue(testBoard, note).replace('s', '#')}}</p>
<p>{{String.fromCharCode(note.keycode)}}</p>
</li>
</ul>
<Keypress
v-for="note in testBoard"
:key="note.id"
key-event="keydown"
:key-code="note.keycode"
@success="playSound(note.freq)"
/>
<Keypress
v-for="note in testBoard"
:key="note.id"
key-event="keyup"
:key-code="note.keycode"
@success="removeNote(note.freq)"
/>
</div>
</template>
脚本部分:
<script>
import { noteValues, testBoard } from './assets/notevalues.js';
export default {
name: 'App',
data() {
return {
noteValues,
testBoard,
selectedNote: null,
wave: 'sine',
pressedNotes: [],
}
},
components: {
Keypress: () => import('vue-keypress')
},
methods: {
getKeyByValue(object, value) {
return Object.keys(object).find(key => object[key] === value);
}
,
playSound(note, clicked) {
if (this.pressedNotes.includes(note)) {
return;
} else {
this.pressedNotes.push(note);
const context = new AudioContext();
const o = context.createOscillator();
const g = context.createGain();
o.connect(g);
g.connect(context.destination);
o.type = this.wave;
const frequency = note;
o.frequency.value = frequency;
o.start(0);
o.stop(context.currentTime + 1)
g.gain.exponentialRampToValueAtTime(
0.00001, context.currentTime + 2.5
);
setTimeout(() => {
context.close();
}, 1000);
if (clicked === 1) {
setTimeout(() => {
this.removeNote(note);
}, 50)
}
}
},
removeNote(note) {
const index = this.pressedNotes.indexOf(note);
if (index > -1) {
this.pressedNotes.splice(index, 1);
}
}
},
}
</script>
这是注释列表:
export let testBoard = {
'C3': { keycode: 81, freq: 130.81, class: 'white' },
'Cs3': { keycode: 50, freq: 138.59, class: 'black' },
'D3': { keycode: 87, freq: 146.83, class: 'white' },
'Ds3': { keycode: 51, freq: 155.56, class: 'black' },
'E3': { keycode: 69, freq: 164.81, class: 'white' },
'F3': { keycode: 82, freq: 174.61, class: 'white' },
'Fs3': { keycode: 53, freq: 185.00, class: 'black' },
'G3': { keycode: 84, freq: 196.00, class: 'white' },
'Gs3': { keycode: 54, freq: 207.65, class: 'black' },
'A3': { keycode: 89, freq: 220.00, class: 'white' },
'As3': { keycode: 55, freq: 233.08, class: 'black' },
'B3': { keycode: 85, freq: 246.94, class: 'white' },
'C4': { keycode: 90, freq: 261.63, class: 'white' },
'Cs4': { keycode: 83, freq: 277.18, class: 'black' },
'D4': { keycode: 88, freq: 293.66, class: 'white' },
'Ds4': { keycode: 68, freq: 311.13, class: 'black' },
'E4': { keycode: 67, freq: 329.63, class: 'white' },
'F4': { keycode: 86, freq: 349.23, class: 'white' },
'Fs4': { keycode: 71, freq: 369.99, class: 'black' },
'G4': { keycode: 66, freq: 392.00, class: 'white' },
'Gs4': { keycode: 72, freq: 415.30, class: 'black' },
'A4': { keycode: 78, freq: 440.00, class: 'white' },
'As4': { keycode: 74, freq: 466.16, class: 'black' },
'B4': { keycode: 77, freq: 493.88, class: 'white' }
}
我也试过别人用vue或其他技术做的钢琴,总是有类似的问题。
我可能遗漏了一些重要的东西,谁知道呢,但我找不到我需要的信息。
非常感谢
您的代码没有任何问题,您也无法修复它 — 这是许多键盘的硬件限制。
首先,假设键盘布局为矩形网格(换句话说,1、Q、 A 和 Z 在同一列中,尽管它们通常不在彼此的正上方)。
限制是不能同时识别构成矩形三个角的三个键。如果您连续按住两个键,则第三个键不能与前两个键在同一列中。如果您在一列中按住两个键,则第三个键不能与前两个键位于同一行。如果您按住 Q 和 Z,那么以 A 开头的行上的任何键都可以正常工作, 但 W, E, X, C,等等都将被锁定。
或者,有些机器可能会在矩形的第四个角给你“幽灵”按键——按住 Q 和 Z 和按 E 会为 E 注册一个按键,同时也会为 C 注册一个按键,即使虽然没有人按下 C.
所有这些都与电子键盘的构建方式有关,您无法通过软件对此做任何事情。有一些键盘没有这个限制,但你不能指望你的用户有它们。
首先,这是我正在研究的实时应用程序:turbo_synth
我正在使用 VueJS 制作它,但是,我认为这个问题与 Vue 无关。
问题: 一切正常,花花公子,除非尝试弹奏某些音符组合,例如,尝试弹奏 Q、W 键,然后弹奏 2。您会注意到最后一个音符没有被弹奏,甚至没有显示为已按下,而您可以同时玩 Q、W、E、R 和 Y。所以好像没有我之前想的那样是有限制的?
代码:我正在使用vue-keypress来轻松全局处理按键事件。
模板部分
<template>
<div id="app">
<h1>Basic oscillator test</h1>
<label for="waveType">Choose a wave type:</label>
<select
name="waveType"
id="waveType"
v-model="wave"
>
<option value="sine">sine</option>
<option value="square">square</option>
<option value="triangle">triangle</option>
<option value="sawtooth">sawtooth</option>
</select>
<hr>
<ul class="keyboard">
<li
v-for="note in testBoard"
:key="note.id"
:class="[note.class, getKeyByValue(testBoard, note).charAt(0), {'pressed': pressedNotes.includes(note.freq)}]"
@mousedown="playSound(note.freq, 1)"
>
<p>{{getKeyByValue(testBoard, note).replace('s', '#')}}</p>
<p>{{String.fromCharCode(note.keycode)}}</p>
</li>
</ul>
<Keypress
v-for="note in testBoard"
:key="note.id"
key-event="keydown"
:key-code="note.keycode"
@success="playSound(note.freq)"
/>
<Keypress
v-for="note in testBoard"
:key="note.id"
key-event="keyup"
:key-code="note.keycode"
@success="removeNote(note.freq)"
/>
</div>
</template>
脚本部分:
<script>
import { noteValues, testBoard } from './assets/notevalues.js';
export default {
name: 'App',
data() {
return {
noteValues,
testBoard,
selectedNote: null,
wave: 'sine',
pressedNotes: [],
}
},
components: {
Keypress: () => import('vue-keypress')
},
methods: {
getKeyByValue(object, value) {
return Object.keys(object).find(key => object[key] === value);
}
,
playSound(note, clicked) {
if (this.pressedNotes.includes(note)) {
return;
} else {
this.pressedNotes.push(note);
const context = new AudioContext();
const o = context.createOscillator();
const g = context.createGain();
o.connect(g);
g.connect(context.destination);
o.type = this.wave;
const frequency = note;
o.frequency.value = frequency;
o.start(0);
o.stop(context.currentTime + 1)
g.gain.exponentialRampToValueAtTime(
0.00001, context.currentTime + 2.5
);
setTimeout(() => {
context.close();
}, 1000);
if (clicked === 1) {
setTimeout(() => {
this.removeNote(note);
}, 50)
}
}
},
removeNote(note) {
const index = this.pressedNotes.indexOf(note);
if (index > -1) {
this.pressedNotes.splice(index, 1);
}
}
},
}
</script>
这是注释列表:
export let testBoard = {
'C3': { keycode: 81, freq: 130.81, class: 'white' },
'Cs3': { keycode: 50, freq: 138.59, class: 'black' },
'D3': { keycode: 87, freq: 146.83, class: 'white' },
'Ds3': { keycode: 51, freq: 155.56, class: 'black' },
'E3': { keycode: 69, freq: 164.81, class: 'white' },
'F3': { keycode: 82, freq: 174.61, class: 'white' },
'Fs3': { keycode: 53, freq: 185.00, class: 'black' },
'G3': { keycode: 84, freq: 196.00, class: 'white' },
'Gs3': { keycode: 54, freq: 207.65, class: 'black' },
'A3': { keycode: 89, freq: 220.00, class: 'white' },
'As3': { keycode: 55, freq: 233.08, class: 'black' },
'B3': { keycode: 85, freq: 246.94, class: 'white' },
'C4': { keycode: 90, freq: 261.63, class: 'white' },
'Cs4': { keycode: 83, freq: 277.18, class: 'black' },
'D4': { keycode: 88, freq: 293.66, class: 'white' },
'Ds4': { keycode: 68, freq: 311.13, class: 'black' },
'E4': { keycode: 67, freq: 329.63, class: 'white' },
'F4': { keycode: 86, freq: 349.23, class: 'white' },
'Fs4': { keycode: 71, freq: 369.99, class: 'black' },
'G4': { keycode: 66, freq: 392.00, class: 'white' },
'Gs4': { keycode: 72, freq: 415.30, class: 'black' },
'A4': { keycode: 78, freq: 440.00, class: 'white' },
'As4': { keycode: 74, freq: 466.16, class: 'black' },
'B4': { keycode: 77, freq: 493.88, class: 'white' }
}
我也试过别人用vue或其他技术做的钢琴,总是有类似的问题。 我可能遗漏了一些重要的东西,谁知道呢,但我找不到我需要的信息。
非常感谢
您的代码没有任何问题,您也无法修复它 — 这是许多键盘的硬件限制。
首先,假设键盘布局为矩形网格(换句话说,1、Q、 A 和 Z 在同一列中,尽管它们通常不在彼此的正上方)。
限制是不能同时识别构成矩形三个角的三个键。如果您连续按住两个键,则第三个键不能与前两个键在同一列中。如果您在一列中按住两个键,则第三个键不能与前两个键位于同一行。如果您按住 Q 和 Z,那么以 A 开头的行上的任何键都可以正常工作, 但 W, E, X, C,等等都将被锁定。
或者,有些机器可能会在矩形的第四个角给你“幽灵”按键——按住 Q 和 Z 和按 E 会为 E 注册一个按键,同时也会为 C 注册一个按键,即使虽然没有人按下 C.
所有这些都与电子键盘的构建方式有关,您无法通过软件对此做任何事情。有一些键盘没有这个限制,但你不能指望你的用户有它们。