GIFPlayer 使用指南:创建可调速的 GIF 播放器

今天我要分享一个功能全面的 JavaScript GIF 播放器类 - GIFPlayer,它支持播放控制、速度调整和自适应尺寸等功能

核心功能

  1. 基本播放控制

    • 播放/暂停切换
    • 自动播放选项
    • 帧精确控制
  2. 速度调节

    • 0.5倍到8倍可调速度
    • 加速(×2)/减速(÷2)快捷方法
    • 速度变化回调通知
  3. 智能尺寸处理

    • 自动使用 GIF 原始尺寸
    • 支持自定义宽高
    • 动态调整画布大小

使用示例





  
  
  Document
  



  
1.0x
class GIFPlayer {
  constructor(options) {
    if (!options.canvas) {
      this.canvas = document.createElement('canvas');
      this.canvas.id = 'gif-player-canvas';
      document.body.appendChild(this.canvas);
    } else {
      this.canvas = options.canvas;
    }
    this.width = options.width;
    this.height = options.height;
    this.autoplay = options.autoplay !== false; // 默认自动播放
    this.frameIndex = 0; // 当前帧索引
    this.animationId = null; // 动画ID
    this.playing = false; // 播放状态
    this.imageDecoder = null;

    // 新增播放速度控制
    this.playbackRate = options.playbackRate || 1; // 默认1倍速
    this.minRate = options.minRate || 0.5;  // 最低0.5倍
    this.maxRate = options.maxRate || 8;    // 最高4倍
    this.rateStep = options.rateStep || 2; // 步长2
    this.onRateChange = options.onRateChange || null;
    this.initCanvas();
  }

  initCanvas(width = this.width, height = this.height) {
    this.canvas.width = width;
    this.canvas.height = height;
    this.ctx = this.canvas.getContext('2d');
  }

  async _renderFrame(frameIndex) {
    const result = await this.imageDecoder.decode({ frameIndex });
    // Initialize canvas size
    if (!this.width && !this.height) {
      await this.initCanvas(result.image.displayWidth, result.image.displayHeight);
    }
    this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
    this.ctx.drawImage(result.image, 0, 0, this.canvas.width, this.canvas.height);
    return result;
  }

  async loadFile(file) {
    try {
      const arrayBuffer = await file.arrayBuffer();
      this.imageDecoder = new ImageDecoder({
        data: arrayBuffer,
        type: file.type || 'image/gif'
      });
      await this._renderFrame(this.frameIndex);
      if (this.autoplay) {
        await this.play();
      }
    } catch (error) {
      console.error('加载失败:', error);
    }
  }

  async play() {
    if (!this.imageDecoder) return;
    if (this.playing) this.stop();
    this.playing = true;
    const renderAnimationFrame = async () => {
      const result = await this._renderFrame(this.frameIndex);
      this.frameIndex = (this.frameIndex + 1) %
        this.imageDecoder.tracks.selectedTrack.frameCount;

      const duration = result.image.duration / 1000 / this.playbackRate;
      this.animationId = setTimeout(
        renderAnimationFrame,
        duration
      );
    };

    renderAnimationFrame();
  }

  stop() {
    clearTimeout(this.animationId);
    this.playing = false;
  }

  toggle() {
    this.playing ? this.stop() : this.play();
  }

  speedUp() {
    const newRate = this.playbackRate * this.rateStep;
    this.setPlaybackRate(newRate);
    return this.playbackRate;
  }

  speedDown() {
    const newRate = this.playbackRate / this.rateStep;
    this.setPlaybackRate(newRate);
    return this.playbackRate;
  }

  setPlaybackRate(rate) {
    const oldRate = this.playbackRate;
    this.playbackRate = Math.max(this.minRate, Math.min(this.maxRate, rate));
    if (this.playbackRate !== oldRate && this.onRateChange) {
      this.onRateChange(this.playbackRate);
    }
    if (this.playing) {
      this.stop();
      this.play();
    }
    return this.playbackRate;
  }
}

if (typeof module !== 'undefined' && module.exports) {
  module.exports = GIFPlayer;
} else {
  window.GIFPlayer = GIFPlayer;
}

gif-palyer

实现亮点

  1. 流畅的动画控制

    • 使用 ImageDecoder API 高效解码
    • 精确计算帧间隔时间
    • 速度变化时无缝重启动画
  2. 完善的状态管理

    • 播放状态跟踪
    • 当前帧索引记录
    • 速度边界检查
  3. 灵活的扩展性

    • 事件回调机制
    • 可配置参数
    • 清晰的 API 设计

应用场景

  • 社交媒体 GIF 查看器
  • 动画教学工具
  • 游戏特效预览
  • 视频编辑工具

这个播放器类已封装为独立模块,可以直接集成到项目中。代码简洁高效,兼容现代浏览器,是处理 GIF 动画的理想解决方案。

你可能感兴趣的:(前端,开发记录,javaScript,前端,javascript)