add fade animation to window
This commit is contained in:
		
							parent
							
								
									2bfcadecb4
								
							
						
					
					
						commit
						a509e87b22
					
				@ -51,10 +51,47 @@ function updateLayout() {
 | 
			
		||||
        layoutManager.updateLayout();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
let movementManager = null;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const FADE_DURATION = 250;
 | 
			
		||||
const FADE_FPS      = 60;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 윈도우 투명도를 서서히 변경한다.
 | 
			
		||||
 * @param {BrowserWindow} win
 | 
			
		||||
 * @param {number} from
 | 
			
		||||
 * @param {number} to
 | 
			
		||||
 * @param {number} duration
 | 
			
		||||
 * @param {Function=} onComplete 
 | 
			
		||||
 */
 | 
			
		||||
function fadeWindow(win, from, to, duration = FADE_DURATION, onComplete) {
 | 
			
		||||
  if (!win || win.isDestroyed()) return;
 | 
			
		||||
 | 
			
		||||
  const steps       = Math.max(1, Math.round(duration / (1000 / FADE_FPS)));
 | 
			
		||||
  let   currentStep = 0;
 | 
			
		||||
 | 
			
		||||
  win.setOpacity(from);
 | 
			
		||||
 | 
			
		||||
  const timer = setInterval(() => {
 | 
			
		||||
    if (win.isDestroyed()) { clearInterval(timer); return; }
 | 
			
		||||
 | 
			
		||||
    currentStep += 1;
 | 
			
		||||
    const progress = currentStep / steps;
 | 
			
		||||
    const eased    = progress < 1
 | 
			
		||||
      ? 1 - Math.pow(1 - progress, 3)
 | 
			
		||||
      : 1;
 | 
			
		||||
 | 
			
		||||
    win.setOpacity(from + (to - from) * eased);
 | 
			
		||||
 | 
			
		||||
    if (currentStep >= steps) {
 | 
			
		||||
      clearInterval(timer);
 | 
			
		||||
      win.setOpacity(to);
 | 
			
		||||
      onComplete && onComplete();
 | 
			
		||||
    }
 | 
			
		||||
  }, 1000 / FADE_FPS);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function setupAnimationController(windowPool, layoutManager, movementManager) {
 | 
			
		||||
    internalBridge.on('request-window-visibility', ({ name, visible }) => {
 | 
			
		||||
@ -91,7 +128,7 @@ async function handleWindowVisibilityRequest(windowPool, layoutManager, movement
 | 
			
		||||
    const isOtherWinVisible = otherWin && !otherWin.isDestroyed() && otherWin.isVisible();
 | 
			
		||||
 | 
			
		||||
    const ANIM_OFFSET_X = 100; 
 | 
			
		||||
    const ANIM_OFFSET_Y = 100; 
 | 
			
		||||
    const ANIM_OFFSET_Y = 20; 
 | 
			
		||||
 | 
			
		||||
    if (shouldBeVisible) {
 | 
			
		||||
        win.setOpacity(0);
 | 
			
		||||
@ -104,22 +141,20 @@ async function handleWindowVisibilityRequest(windowPool, layoutManager, movement
 | 
			
		||||
                const startPos = { x: targets.listen.x - ANIM_OFFSET_X, y: targets.listen.y };
 | 
			
		||||
                win.setBounds(startPos);
 | 
			
		||||
                win.show();
 | 
			
		||||
                win.setOpacity(1);
 | 
			
		||||
                fadeWindow(win, 0, 1);
 | 
			
		||||
                movementManager.animateWindow(win, targets.listen.x, targets.listen.y);
 | 
			
		||||
 | 
			
		||||
            } else {
 | 
			
		||||
                const targets = layoutManager.getTargetBoundsForFeatureWindows({ listen: true, ask: true });
 | 
			
		||||
                if (!targets.listen || !targets.ask) return;
 | 
			
		||||
 | 
			
		||||
                // 'listen'은 목표 위치의 왼쪽에서 시작
 | 
			
		||||
                const startListenPos = { x: targets.listen.x - ANIM_OFFSET_X, y: targets.listen.y };
 | 
			
		||||
                win.setBounds(startListenPos);
 | 
			
		||||
 | 
			
		||||
                // 'listen'을 보여주고 두 창을 동시에 애니메이션
 | 
			
		||||
                win.show();
 | 
			
		||||
                win.setOpacity(1);
 | 
			
		||||
                movementManager.animateWindow(otherWin, targets.ask.x, targets.ask.y); // 'ask' 창을 새 위치로 이동
 | 
			
		||||
                movementManager.animateWindow(win, targets.listen.x, targets.listen.y); // 'listen' 창을 새 위치로 이동
 | 
			
		||||
                fadeWindow(win, 0, 1);
 | 
			
		||||
                movementManager.animateWindow(otherWin, targets.ask.x, targets.ask.y);
 | 
			
		||||
                movementManager.animateWindow(win, targets.listen.x, targets.listen.y);
 | 
			
		||||
            }
 | 
			
		||||
        } else if (name === 'ask') {
 | 
			
		||||
            if (!isOtherWinVisible) {
 | 
			
		||||
@ -129,7 +164,7 @@ async function handleWindowVisibilityRequest(windowPool, layoutManager, movement
 | 
			
		||||
                const startPos = { x: targets.ask.x, y: targets.ask.y - ANIM_OFFSET_Y };
 | 
			
		||||
                win.setBounds(startPos);
 | 
			
		||||
                win.show();
 | 
			
		||||
                win.setOpacity(1);
 | 
			
		||||
                fadeWindow(win, 0, 1);
 | 
			
		||||
                movementManager.animateWindow(win, targets.ask.x, targets.ask.y);
 | 
			
		||||
 | 
			
		||||
            } else {
 | 
			
		||||
@ -140,37 +175,32 @@ async function handleWindowVisibilityRequest(windowPool, layoutManager, movement
 | 
			
		||||
                win.setBounds(startAskPos);
 | 
			
		||||
 | 
			
		||||
                win.show();
 | 
			
		||||
                win.setOpacity(1);
 | 
			
		||||
                fadeWindow(win, 0, 1);
 | 
			
		||||
                movementManager.animateWindow(otherWin, targets.listen.x, targets.listen.y);
 | 
			
		||||
                movementManager.animateWindow(win, targets.ask.x, targets.ask.y);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        const currentBounds = win.getBounds();
 | 
			
		||||
 | 
			
		||||
        fadeWindow(
 | 
			
		||||
            win, 1, 0, FADE_DURATION,
 | 
			
		||||
            () => win.hide()
 | 
			
		||||
          );
 | 
			
		||||
        if (name === 'listen') {
 | 
			
		||||
            if (!isOtherWinVisible) {
 | 
			
		||||
                const targetX = currentBounds.x - ANIM_OFFSET_X;
 | 
			
		||||
                movementManager.animateWindow(win, targetX, currentBounds.y, {
 | 
			
		||||
                    onComplete: () => win.hide()
 | 
			
		||||
                });
 | 
			
		||||
                movementManager.animateWindow(win, targetX, currentBounds.y);
 | 
			
		||||
            } else {
 | 
			
		||||
                const targetX = currentBounds.x - currentBounds.width;
 | 
			
		||||
                movementManager.animateWindow(win, targetX, currentBounds.y, {
 | 
			
		||||
                    onComplete: () => win.hide()
 | 
			
		||||
                });
 | 
			
		||||
                movementManager.animateWindow(win, targetX, currentBounds.y);
 | 
			
		||||
            }
 | 
			
		||||
        } else if (name === 'ask') {
 | 
			
		||||
            if (!isOtherWinVisible) {
 | 
			
		||||
                 const targetY = currentBounds.y - ANIM_OFFSET_Y;
 | 
			
		||||
                 movementManager.animateWindow(win, currentBounds.x, targetY, {
 | 
			
		||||
                     onComplete: () => win.hide()
 | 
			
		||||
                 });
 | 
			
		||||
                 movementManager.animateWindow(win, currentBounds.x, targetY);
 | 
			
		||||
            } else {
 | 
			
		||||
                const targetAskY = currentBounds.y - ANIM_OFFSET_Y;
 | 
			
		||||
                movementManager.animateWindow(win, currentBounds.x, targetAskY, {
 | 
			
		||||
                    onComplete: () => win.hide()
 | 
			
		||||
                });
 | 
			
		||||
                movementManager.animateWindow(win, currentBounds.x, targetAskY);
 | 
			
		||||
 | 
			
		||||
                const targets = layoutManager.getTargetBoundsForFeatureWindows({ listen: true, ask: false });
 | 
			
		||||
                if (targets.listen) {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user