fixed positioning for presentations
This commit is contained in:
parent
7dd3384a46
commit
e1ff820629
@ -9,9 +9,9 @@
|
||||
import React from 'react';
|
||||
import UiElementRenderer from './UiElements/UiElementRenderer';
|
||||
import { useElementEffects } from '../hooks/useElementEffects';
|
||||
import { useAppearAnimation } from '../hooks/useAppearAnimation';
|
||||
import {
|
||||
buildTransitionStyle,
|
||||
buildAppearAnimationStyle,
|
||||
hasAnyEffects,
|
||||
extractEffectProperties,
|
||||
} from '../lib/elementEffects';
|
||||
@ -57,20 +57,11 @@ const RuntimeElement: React.FC<RuntimeElementProps> = ({
|
||||
element as unknown as Record<string, unknown>,
|
||||
);
|
||||
|
||||
// Use appear animation hook (removes animation after completion to unlock properties)
|
||||
const { animationStyle, onAnimationEnd, hasAnimationEnded } =
|
||||
useAppearAnimation(
|
||||
effectProperties,
|
||||
element.id, // Reset animation when element changes
|
||||
);
|
||||
|
||||
// Use effects hook for interactive states with animation coordination
|
||||
// Use effects hook for interactive states
|
||||
const { effectStyle, eventHandlers, onPersistClick } = useElementEffects(
|
||||
effectProperties,
|
||||
{
|
||||
resetKey: element.id, // Reset reveal on element change
|
||||
appearAnimationCompleted:
|
||||
hasAnimationEnded || !effectProperties.appearAnimation,
|
||||
},
|
||||
);
|
||||
|
||||
@ -80,36 +71,33 @@ const RuntimeElement: React.FC<RuntimeElementProps> = ({
|
||||
onClick(); // Original navigation action
|
||||
};
|
||||
|
||||
// Build base position style
|
||||
// Build base position style (outer div - handles positioning + animation)
|
||||
let positionStyle: React.CSSProperties = {
|
||||
left: `${xPercent}%`,
|
||||
top: `${yPercent}%`,
|
||||
transform: `translate(-50%, -50%)${rotation ? ` rotate(${rotation}deg)` : ''}`,
|
||||
};
|
||||
|
||||
// Merge transform if effect style has transform
|
||||
if (effectStyle.transform) {
|
||||
// Preserve the translate and rotation, add effect transform
|
||||
positionStyle.transform = `translate(-50%, -50%)${rotation ? ` rotate(${rotation}deg)` : ''} ${effectStyle.transform}`;
|
||||
// Remove transform from effectStyle to avoid double application
|
||||
const { transform, ...restEffectStyle } = effectStyle;
|
||||
positionStyle = { ...positionStyle, ...restEffectStyle };
|
||||
} else {
|
||||
positionStyle = { ...positionStyle, ...effectStyle };
|
||||
// Add appear animation to outer div
|
||||
// Animation stays on outer div to keep positioning hack working
|
||||
if (effectProperties.appearAnimation) {
|
||||
positionStyle = {
|
||||
...positionStyle,
|
||||
...buildAppearAnimationStyle(effectProperties),
|
||||
};
|
||||
}
|
||||
|
||||
// Add transition if element has any effects
|
||||
// Build inner wrapper style for hover/focus/active effects
|
||||
// Using separate div so animation on outer div doesn't block these effects
|
||||
let innerEffectStyle: React.CSSProperties = {};
|
||||
if (hasAnyEffects(effectProperties)) {
|
||||
const transitionStyle = buildTransitionStyle(effectProperties);
|
||||
positionStyle = { ...positionStyle, ...transitionStyle };
|
||||
innerEffectStyle = {
|
||||
...effectStyle,
|
||||
...buildTransitionStyle(effectProperties),
|
||||
};
|
||||
}
|
||||
|
||||
// Check if appear animation uses transform (slide/scale need separate wrapper)
|
||||
const needsAnimationWrapper =
|
||||
effectProperties.appearAnimation &&
|
||||
effectProperties.appearAnimation !== 'fade';
|
||||
|
||||
// Render content (with or without animation wrapper)
|
||||
// Render content
|
||||
const content = (
|
||||
<UiElementRenderer
|
||||
element={element}
|
||||
@ -121,41 +109,25 @@ const RuntimeElement: React.FC<RuntimeElementProps> = ({
|
||||
/>
|
||||
);
|
||||
|
||||
// For fade animation (opacity only), apply to positioning div
|
||||
// For slide/scale (uses transform), use separate wrapper to avoid conflict
|
||||
if (needsAnimationWrapper) {
|
||||
return (
|
||||
<div
|
||||
className='absolute cursor-pointer'
|
||||
style={positionStyle}
|
||||
onClick={handleClick}
|
||||
tabIndex={0}
|
||||
{...eventHandlers}
|
||||
>
|
||||
<div style={animationStyle} onAnimationEnd={onAnimationEnd}>
|
||||
{content}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Fade or no animation: apply animation to positioning div
|
||||
const combinedStyle = effectProperties.appearAnimation
|
||||
? { ...positionStyle, ...animationStyle }
|
||||
: positionStyle;
|
||||
// Check if we need the inner wrapper for effects
|
||||
const needsEffectWrapper = hasAnyEffects(effectProperties);
|
||||
|
||||
return (
|
||||
<div
|
||||
className='absolute cursor-pointer'
|
||||
style={combinedStyle}
|
||||
style={positionStyle}
|
||||
onClick={handleClick}
|
||||
tabIndex={0}
|
||||
onAnimationEnd={
|
||||
effectProperties.appearAnimation ? onAnimationEnd : undefined
|
||||
}
|
||||
{...eventHandlers}
|
||||
{...(!needsEffectWrapper ? eventHandlers : {})}
|
||||
>
|
||||
{content}
|
||||
{needsEffectWrapper ? (
|
||||
// Inner wrapper handles hover/focus/active effects independently from animation
|
||||
<div style={innerEffectStyle} {...eventHandlers}>
|
||||
{content}
|
||||
</div>
|
||||
) : (
|
||||
content
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user