Add emoji confetti bursts and component playground.
Support app.relay.emoji_confetti on jumbo emoji clicks with canvas physics, per-emoji particle profiles, and a fixed overlay that does not affect scroll. Also add a Vite playground for live component previews and theme hover preview.
This commit is contained in:
54
src/app/features/room/emoji-confetti/resolveClickedEmoji.ts
Normal file
54
src/app/features/room/emoji-confetti/resolveClickedEmoji.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import { KeyboardEvent, MouseEvent } from 'react';
|
||||
import { extractJumboEmojis } from './sendEmojiConfetti';
|
||||
import { BurstPoint, getBurstPointFromElement } from './burstOrigin';
|
||||
|
||||
export function resolveClickedEmoji(
|
||||
event: MouseEvent<HTMLElement> | KeyboardEvent<HTMLElement>,
|
||||
fallbackBody: string
|
||||
): { emoji: string; origin: BurstPoint } | null {
|
||||
const currentTarget = event.currentTarget as HTMLElement;
|
||||
const target = event.target as HTMLElement;
|
||||
const emoticonEl = target.closest('[data-emoticon]') ?? currentTarget.querySelector('[data-emoticon]');
|
||||
if (emoticonEl instanceof HTMLElement) {
|
||||
const emoji = emoticonEl.getAttribute('data-emoticon');
|
||||
if (emoji) {
|
||||
return {
|
||||
emoji,
|
||||
origin: getBurstPointFromElement(emoticonEl),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (!currentTarget.closest('[data-jumbo-emoji]') && !currentTarget.hasAttribute('data-jumbo-emoji')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const emojis = extractJumboEmojis(fallbackBody);
|
||||
if (emojis.length === 0) return null;
|
||||
|
||||
if ('clientX' in event) {
|
||||
return {
|
||||
emoji: emojis[0],
|
||||
origin: {
|
||||
x: event.clientX,
|
||||
y: event.clientY,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const firstEmoticon = currentTarget.querySelector('[data-emoticon]');
|
||||
if (firstEmoticon instanceof HTMLElement) {
|
||||
const emoji = firstEmoticon.getAttribute('data-emoticon');
|
||||
if (emoji) {
|
||||
return {
|
||||
emoji,
|
||||
origin: getBurstPointFromElement(firstEmoticon),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
emoji: emojis[0],
|
||||
origin: getBurstPointFromElement(currentTarget),
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user