-
Notifications
You must be signed in to change notification settings - Fork 159
fix(cat): polish cat/model transition behavio #1666
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
ea60c7f
d69f703
da56d92
1a38e95
46c10ad
b7c9932
97448a7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -211,6 +211,7 @@ const _NEKO_IDLE_CAT1_COMPACT_TOP_EDGE_DROP_PX = 52; | |
| const _NEKO_IDLE_CAT1_COMPACT_TOP_EDGE_DROP_ANIMATION_MS = 360; | ||
| const _NEKO_IDLE_CAT1_COMPACT_TOP_EDGE_DROP_COOLDOWN_MS = 900; | ||
| const _NEKO_IDLE_CAT1_COMPACT_SURFACE_SETTLE_SYNC_MS = 160; | ||
| const _NEKO_IDLE_CAT1_COMPACT_MIRROR_SETTLE_HIDE_DELAY_MS = 180; | ||
| const _NEKO_IDLE_CAT1_WALK_ENTER_DISTANCE_PX = 120; | ||
| const _NEKO_IDLE_CAT1_WALK_EXIT_DISTANCE_PX = 14; | ||
| const _NEKO_IDLE_CAT1_WALK_SPEED_PX_PER_SEC = 82; | ||
|
|
@@ -576,6 +577,7 @@ function _playNekoIdleCat1AmbientSound(token) { | |
| _pickNekoIdleCat1AmbientSoundUrl(), | ||
| _NEKO_IDLE_CAT1_AMBIENT_SOUND_VOLUME | ||
| ); | ||
| _playNekoIdleCat1SoundReaction(); | ||
| } | ||
|
|
||
| function _scheduleNekoIdleCat1AmbientSoundInterval(intervalStartedAt) { | ||
|
|
@@ -639,6 +641,77 @@ function _fadeOutNekoIdleCat1DragSound() { | |
| _fadeOutNekoIdleSoundAudio(_nekoIdleCat1DragSoundState, _NEKO_IDLE_CAT1_DRAG_SOUND_FADE_OUT_MS); | ||
| } | ||
|
|
||
| function _syncNekoIdleCat1CompactMirrorReaction(button, container, assetUrl, reason) { | ||
| const state = button && (button.__nekoIdleReturnSubactionState || button.__nekoIdleCat1Journey); | ||
| if (!state || | ||
| !container || | ||
| !container.__nekoIdleCat1CompactMirrorActive || | ||
| state.targetKind !== _NEKO_IDLE_CAT1_TARGET_KIND_COMPACT_TOP_EDGE) { | ||
| return; | ||
| } | ||
|
|
||
| const surfaceRect = _getNekoIdleChatCompactSurfaceRect(); | ||
| if (!surfaceRect) return; | ||
| _setNekoIdleCat1CompactMirrorActive(button, container, true, { | ||
| reason: reason || 'cat1-sound-reaction', | ||
| surfaceRect: surfaceRect, | ||
| target: { | ||
| anchorRatio: state.compactFollowAnchorRatio | ||
| }, | ||
| assetUrl: assetUrl | ||
| }); | ||
| } | ||
|
|
||
| function _playNekoIdleCat1SoundReaction() { | ||
| _forEachNekoIdleReturnButton((button) => { | ||
| if (_normalizeNekoIdleReturnTier(button.getAttribute('data-neko-idle-tier')) !== _NEKO_IDLE_TIER_CAT1) return; | ||
| if (_isNekoIdleReturnDragActionActive(button)) return; | ||
| const container = _getNekoIdleReturnContainerFromButton(button); | ||
| if (!container || container.style.display === 'none') return; | ||
| const state = button.__nekoIdleReturnSubactionState || button.__nekoIdleCat1Journey; | ||
| if (!state || state.targetKind !== _NEKO_IDLE_CAT1_TARGET_KIND_COMPACT_TOP_EDGE) return; | ||
| const art = button.querySelector('.neko-idle-return-art'); | ||
| if (!art) return; | ||
|
|
||
| _playNekoIdleHoverArt(art, _NEKO_IDLE_TIER_CAT1); | ||
| const reactionSrc = art.__nekoIdleHoverSrc; | ||
| if (!reactionSrc) return; | ||
| const reactionStartedAt = Math.max(0, Number(art.__nekoIdleHoverStartedAt) || Date.now()); | ||
| const hoverToken = art.__nekoIdleHoverToken || 0; | ||
| const mirrorToken = (art.__nekoIdleCat1CompactMirrorReactionToken || 0) + 1; | ||
| art.__nekoIdleCat1CompactMirrorReactionToken = mirrorToken; | ||
| _finishNekoIdleHoverArtAfterPlayback(art, _NEKO_IDLE_TIER_CAT1); | ||
| _syncNekoIdleCat1CompactMirrorReaction(button, container, reactionSrc, 'cat1-sound-reaction'); | ||
|
|
||
| _getNekoIdleGifDurationMs(reactionSrc).then((durationMs) => { | ||
| if ((art.__nekoIdleCat1CompactMirrorReactionToken || 0) !== mirrorToken) return; | ||
| const elapsedMs = Math.max(0, Date.now() - reactionStartedAt); | ||
| const remainingMs = Math.max(0, (Number(durationMs) || 0) - elapsedMs); | ||
| window.setTimeout(() => { | ||
| if ((art.__nekoIdleCat1CompactMirrorReactionToken || 0) !== mirrorToken) return; | ||
| const latestHoverToken = art.__nekoIdleHoverToken || 0; | ||
| const hoverStillPlaying = latestHoverToken === hoverToken; | ||
| const hoverFinishedThisReaction = latestHoverToken === hoverToken + 1 && !art.__nekoIdleHoverSrc; | ||
| if (!hoverStillPlaying && !hoverFinishedThisReaction) return; | ||
| const latestState = button.__nekoIdleReturnSubactionState || button.__nekoIdleCat1Journey; | ||
| const latestContainer = _getNekoIdleReturnContainerFromButton(button); | ||
| if (!latestState || | ||
| latestState.targetKind !== _NEKO_IDLE_CAT1_TARGET_KIND_COMPACT_TOP_EDGE || | ||
| !latestContainer || | ||
| !latestContainer.__nekoIdleCat1CompactMirrorActive) { | ||
| return; | ||
| } | ||
| _syncNekoIdleCat1CompactMirrorReaction( | ||
| button, | ||
| latestContainer, | ||
| _getNekoIdleReturnCurrentArtUrl(button, _NEKO_IDLE_TIER_CAT1), | ||
| 'cat1-sound-reaction-finished' | ||
| ); | ||
| }, remainingMs); | ||
| }); | ||
| }); | ||
| } | ||
|
|
||
| const _NEKO_IDLE_RETURN_SUBACTION_CAT1_CHAT_FOLLOW = Object.freeze({ | ||
| id: 'cat1-chat-follow', | ||
| tier: _NEKO_IDLE_TIER_CAT1, | ||
|
|
@@ -1308,29 +1381,61 @@ function _getNekoIdleScreenRectFromCompactSurfaceRect(rect) { | |
| } | ||
|
|
||
| function _postNekoIdleCat1CompactMirrorState(payload) { | ||
| const message = Object.assign({ | ||
| action: 'idle_cat1_compact_mirror_state', | ||
| source: 'pet-window', | ||
| lanlan_name: _getNekoIdleCurrentLanlanName(), | ||
| timestamp: Date.now() | ||
| }, payload || {}); | ||
| let dispatchedLocal = false; | ||
| try { | ||
| window.dispatchEvent(new CustomEvent('neko:idle-cat1-compact-mirror-state', { | ||
| detail: Object.assign({ | ||
| via: 'local' | ||
| }, message) | ||
|
Comment on lines
+1392
to
+1395
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When the compact chat runs in the separate Electron chat window, Useful? React with 👍 / 👎. |
||
| })); | ||
| dispatchedLocal = true; | ||
| } catch (_) {} | ||
|
|
||
| const channel = window.appInterpage && window.appInterpage.nekoBroadcastChannel; | ||
| if (!channel || typeof channel.postMessage !== 'function') return false; | ||
| if (!channel || typeof channel.postMessage !== 'function') return dispatchedLocal; | ||
| try { | ||
| channel.postMessage(Object.assign({ | ||
| action: 'idle_cat1_compact_mirror_state', | ||
| source: 'pet-window', | ||
| lanlan_name: _getNekoIdleCurrentLanlanName(), | ||
| timestamp: Date.now() | ||
| }, payload || {})); | ||
| channel.postMessage(message); | ||
| return true; | ||
| } catch (error) { | ||
| if (typeof console !== 'undefined' && console.warn) { | ||
| console.warn('[NekoIdleCat1] compact mirror postMessage failed:', error && error.message ? error.message : error); | ||
| } | ||
| return false; | ||
| return dispatchedLocal; | ||
| } | ||
| } | ||
|
|
||
| function _setNekoIdleCat1CompactMirrorActive(button, container, active, options = {}) { | ||
| if (!container) return false; | ||
| const nextActive = !!active; | ||
| const state = button && (button.__nekoIdleReturnSubactionState || button.__nekoIdleCat1Journey); | ||
| if (nextActive && container.__nekoIdleCat1CompactMirrorSettleTimer) { | ||
| clearTimeout(container.__nekoIdleCat1CompactMirrorSettleTimer); | ||
| container.__nekoIdleCat1CompactMirrorSettleTimer = 0; | ||
| } | ||
| if (!nextActive) { | ||
| const inactiveReason = options.reason || 'inactive'; | ||
| if ( | ||
| inactiveReason === 'compact-surface-settled' && | ||
| !options.forceImmediate && | ||
| container.__nekoIdleCat1CompactMirrorActive | ||
| ) { | ||
| if (!container.__nekoIdleCat1CompactMirrorSettleTimer) { | ||
| container.__nekoIdleCat1CompactMirrorSettleTimer = setTimeout(() => { | ||
| container.__nekoIdleCat1CompactMirrorSettleTimer = 0; | ||
| _setNekoIdleCat1CompactMirrorActive(button, container, false, { | ||
| reason: inactiveReason, | ||
| forceImmediate: true | ||
| }); | ||
| }, _NEKO_IDLE_CAT1_COMPACT_MIRROR_SETTLE_HIDE_DELAY_MS); | ||
| } | ||
| return true; | ||
| } | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| if (!container.__nekoIdleCat1CompactMirrorActive) return true; | ||
| container.__nekoIdleCat1CompactMirrorActive = false; | ||
| container.classList.remove('is-cat1-compact-mirror-active'); | ||
|
|
@@ -1365,7 +1470,7 @@ function _setNekoIdleCat1CompactMirrorActive(button, container, active, options | |
| }, | ||
| overlapPx: _NEKO_IDLE_CAT1_COMPACT_TOP_EDGE_OVERLAP_PX, | ||
| sidePaddingPx: _NEKO_IDLE_CAT1_COMPACT_TOP_EDGE_SIDE_PADDING_PX, | ||
| assetUrl: _getNekoIdleReturnAssetUrl(_NEKO_IDLE_TIER_CAT1), | ||
| assetUrl: options.assetUrl || _getNekoIdleReturnAssetUrl(_NEKO_IDLE_TIER_CAT1), | ||
| facingRight: !!(state && state.facingRight) | ||
| }); | ||
| if (!posted) return false; | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.