Skip to content

Commit

Permalink
Adding click and play note for lattice
Browse files Browse the repository at this point in the history
Fix
  • Loading branch information
wilckerson committed May 20, 2024
1 parent 971a7da commit a0ebe67
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 1 deletion.
23 changes: 23 additions & 0 deletions src/components/GridLattice.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,16 @@ const props = defineProps<{
labels: string[]
colors: string[]
heldNotes: Set<number>
baseMidiNote:number
onTouchStart:TouchEventCallback
onTouchEnd:TouchEventCallback
onMouseDown:MouseEventCallback
onMouseUp:MouseEventCallback
onMouseEnter:MouseEventCallback
onMouseLeave:MouseEventCallback
}>()
type TouchEventCallback = (event: TouchEvent, index: number) => void
type MouseEventCallback = (event: MouseEvent, index: number) => void
const svgElement = ref<SVGSVGElement | null>(null)
Expand Down Expand Up @@ -127,6 +136,13 @@ watch(() => store.modulus, computeExtent)
:fill="colors[v.indices[0]] ?? 'none'"
:stroke="colors[v.indices[0]] ?? 'none'"
:stroke-width="store.size * 0.1"
@touchstart="onTouchStart($event, props.baseMidiNote + v.indices[0] + 1)"
@touchend="onTouchEnd($event, props.baseMidiNote + v.indices[0] + 1)"
@touchcancel="onTouchEnd($event, props.baseMidiNote + v.indices[0] + 1)"
@mousedown="onMouseDown($event, props.baseMidiNote + v.indices[0] + 1)"
@mouseup="onMouseUp($event, props.baseMidiNote + v.indices[0] + 1)"
@mouseenter="onMouseEnter($event, props.baseMidiNote + v.indices[0] + 1)"
@mouseleave="onMouseLeave($event, props.baseMidiNote + v.indices[0] + 1)"
/>
<template v-if="store.showLabels">
<template v-for="(v, i) of grid.vertices" :key="i">
Expand All @@ -139,6 +155,13 @@ watch(() => store.modulus, computeExtent)
:font-size="`${2.5 * store.size}px`"
:stroke-width="store.size * 0.05"
dominant-baseline="middle"
@touchstart="onTouchStart($event, props.baseMidiNote + idx + 1)"
@touchend="onTouchEnd($event, props.baseMidiNote + idx + 1)"
@touchcancel="onTouchEnd($event, props.baseMidiNote + idx + 1)"
@mousedown="onMouseDown($event, props.baseMidiNote + idx + 1)"
@mouseup="onMouseUp($event, props.baseMidiNote + idx + 1)"
@mouseenter="onMouseEnter($event, props.baseMidiNote + idx + 1)"
@mouseleave="onMouseLeave($event, props.baseMidiNote + idx + 1)"
>
{{ labels[idx] }}
</text>
Expand Down
26 changes: 25 additions & 1 deletion src/components/JustIntonationLattice.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,19 @@ const props = defineProps<{
relativeIntervals: Interval[]
labels: string[]
colors: string[]
heldNotes: Set<number>
heldNotes: Set<number>
baseMidiNote:number
onTouchStart:TouchEventCallback
onTouchEnd:TouchEventCallback
onMouseDown:MouseEventCallback
onMouseUp:MouseEventCallback
onMouseEnter:MouseEventCallback
onMouseLeave:MouseEventCallback
}>()
type TouchEventCallback = (event: TouchEvent, index: number) => void
type MouseEventCallback = (event: MouseEvent, index: number) => void
const svgElement = ref<SVGSVGElement | null>(null)
const viewBox = reactive([-1, -1, 2, 2])
Expand Down Expand Up @@ -186,6 +196,13 @@ watch(
:fill="colors[v.index!] ?? 'none'"
:stroke="colors[v.index!] ?? 'none'"
:stroke-width="store.size * 0.1"
@touchstart="onTouchStart($event, props.baseMidiNote + v.index! + 1)"
@touchend="onTouchEnd($event, props.baseMidiNote + v.index! + 1)"
@touchcancel="onTouchEnd($event, props.baseMidiNote + v.index! + 1)"
@mousedown="onMouseDown($event, props.baseMidiNote + v.index! + 1)"
@mouseup="onMouseUp($event, props.baseMidiNote + v.index! + 1)"
@mouseenter="onMouseEnter($event, props.baseMidiNote + v.index! + 1)"
@mouseleave="onMouseLeave($event, props.baseMidiNote + v.index! + 1)"
/>
<template v-if="store.showLabels">
<text
Expand All @@ -197,6 +214,13 @@ watch(
:y="v.y - store.labelOffset * store.size"
:font-size="`${3 * store.size}px`"
:stroke-width="store.size * 0.08"
@touchstart="onTouchStart($event, props.baseMidiNote + v.index! + 1)"
@touchend="onTouchEnd($event, props.baseMidiNote + v.index! + 1)"
@touchcancel="onTouchEnd($event, props.baseMidiNote + v.index! + 1)"
@mousedown="onMouseDown($event, props.baseMidiNote + v.index! + 1)"
@mouseup="onMouseUp($event, props.baseMidiNote + v.index! + 1)"
@mouseenter="onMouseEnter($event, props.baseMidiNote + v.index! + 1)"
@mouseleave="onMouseLeave($event, props.baseMidiNote + v.index! + 1)"
>
{{ labels[v.index!] }}
</text>
Expand Down
89 changes: 89 additions & 0 deletions src/views/LatticeView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ import { useScaleStore } from '@/stores/scale'
import { useJiLatticeStore } from '@/stores/ji-lattice'
import { useGridStore } from '@/stores/grid'
import { setAndReportValidity } from '@/utils'
import { LEFT_MOUSE_BTN } from '@/constants'
const props = defineProps<{
noteOn: NoteOnCallback
}>()
type NoteOff = () => void
type NoteOnCallback = (index: number) => NoteOff
const state = useStateStore()
const scale = useScaleStore()
Expand Down Expand Up @@ -88,6 +96,68 @@ watch(etPreset, (newValue) => {
return
}
})
const isMousePressed = ref(false)
const noteOffs: Map<number, NoteOff> = new Map()
function start(index: number) {
noteOffs.set(index, props.noteOn(index))
}
function end(index: number) {
if (noteOffs.has(index)) {
noteOffs.get(index)!()
noteOffs.delete(index)
}
}
function onTouchEnd(event: TouchEvent, index: number) {
event.preventDefault()
end(index)
}
function onTouchStart(event: TouchEvent, index: number) {
event.preventDefault()
// Make sure that we start a new note.
end(index)
start(index)
}
function onMouseDown(event: MouseEvent, index: number) {
if (event.button !== LEFT_MOUSE_BTN) {
return
}
event.preventDefault()
isMousePressed.value = true
start(index)
}
function onMouseUp(event: MouseEvent, index: number) {
if (event.button !== LEFT_MOUSE_BTN) {
return
}
event.preventDefault()
isMousePressed.value = false
end(index)
}
function onMouseEnter(event: MouseEvent, index: number) {
if (!isMousePressed.value) {
return
}
event.preventDefault()
start(index)
}
function onMouseLeave(event: MouseEvent, index: number) {
if (!isMousePressed.value) {
return
}
event.preventDefault()
end(index)
}
</script>

<template>
Expand All @@ -99,13 +169,27 @@ watch(etPreset, (newValue) => {
:colors="scale.latticeColors"
:relativeIntervals="scale.latticeIntervals"
:heldNotes="heldNotes"
:baseMidiNote="scale.baseMidiNote"
:onTouchStart="onTouchStart"
:onTouchEnd="onTouchEnd"
:onMouseDown="onMouseDown"
:onMouseUp="onMouseUp"
:onMouseEnter="onMouseEnter"
:onMouseLeave="onMouseLeave"
/>
<GridLattice
v-else
:labels="scale.latticeLabels"
:colors="scale.latticeColors"
:relativeIntervals="scale.latticeIntervals"
:heldNotes="heldNotes"
:baseMidiNote="scale.baseMidiNote"
:onTouchStart="onTouchStart"
:onTouchEnd="onTouchEnd"
:onMouseDown="onMouseDown"
:onMouseUp="onMouseUp"
:onMouseEnter="onMouseEnter"
:onMouseLeave="onMouseLeave"
/>
<button @click="showConfig = true">Configure</button>
<Modal
Expand Down Expand Up @@ -343,6 +427,9 @@ path.arrow {
stroke-dasharray: 1;
}
circle.node{
cursor: pointer;
}
circle.node:not(.held) {
stroke: var(--color-text);
}
Expand All @@ -359,5 +446,7 @@ text.node-label {
fill: var(--color-text);
text-anchor: middle;
stroke: var(--color-background);
user-select: none;
cursor: pointer;
}
</style>

0 comments on commit a0ebe67

Please sign in to comment.