void => * or :enter
.// Appear
if(!isMounted && visible && motionAppear){
nextStatus=STATUS_APPEAR;
}
// Enter
if(isMounted && visible && motionEnter){
nextStatus=STATUS_ENTER;
}
* => void or : leave
// Leave
if(
(isMounted && !visible && motionLeave) ||
(!isMounted && motionLeaveImmediately && !visible && motionLeave)
){
nextStatus=STATUS_LEAVE;
}
note: ${animationName}-appear or ${animationName}-enter ${animationName}-leave
className will be applied to target element.please define css styles to these class.
for every status, it will go across steps queue, like prepare -> start -> active -> end.
eveytime we come into one step, we will call callback function to get an result promise/nonpromise to deterine if we go to next step directly or go to next step in next animationframe or in any time.
note: these className will be generated according to different step. ${transitionName}-${statusName}-preare/start/active/end
. please define different css.
onAppearPrepare, onEnterPrepare, onLeavePrepare
we can use these functions to control animation process. take role like delay.if(nextStep === STEP_PREPARE){
const onPrepare = eventHandlers[STEP_PREPARE];
if(!onPrepare){
return SkipStep;
}
return onPrepare(getDomElement());
}
onAppearStart, onEnterStart, onLeaveStart
, these functions will return style which will be apply to target elements directly.if(step in eventHandlers){
setStyle(eventHandlers[step as ‘start‘|‘active‘]?.(getDomElement(),null as any)||null);
}
onAppearActive, onEnterActive, onLeaveActive
to apply style to target elements. by the way, we will listen to the animationend event to the target element. or we will call animationend event handler in motionDeadlineif(step === STEP_ACTIVE){
patchMotionEvents(getDomElement());
if(motionDeadline! > 0){
clearTimeout(deadlineRef.current!);
deadlineRef.current = setTimeout(()=>{
onInternalMotionEnd({
deadline:true
}as MotionEvent);
},motionDeadline);
}
}
onAppearEnd, onEnterEnd, onLeaveEnd
to determine if we reset status and step into ‘none‘function onInternalMotionEnd(event:MotionEvent){
const element = getDomElement();
if(event && !event.deadline && event.target !==element){
return;
}
let canEnd:boolean|void;
if(status === STATUS_APPEAR && activeRef.current){
canEnd = onAppearEnd?.(element,event);
}else if(status === STATUS_ENTER && activeRef.current){
canEnd = onEnterEnd?.(element,event);
}else if(status === STATUS_LEAVE && activeRef.current){
canEnd = onLeaveEnd?.(element,event);
}
if(canEnd !== false && !destroyRef.current){
setStatus(STATUS_NONE);
setStyle(null);
}
}
.transition{
transition: background 0.3s,height 1.3s,opacity 1.3s;
&.transition-appear,
&.transition-enter{
opacity: 0;
}
&.transition-appear.transition-appear-active,
&.transition-enter.transition-enter-active{
opacity: 1;
}
&.transition-leave-active{
opacity: 0;
background: green;
}
}
.animation{
animation-duration: 1.3s;
animation-fill-mode: both;
&.animation-appear,
&.animation-enter{
animation-name: enter;
animation-play-state: paused;
}
&.animation-appear.animation-appear-active,
&.animation-enter.animation-enter-active{
animation-name: enter;
animation-play-state: running;
}
&.animation-leave{
animation-name:leave;
animation-fill-mode: both;
animation-play-state: paused;
}
&.animation-leave.animation-leave-active{
animation-play-state: running;
}
}
<CSSMotion>
{
({className,style},ref)=>(
<div ref={ref} className={className} style = {style}>
</div>
)
}
</CSSMotion>
state(‘state1‘, style({ height: ‘*‘, opacity: 1, overflow: ‘hidden‘ })),
state(‘state2‘, style({ height: 0, opacity: 0, padding: 0, overflow: ‘hidden‘ })),
transition(`state1 => state2`, [
animate(‘0.2s ease-out‘)
]),
export function EnterAnimation(){
return [
transition(‘:enter‘,useAnimation(
animation([
style({transform:‘scale(0.8)‘,opacity:0}),
animate(‘300ms ease-out‘,style({transform:‘none‘,opacity:1}))
])
))
]
}
@Component({
selector:‘subscription-transcribe‘,
templateUrl:‘./subscription-transcribe.component.html‘,
styleUrls:[‘./subscription-transcribe.component.scss‘],
animations:[
trigger(‘enterLeaveTrigger‘,
EnterAnimation()
)
]
})
<div [@enterLeaveTrigger]> (@enterLeaveTrigger.start)="(e)=>{}" (@enterLeaveTrigger.end)="(e)=>{}"</div>
CSSMotion VS animation in Angular
原文:https://www.cnblogs.com/kongshu-612/p/14784070.html