From 0c16b1a3d99a12db6f6a43183592d445e434900c Mon Sep 17 00:00:00 2001 From: Alex Hua Date: Wed, 12 Feb 2025 21:02:26 +0800 Subject: [PATCH] feat: Add pause animation 1. Display pause icon animation when all tasks are paused 2. Refine the animation transition logic --- background.js | 3 ++ js/IconUtils/Animation.js | 45 ++++++++++++++++++++++++++++- js/IconUtils/AnimationController.js | 15 ++++++---- js/IconUtils/TransitionManager.js | 22 ++++++-------- 4 files changed, 65 insertions(+), 20 deletions(-) diff --git a/background.js b/background.js index f960668..97b3aa0 100644 --- a/background.js +++ b/background.js @@ -721,6 +721,9 @@ async function monitorAria2() { enableMonitor(); } chrome.power.releaseKeepAwake(); + if (waiting > 0) { + IconAnimController.start('Pause'); + } } let bgColor = 'green', textColor = 'white', text = '', title = ''; diff --git a/js/IconUtils/Animation.js b/js/IconUtils/Animation.js index 882981c..0e45a93 100644 --- a/js/IconUtils/Animation.js +++ b/js/IconUtils/Animation.js @@ -36,7 +36,6 @@ class BaseAnimation { this.ctx.globalAlpha = alpha; this.ctx.scale(this.scaleFactor, this.scaleFactor); this.render(); - this.ctx.globalAlpha = 1; this.frameId = (this.frameId + 1) % this.totalFrames; this.ctx.restore(); return this.canvas.getImageData(); @@ -277,4 +276,48 @@ export class ProgressAnimation extends BaseAnimation { this.#drawProgressCircle(); this.#drawArrow(); } +} + +export class PauseAnimation extends BaseAnimation { + constructor() { + super(); + this.duration = 3010; + this.colors = [ + [0, '#4FC3F7'], // Light blue + [0.5, '#2196F3'], // Medium blue + [1, '#1976D2'] // Dark blue + ]; + } + + render() { + + // Draw circle + this.ctx.beginPath(); + this.ctx.lineWidth = 1.5; + this.ctx.strokeStyle = 'rgba(33, 150, 243, .6)'; + this.ctx.arc(8, 8, 7, 0, Math.PI * 2); + this.ctx.stroke(); + + // set round conner + this.ctx.lineCap = 'round'; + this.ctx.lineJoin = 'round'; + + // Draw pause symbol + this.addShadow('rgba(3, 169, 244, 0.2)', 1); + const gradient = this.createGradient(this.colors, 0, 0, 16, 16); + this.ctx.strokeStyle = gradient; + this.ctx.lineWidth = 1.5; + + // left line + this.ctx.beginPath(); + this.ctx.moveTo(6.75, 5); + this.ctx.lineTo(6.75, 11); + this.ctx.stroke(); + + // right line + this.ctx.beginPath(); + this.ctx.moveTo(9.25, 5); + this.ctx.lineTo(9.25, 11); + this.ctx.stroke(); + } } \ No newline at end of file diff --git a/js/IconUtils/AnimationController.js b/js/IconUtils/AnimationController.js index 6bdeb0b..3102ee3 100644 --- a/js/IconUtils/AnimationController.js +++ b/js/IconUtils/AnimationController.js @@ -1,4 +1,4 @@ -import { DownloadAnimation, CompleteAnimation, ErrorAnimation, ProgressAnimation } from './Animation.js'; +import { DownloadAnimation, CompleteAnimation, ErrorAnimation, ProgressAnimation, PauseAnimation } from './Animation.js'; import { FRAME_INTERVAL, FADE_INTERVAL } from './Constants.js'; import { IconManager } from './IconManager.js'; import { TransitionManager } from './TransitionManager.js'; @@ -18,6 +18,9 @@ export class AnimationController { case 'Download': newAnimation = new DownloadAnimation(); break; + case 'Pause': + newAnimation = new PauseAnimation(); + break; case 'Complete': newAnimation = new CompleteAnimation(); break; @@ -39,13 +42,13 @@ export class AnimationController { throw new Error(`AnimationController: Invalid animation type: ${type}`); } - if (this.transitionManager.currentAnimation && - this.transitionManager.currentAnimation != this.progressAnimation) { - const currentAnimation = this.transitionManager.isTransitioning ? - this.transitionManager.nextAnimation : this.transitionManager.currentAnimationAnimation; + const currentAnimation = this.transitionManager.isTransitioning ? + this.transitionManager.nextAnimation : this.transitionManager.currentAnimation; + // Start transition between different animation + if (currentAnimation?.constructor !== newAnimation.constructor) { this.transitionManager.startTransition(currentAnimation, newAnimation); - } else { + } else if (!this.transitionManager.isTransitioning) { this.transitionManager.currentAnimation = newAnimation; } diff --git a/js/IconUtils/TransitionManager.js b/js/IconUtils/TransitionManager.js index df33e9c..b9ff3ce 100644 --- a/js/IconUtils/TransitionManager.js +++ b/js/IconUtils/TransitionManager.js @@ -41,26 +41,22 @@ export class TransitionManager { } #blend(progress) { - const canvas1 = new Canvas(); - const canvas2 = new Canvas(); + const ctx = this.canvas.getContext(); + + this.canvas.clear(); if (this.currentAnimation) { - canvas1.ctx.putImageData(this.currentAnimation.draw(), 0, 0); + this.currentAnimation.draw(); + ctx.globalAlpha = 1 - progress; + ctx.drawImage(this.currentAnimation.canvas.getCanvas(), 0, 0); } if (this.nextAnimation) { - canvas2.ctx.putImageData(this.nextAnimation.draw(), 0, 0); + this.nextAnimation.draw(); + ctx.globalAlpha = progress; + ctx.drawImage(this.nextAnimation.canvas.getCanvas(), 0, 0); } - this.canvas.clear(); - const ctx = this.canvas.getContext(); - - ctx.globalAlpha = 1 - progress; - ctx.drawImage(canvas1.getCanvas(), 0, 0); - ctx.globalAlpha = progress; - ctx.drawImage(canvas2.getCanvas(), 0, 0); - ctx.globalAlpha = 1; - return this.canvas.getImageData(); } } \ No newline at end of file