当前位置: 首页 > news >正文

前端实现 GIF 图片循环播放

前言

使用 img 加载 GIF 图片,内容只会播放一次,之后就会自动暂停;

通过定时器在一段时间后重新加载图片的方式,会导致浏览器内存不断增大,并且可能会有闪烁、卡顿的问题;

ImageDecoder

WebCodecs API 的 ImageDecoder 接口提供了一种对编码图像数据进行解包和解码的方法。

在这里插入图片描述

ImageDecoder 只能在 localhost 或者 https 的 tab 页中获取到

代码

  1. canvas 设置 widthheight,和 GIF 图片尺寸一致
    <canvas width="1310" height="954"></canvas>
    
    或许你也可以通过一下方法动态设置尺寸;
    const img = new Image();
    img.src = '图片路径';
    img.onload = function() {var width = this.width;   // 图片宽度var height = this.height; // 图片高度console.log(`图片尺寸为:${width} x ${height}`);// some code... // 为canvas 设置 width、height
    };
    
  2. 通过 fetch 获取 GIF 图片资源,传入 url
    fetch(url).then((response) => decodeImage(response.body));
    
  3. decodeImage 方法对图片解码
    imageDecoder = new ImageDecoder({ data: imageByteStream, type: "image/gif" });
    imageDecoder.decode({ frameIndex: imageIndex }).then(renderImage);
    
  4. renderImage 渲染每一帧的图片
     function renderImage (result) {const canvas = document.querySelector("canvas");const canvasContext = canvas.getContext("2d");// 绘制图片 canvasContext.drawImage(result.image, 0, 0);const track = imageDecoder.tracks.selectedTrack;if (imageDecoder.complete) {if (track.frameCount === 1) return;// 如果序号超出了帧数,重置为 0if (imageIndex + 1 >= track.frameCount) imageIndex = 0;}// 解码下一帧图片并渲染imageDecoder.decode({ frameIndex: ++imageIndex }).then((nextResult) =>setTimeout(() => {renderImage(nextResult);}, result.image.duration / 1000) // 可以调整播放速度).catch((e) => {if (e instanceof RangeError) {imageIndex = 0;imageDecoder.decode({ frameIndex: imageIndex }).then(renderImage);} else {throw e;}});}
    

完整代码

<template><div><canvas width="1310" height="954"></canvas></div>
</template><script>
export default {mounted() {this.play(require("@/assets/images/animate.gif"));},play(url) {let imageDecoder = null;let imageIndex = 0;function renderImage (result) {const canvas = document.querySelector("canvas");const canvasContext = canvas.getContext("2d");canvasContext.drawImage(result.image, 0, 0);const track = imageDecoder.tracks.selectedTrack;if (imageDecoder.complete) {if (track.frameCount === 1) return;if (imageIndex + 1 >= track.frameCount) imageIndex = 0;}imageDecoder.decode({ frameIndex: ++imageIndex }).then((nextResult) =>setTimeout(() => {renderImage(nextResult);}, result.image.duration / 1000)).catch((e) => {if (e instanceof RangeError) {imageIndex = 0;imageDecoder.decode({ frameIndex: imageIndex }).then(renderImage);} else {throw e;}});}function decodeImage (imageByteStream) {imageDecoder = new ImageDecoder({ data: imageByteStream, type: "image/gif" });imageDecoder.decode({ frameIndex: imageIndex }).then(renderImage);}fetch(url).then((response) => decodeImage(response.body));}
}
</script>

相关链接

  • 纯前端如何实现Gif暂停、倍速播放
  • MDN ImageDecoder

相关文章:

前端实现 GIF 图片循环播放

前言 使用 img 加载 GIF 图片&#xff0c;内容只会播放一次&#xff0c;之后就会自动暂停&#xff1b; 通过定时器在一段时间后重新加载图片的方式&#xff0c;会导致浏览器内存不断增大&#xff0c;并且可能会有闪烁、卡顿的问题&#xff1b; ImageDecoder WebCodecs API 的…...

React - 事件绑定this

在 React 中&#xff0c;this 的绑定是一个常见问题&#xff0c;尤其在类组件中使用事件处理函数时。JavaScript 中的 bind 函数用于设置函数调用时 this 的值。 bind 函数的作用 bind() 方法创建一个新的函数&#xff0c;当被调用时&#xff0c;其 this 关键字被设置为提供的…...

STM32系统架构介绍

STM32系统架构 1. CM3/4系统架构2. CM3/4系统架构-----存储器组织结构2.1 寄存器地址映射&#xff08;特殊的存储器&#xff09;2.2 寄存器地址计算2.3 寄存器的封装 3. CM3/4系统架构-----时钟系统 STM32 和 ARM 以及 ARM7是什么关系? ARM 是一个做芯片标准的公司&#xff0c…...

Macbook Pro快速搭建Easysearch学习环境

在学习过程中&#xff0c;我们有时身边没有可用的服务器&#xff0c;这时就需要借助自己的 Mac 来安装和学习 Easysearch。然而&#xff0c;Easysearch 官网并未提供 Mac 版本的安装教程&#xff0c;下面我将详细整理我在 Mac 上安装和使用 Easysearch 的折腾经历。 Easysearc…...

老游戏回顾:SWRacer

竞速类游戏里&#xff0c;我很怀念它。 虽然已经25年过去了。 相比之下&#xff0c;别的游戏真的没法形容。 ---- 是LucasArts制作的一款赛车竞速游戏&#xff1b; 玩家要扮演一名银河旅行者参加各种赛车比赛&#xff0c;赢得奖金&#xff0c;在经历了八个不同星球上的24场…...

Firefox无法隐藏标题栏

Openbox 窗管 Firefox 无法隐藏标题栏。 深度Linux安装火狐,Linux(deepin) 下隐藏 Firefox 标题栏-CSDN博客 需要在 desktop 的 exec 中增加环境变量&#xff1a; Execenv MOZ_GTK_TITLEBAR_DECORATIONclient firefox...

vue基础(五)

Vue 实例在创建、挂载、更新、销毁的过程中会触发一系列的生命周期钩子&#xff08;Lifecycle Hooks&#xff09;&#xff0c;让开发者可以在不同阶段执行逻辑。 1. Vue 2 生命周期完整流程 生命周期的四个主要阶段 创建阶段&#xff08;Creation&#xff09;挂载阶段&#…...

MySQL的深度分页如何优化?

大家好&#xff0c;我是锋哥。今天分享关于【MySQL的深度分页如何优化&#xff1f;】面试题。希望对大家有帮助&#xff1b; MySQL的深度分页如何优化&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 MySQL的深度分页&#xff08;即跳过大量数据后进行分…...

深度学习每周学习总结R6(RNN实现阿尔茨海默病诊断)

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客R8中的内容&#xff0c;为了便于自己整理总结起名为R6&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制 目录 0. 总结1. 数据集介绍2. 数据预处理3. 模型构建4. 初始化模型及优化器5. 训练函…...

Node.js 多模态图像描述服务 调用siliconflow:现代 JavaScript 实践

Node.js 多模态图像描述服务&#xff1a;现代 JavaScript 实践 项目背景 本项目使用 Node.js 和 TypeScript 实现一个高性能的图像描述微服务&#xff0c;展示 JavaScript 在多模态 AI 应用中的强大能力。 技术栈 Node.jsTypeScriptExpress.jsOpenAI APIdotenvRxJS (可选&a…...

机器学习数学基础:21.特征值与特征向量

一、引言 在现代科学与工程的众多领域中&#xff0c;线性代数扮演着举足轻重的角色。其中&#xff0c;特征值、特征向量以及相似对角化的概念和方法&#xff0c;不仅是线性代数理论体系的核心部分&#xff0c;更是解决实际问题的有力工具。无论是在物理学中描述系统的振动模式…...

【目标检测json2txt】label从COCO格式json文件转YOLO格式txt文件

目录 🍀🍀1.COCO格式json文件 🌷🌷2.YOLO格式txt文件 💖💖3.xml2json代码(python) 🐸🐸4.输入输出展示 🙋🙋4.1输入json 🍂🍂4.2输出txt 整理不易,欢迎一键三连!!! 送你们一条美丽的--分割线-- 🍀🍀1.COCO格式json文件 COCO数…...

强化学习之 PPO 算法:原理、实现与案例深度剖析

目录 一、引言二、PPO 算法原理2.1 策略梯度2.2 PPO 核心思想 三、PPO 算法公式推导3.1 重要性采样3.2 优势函数估计 四、PPO 算法代码实现&#xff08;以 Python 和 PyTorch 为例&#xff09;五、PPO 算法案例应用5.1 机器人控制5.2 自动驾驶 六、总结 一、引言 强化学习作为…...

vue-点击生成动态值,动态渲染回显输入框

1.前言 动态点击生成数值&#xff0c;回显输入框&#xff0c;并绑定。 2.实现 <template><div style"display:flex;align-items: center;flex-direction:row"><a-input:key"inputKey"v-model"uploadData[peo.field]"placehold…...

高性能 :OpenAI Triton Open-source GPU programming Language LINUX 环境配置

目录 配置triton环境cudabuild-essential带有pip的python环境直接安装pipanaconda 安装 triton 环境pip install tritonpip install torch 运行test示例vector-add.pylaunch.json 配置triton环境 cuda wget http://developer.download.nvidia.com/compute/cuda/11.0.2/local_…...

TCP 端口号为何位于首部前四个字节?协议设计的智慧与启示

知乎的一个问题很有意思&#xff1a;“为什么在TCP首部中要把TCP的端口号放入最开始的四个字节&#xff1f;” 这种问题很适合我这种搞历史的人&#xff0c;大年初一我给出了一个简短的解释&#xff0c;但仔细探究这个问题&#xff0c;我们将会获得 TCP/IP 被定义的过程。 文…...

HTML之JavaScript函数声明

HTML之JavaScript函数声明 1. function 函数名(){}2. var 函数名 function(){}<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1…...

R 数组:高效数据处理的基础

R 数组&#xff1a;高效数据处理的基础 引言 在数据科学和统计分析领域&#xff0c;R 语言以其强大的数据处理和分析能力而备受推崇。R 数组是 R 语言中用于存储和操作数据的基本数据结构。本文将详细介绍 R 数组的创建、操作和优化&#xff0c;帮助读者掌握 R 数组的使用技巧…...

git服务器搭建,gitea服务搭建,使用systemclt管理服务

文章目录 页面展示使用二进制文件安装git服务下载选择架构使用wget下载安装 验证 GPG 签名服务器设置准备环境创建systemctl文件 备份与恢复备份命令 (dump)恢复命令 (restore) 页面展示 使用二进制文件安装git服务 所有打包的二进制程序均包含 SQLite&#xff0c;MySQL 和 Po…...

Pdf手册阅读(1)--数字签名篇

原文阅读摘要 PDF支持的数字签名&#xff0c; 不仅仅是公私钥签名&#xff0c;还可以是指纹、手写、虹膜等生物识别签名。PDF签名的计算方式&#xff0c;可以基于字节范围进行计算&#xff0c;也可以基于Pdf 对象&#xff08;pdf object&#xff09;进行计算。 PDF文件可能包…...

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

K8S认证|CKS题库+答案| 11. AppArmor

目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、切换节点 3&#xff09;、切换到 apparmor 的目录 4&#xff09;、执行 apparmor 策略模块 5&#xff09;、修改 pod 文件 6&#xff09;、…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

学校招生小程序源码介绍

基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码&#xff0c;专为学校招生场景量身打造&#xff0c;功能实用且操作便捷。 从技术架构来看&#xff0c;ThinkPHP提供稳定可靠的后台服务&#xff0c;FastAdmin加速开发流程&#xff0c;UniApp则保障小程序在多端有良好的兼…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

srs linux

下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935&#xff0c;SRS管理页面端口是8080&#xff0c;可…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

蓝桥杯3498 01串的熵

问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798&#xff0c; 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...