editor: add resize SFX triggered while dragging resize handles
Register a `resize` sound effect (three round-robin variations with pitch/pan jitter and an 80ms gap) and emit it from the linear/radial resize drag handler whenever the snapped+clamped value steps, so width / length / depth / radius / height drags tick as the size changes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
b2f1a8432e
commit
9bfbcc9f01
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -668,6 +668,11 @@ function LinearArrow({
|
|||||||
? 1
|
? 1
|
||||||
: -1
|
: -1
|
||||||
|
|
||||||
|
// Last value an emitted resize tick fired at — a new tick fires only
|
||||||
|
// when the (snapped + clamped) value actually changes, so the cue
|
||||||
|
// tracks real size steps instead of every sub-pixel pointer jitter.
|
||||||
|
let lastTickValue = initialValue
|
||||||
|
|
||||||
return {
|
return {
|
||||||
overrideId,
|
overrideId,
|
||||||
onBegin: () => {
|
onBegin: () => {
|
||||||
@@ -695,6 +700,10 @@ function LinearArrow({
|
|||||||
? snapScalar(rawNext, gridSnapStep)
|
? snapScalar(rawNext, gridSnapStep)
|
||||||
: rawNext
|
: rawNext
|
||||||
const next = Math.min(maxBound, Math.max(minBound, snappedNext))
|
const next = Math.min(maxBound, Math.max(minBound, snappedNext))
|
||||||
|
if (next !== lastTickValue) {
|
||||||
|
lastTickValue = next
|
||||||
|
sfxEmitter.emit('sfx:resize')
|
||||||
|
}
|
||||||
const patch = descriptor.apply(initialNode as never, next, sceneApi) as Partial<AnyNode>
|
const patch = descriptor.apply(initialNode as never, next, sceneApi) as Partial<AnyNode>
|
||||||
// Let the kind publish live guides for the edge being resized.
|
// Let the kind publish live guides for the edge being resized.
|
||||||
onDrag?.({ ...(initialNode as object), ...patch } as AnyNode, sceneApi)
|
onDrag?.({ ...(initialNode as object), ...patch } as AnyNode, sceneApi)
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ type SFXEvents = {
|
|||||||
'sfx:item-pick': undefined
|
'sfx:item-pick': undefined
|
||||||
'sfx:item-place': undefined
|
'sfx:item-place': undefined
|
||||||
'sfx:item-rotate': undefined
|
'sfx:item-rotate': undefined
|
||||||
|
'sfx:resize': undefined
|
||||||
'sfx:structure-build-start': undefined
|
'sfx:structure-build-start': undefined
|
||||||
'sfx:structure-build': undefined
|
'sfx:structure-build': undefined
|
||||||
'sfx:structure-delete': undefined
|
'sfx:structure-delete': undefined
|
||||||
@@ -40,6 +41,7 @@ export function initSFXBus() {
|
|||||||
sfxEmitter.on('sfx:item-pick', () => playSFX('itemPick'))
|
sfxEmitter.on('sfx:item-pick', () => playSFX('itemPick'))
|
||||||
sfxEmitter.on('sfx:item-place', () => playSFX('itemPlace'))
|
sfxEmitter.on('sfx:item-place', () => playSFX('itemPlace'))
|
||||||
sfxEmitter.on('sfx:item-rotate', () => playSFX('itemRotate'))
|
sfxEmitter.on('sfx:item-rotate', () => playSFX('itemRotate'))
|
||||||
|
sfxEmitter.on('sfx:resize', () => playSFX('resize'))
|
||||||
sfxEmitter.on('sfx:structure-build-start', () => playSFX('structureBuildStart'))
|
sfxEmitter.on('sfx:structure-build-start', () => playSFX('structureBuildStart'))
|
||||||
sfxEmitter.on('sfx:structure-build', () => playSFX('structureBuildEnd'))
|
sfxEmitter.on('sfx:structure-build', () => playSFX('structureBuildEnd'))
|
||||||
sfxEmitter.on('sfx:structure-delete', () => playSFX('structureDelete'))
|
sfxEmitter.on('sfx:structure-delete', () => playSFX('structureDelete'))
|
||||||
|
|||||||
@@ -59,6 +59,16 @@ export const SFX: Record<string, SFXConfig> = {
|
|||||||
volumeRange: [0.92, 1.0],
|
volumeRange: [0.92, 1.0],
|
||||||
panJitter: 0.15,
|
panJitter: 0.15,
|
||||||
},
|
},
|
||||||
|
// Ticks as a resize handle is dragged across snap steps. Fires in rapid
|
||||||
|
// succession, so it mirrors gridSnap: three variations cycled round-robin
|
||||||
|
// with pitch/pan jitter and a gap so the run reads as texture, not a tone.
|
||||||
|
resize: {
|
||||||
|
src: ['/audios/sfx/resize_0.mp3', '/audios/sfx/resize_1.mp3', '/audios/sfx/resize_2.mp3'],
|
||||||
|
rateRange: [0.98, 1.02],
|
||||||
|
volumeRange: [0.26, 0.34],
|
||||||
|
panJitter: 0.15,
|
||||||
|
minIntervalMs: 80,
|
||||||
|
},
|
||||||
// Fired when a structure draft begins (first click of a wall/slab/etc).
|
// Fired when a structure draft begins (first click of a wall/slab/etc).
|
||||||
structureBuildStart: {
|
structureBuildStart: {
|
||||||
src: '/audios/sfx/structure_build_start.mp3',
|
src: '/audios/sfx/structure_build_start.mp3',
|
||||||
|
|||||||
Reference in New Issue
Block a user