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

如何在 AWS 上构建支持 AVIF 的前端图片优化方案

一、为什么使用 AVIF 图片格式?

优势点

说明

高压缩率

在相似质量下,AVIF 文件比 JPEG/PNG/WebP 更小,能有效节省带宽和存储空间。

更高画质

即使在低码率下也能保持清晰细节,减少压缩带来的马赛克或模糊问题。

支持透明度

像 PNG 一样支持 Alpha 通道透明效果,且文件更小。

支持 HDR

支持高动态范围(HDR)色彩,亮部与暗部细节表现更出色。

支持动画

支持多帧动画,体积远小于 GIF,可实现流畅动画效果。

开源免费

基于开放标准,无需支付版权费用,适合广泛应用。

更好的色彩表现

支持更高位深(如 10 位、12 位色深),色彩过渡更加自然。

浏览器支持不断提升

已被 Chrome、Firefox、Safari、Edge 等主流浏览器广泛支持,兼容性持续提升。

采用 AVIF 图片格式,可以大幅提升网页加载性能、优化视觉体验,并有效降低服务器及流量成本。

二、图片上传为 PNG/JPG,为什么最终返回的是 AVIF?

我们上传至 AWS S3 桶中的图片文件,最初是以传统格式(如 PNG、JPG)存在的。但用户最终访问时,返回的是 AVIF 格式,主要是因为配置了以下动态处理流程:

  1. 拦截请求与格式判断

  • 当浏览器请求图片资源时,AWS 会拦截请求,检测浏览器是否支持 AVIF 格式。

  • 如果支持,将在 S3 中查找对应的 AVIF 文件。

2. 动态生成 AVIF 图片

- 如果 S3 桶中已有对应的 AVIF 图片,直接返回。

- 如果没有现成的 AVIF 图片,则根据用户请求的源图片(PNG/JPG),实时生成一张新的 AVIF 图片,并保存到 S3 桶中,随后返回给用户。

3. 兼容老浏览器

  • 如果浏览器不支持 AVIF,则直接返回原始格式的图片(如 PNG、JPG),确保访问兼容性。

三、替换同名图片后,是否还会访问到旧的 AVIF 图片?

不会。

为了避免用户访问到缓存中的老图片,系统在图片上传阶段进行了以下处理:

  • 当上传新的同名图片时,AWS 会自动检测并删除已有的同名 AVIF 图片资源。

  • 这样一来,旧版 AVIF 图片被清除。

  • 当用户下次访问时,因找不到旧的 AVIF 图片,系统会根据新的源图重新生成新的 AVIF 文件并返回。

  • 从而确保用户访问到的永远是最新版本的图片内容。

✅ 此机制有效避免了 CDN 缓存失效等待问题,大大简化了图片更新和运维管理流程。

四、我们访问的图片后缀明明是jpg 或者png 为什么我们下载下来是avif

  1. 浏览器发起请求,比如 GET https://yourdomain.com/path/image.jpg

  2. **请求头(Accept)**中会带上浏览器支持的图片格式,比如:

Accept: image/avif,image/webp,image/apng,image/*,*/*;q=0.8

浏览器告诉服务器:"我可以接受 avif 格式哦!"

  1. Lambda@Edge 或 CDN(如 CloudFront)拦截了请求,根据请求头里的 Accept 判断,发现浏览器支持 avif,于是就做了智能格式替换:

  • 虽然你请求的是 image.jpg

  • 但是它在 S3 或缓存中找到了对应的 image.avif

  • 返回的时候,偷偷换了资源文件,返回的是 AVIF 内容

  • 当用户下次访问时,因找不到旧的 AVIF 图片,系统会根据新的源图重新生成新的 AVIF 文件并返回。

  • 从而确保用户访问到的永远是最新版本的图片内容。

  •  返回的 HTTP 响应里,重要的是Content-Type 头:

Content-Type: image/avif

浏览器收到的是一个 AVIF 格式的数据,虽然 URL 还是 .jpg,但实际上它知道应该用 AVIF 解码来展示。

为什么下载下来是 AVIF?

  • 你点右键下载时,浏览器是根据返回的 Content-Type 类型来确定文件格式的,不是根据 URL 后缀。

  • Content-Type: image/avif,所以浏览器保存成了 .avif 文件,即使链接上还是 .jpg

  • 浏览器内部已经知道这张图实际上是 AVIF 格式了。

总结一句话:

请求是 JPG,返回是 AVIF,靠的是 HTTP Content-Type,浏览器根据返回类型进行识别和保存。

五、补充说明

  • 动态生成 AVIF 图片一般通过 AWS Lambda@Edge 来实现,支持实时生成并自动回写存储。

  • 项目如果对首屏加载性能要求极高,可以结合 CDN 对 AVIF 图片进行缓存加速。

  • 建议统一规范图片命名,避免因频繁重名导致过多历史资源堆积,影响桶管理效率。

要通过 AWS Lambda@Edge 动态把 S3 上的 PNG、JPG 转成 AVIF 图片,基本思路是:

  • 拦截图片请求(比如 .jpg、.png)

  • 判断浏览器 Accept 请求头是否支持 image/avif

  • 如果支持:

  • 查询 S3 中是否已有对应 .avif 文件

  • 如果没有,就实时读取源图,转码成 .avif,存回 S3,再返回

  • 如果不支持:

  • 直接返回原图

下面是一个简单版的 Node.js(AWS Lambda@Edge)脚本示例:

const AWS = require('aws-sdk');
const sharp = require('sharp'); // sharp 用于图片处理// S3 客户端
const s3 = new AWS.S3({ region: 'your-bucket-region' });const BUCKET = 'your-bucket-name';exports.handler = async (event, context, callback) => {const request = event.Records[0].cf.request;const headers = request.headers;const uri = request.uri;console.log('Request URI:', uri);// 只处理 jpg/png 请求if (!uri.match(/\.(jpg|jpeg|png)$/i)) {return callback(null, request);}// 检查浏览器是否支持 AVIFconst acceptHeader = headers['accept'] ? headers['accept'][0].value : '';const supportsAvif = acceptHeader.includes('image/avif');if (!supportsAvif) {// 不支持 AVIF,直接返回原图console.log('Browser does not support AVIF');return callback(null, request);}// 构造 avif 文件的路径const avifUri = uri.replace(/\.(jpg|jpeg|png)$/i, '.avif');try {// 先检查 AVIF 是否已经存在await s3.headObject({Bucket: BUCKET,Key: decodeURIComponent(avifUri).substring(1), // 去掉开头的 /}).promise();// 已存在,修改请求路径,返回 avifconsole.log('AVIF exists, serving AVIF');request.uri = avifUri;return callback(null, request);} catch (error) {if (error.code !== 'NotFound') {// 其他异常console.error('Error checking AVIF file:', error);return callback(error);}console.log('AVIF not found, generating dynamically');// AVIF 不存在,读取源图const originImage = await s3.getObject({Bucket: BUCKET,Key: decodeURIComponent(uri).substring(1),}).promise();// 用 sharp 转 AVIFconst avifBuffer = await sharp(originImage.Body).avif({ quality: 50 }).toBuffer();// 写回 S3,生成新的 AVIF 文件await s3.putObject({Bucket: BUCKET,Key: decodeURIComponent(avifUri).substring(1),Body: avifBuffer,ContentType: 'image/avif',CacheControl: 'public, max-age=31536000', // 设置长缓存}).promise();// 修改请求路径,返回新的 AVIFrequest.uri = avifUri;return callback(null, request);}
};

相关文章:

如何在 AWS 上构建支持 AVIF 的前端图片优化方案

一、为什么使用 AVIF 图片格式? 优势点 说明 高压缩率 在相似质量下,AVIF 文件比 JPEG/PNG/WebP 更小,能有效节省带宽和存储空间。 更高画质 即使在低码率下也能保持清晰细节,减少压缩带来的马赛克或模糊问题。 支持透明度 …...

Linux系统进行环境开发环境配置

一. 使用fishros(鱼香肉丝)配置开发环境 对于初学者来说,最难的关卡莫非是开发环境的的搭建,特别是在Ubuntu系统上ROS系统安装时后出现的各种报错以及失败,本篇博客讲述了ROS系统的一键安装过程,适用于18.04及以后的Ubuntu系统版本…...

前端npm的核心作用与使用详解

一、npm是什么? npm(Node Package Manager) 是 Node.js 的默认包管理工具,也是全球最大的开源代码库生态系统。虽然它最初是为 Node.js 后端服务设计的,但如今在前端开发中已成为不可或缺的基础设施。通过npm,开发者可以轻松安装、管理和共享代码模块。 特性: 依赖管理…...

软考软件评测师——软件工程之系统维护

一、系统质量属性 可维护性 衡量软件系统适应修改的难易程度,包括修复缺陷、扩展功能或调整规模的效率。计算公式为:系统可用时间占比 1/(1平均修复时间),其中平均修复时间(MTTR)指排除故障所需的平均耗时。 可靠性 vs 可用性 可靠性&…...

CSRF攻击 + 观测iframe加载时间利用时间响应差异侧信道攻击 -- reelfreaks DefCamp 2024

参考: https://0x90r00t.com/2024/09/30/3708/ 题目信息 有些事情最好还是保持低调。当然,除非你是个真正的怪胎。 注意:该网站通过HTTPS提供服务 标志格式:DCTF{}题目实现了一个类似视频网站的东西 在其提供的数据库中…...

火山RTC 8 SDK集成进项目中

一、SDK 集成预备工作 1、SDK下载 https://www.volcengine.com/docs/6348/75707 2、解压后 3、放在自己项目中的位置 1)、include 2)、lib 3)、dll 暂时,只需要VolcEngineRTC.dll RTCFFmpeg.dll openh264-4.dll, 放在intLive2…...

spring boot Controller 和 RestController 的区别

spring boot Controller 和 RestController 的区别 5.3.1常用注解 Spring MVC控制器中常使用的注解有如下几种。 Controller Controller 标记在类上。使用Controller 标记的类表示是Spring MVC的Controller对象。分发处理器将会扫描使用了该注解的类,并检测其中的…...

mavgenerate 在 win11 下环境搭建注意问题

开发随笔 mavgenerate 是mavlink配套的协议生成工具,mavgenerate 在 win11 下环境搭建注意问题: 1、Python 就使用文件包当中的版本,由于python 版本能与 future 及 pip 之间存在特定的组合关系,故不推荐下载使用最新版本 2、安…...

SSM项目集成redis、Linux服务器安装redis

在SSM(Spring Spring MVC MyBatis)项目中引入Redis主要分为以下步骤,确保配置正确并能在业务中灵活使用: 1. 添加Redis依赖​​ 在Maven的pom.xml中添加Spring Data Redis和Jedis(或Lettuce)依赖&#…...

sqli-labs靶场第七关——文件导出注入

一:目标 通过sql注入将php代码写入网站目录,通过这个php文件执行命令 二:确认前置条件 %secure_file_priv% 首先我们需要Mysql是否允许导出文件 先尝试在网页中sql注入,检查导出权限 ?id1)) union select 1,secure_file_pr…...

python使用matplotlib无法显示中文字体报错

python使用matplotlib字体报错 当我们使用python使用matplotlib总是出现报错,图片中文变成方框 findfont: Font family WenQuanYi Micro Hei not found. findfont: Font family Heiti TC not found. findfont: Font family [SimHei] not found. Falling back to De…...

VTEP是什么

VTEP(VXLAN Tunnel Endpoint,VXLAN 隧道端点)是 VXLAN(Virtual Extensible LAN)网络中的关键组件,用于处理 VXLAN 流量的封装和解封装。以下以可读的 Markdown 格式详细解释 VTEP 的定义、功能、实现方式以…...

React Native简介

React Native 是由 Meta(原 Facebook)开源的跨平台移动应用开发框架,基于 React 和 JavaScript,允许开发者使用同一套代码库构建 iOS 和 Android 原生应用。通过 JavaScript 调用原生组件实现高性能渲染。 跨平台开发 共享 80%-9…...

边缘计算模块

本文来源 :腾讯元宝 边缘计算模块是一种部署在网络边缘(靠近数据源)的集成化硬件/软件设备,用于实时处理本地数据,减少云端依赖,提升响应速度与安全性。以下是其核心要点: ​​1. 核心组成​​ …...

策略模式-枚举实现

策略模式的实现方法有很多,可以通过策略类if,else实现。下面是用枚举类实现策略模式的方法。 定义一个枚举类,枚举类有抽象方法,每个枚举都实现抽象方法。这个策略,实现方法是工具类的很实现,代码简单好理解 枚举实现…...

C++算法(22):二维数组参数传递,从内存模型到高效实践

引言 在C程序设计中,二维数组的参数传递是许多开发者面临的棘手问题。不同于一维数组的相对简单性,二维数组在内存结构、类型系统和参数传递机制上都存在独特特性。本文将深入探讨静态数组、动态数组以及STL容器三种实现方式,通过底层原理分…...

LeetCode LCR 015. 找到字符串中所有字母异位词 (Java)

LCR 015. 找到字符串中所有字母异位词 题目描述 给定两个字符串 s 和 p,要求找到 s 中所有是 p 的变位词(字母相同但排列不同)的子串,并返回这些子串的起始索引。例如: 输入 s "cbaebabacd", p "a…...

幼儿学前教育答辩词答辩技巧问题答辩自述稿

### 📘《幼儿园大班活动开展存在的问题及解决策略》📝 我的论文题目是《幼儿园大班活动开展存在的问题及解决策略》📖。我将从论文框架、研究内容、需要解决的问题、研究结论这四部分来阐述我的论文📝。 论文框架由绪论&#x1f4…...

双目立体视觉

文章目录 1,前言2,原理3,组成部分3.1,数字图像采集。3.2 ,相机标定。3.3,图像预处理与特征提取。3.4 ,图像校正。3.5 ,立体匹配。3.6 ,三维重建。 4,主要的算…...

机器人弧焊二八混合气体节约

焊接技术在现代工业生产中作为关键环节之一,其效率和成本直接影响到整个制造流程的经济性与环保性。近年来,随着节能减排理念深入人心,各行业都在积极探索绿色制造方案。在焊接领域,二八混合气体的应用结合WGFACS智能流量调节系统…...

Linux进程通讯和原子性

在Linux系统中,进程间通信(IPC)和原子性是并发编程中的核心问题。以下是对这些概念的详细分步解释: 一、进程间通信(IPC)方法 1. 管道(Pipe) 匿名管道:用于父子进程等有…...

深度学习之用CelebA_Spoof数据集搭建一个活体检测-一些模型训练中的改动带来的改善

实验背景 在前面的深度学习之用CelebA_Spoof数据集搭建一个活体检测-模型搭建和训练,我们基于CelebA_Spoof数据集构建了一个用SqueezeNe框架进行训练的活体2D模型,采用了蒸馏法进行了一些简单的工作。在前面提供的训练参数中,主要用了以下几…...

Oracle APEX IR报表列宽调整

1. 问题:如何调整Oracle APEX IR报表列宽 1-1. 防止因标题长而数据短,导致标题行的文字都立起来了,不好看。 1-2. 防止因数据太长而且中间还没有空格,把列撑开的太宽也不换行,不好看。 2. 解决办法 针对如上问题解…...

6大核心记忆方法

以下是结合脑科学原理和高效学习策略总结的 6大核心记忆方法,帮助你摆脱“学完就忘”的困境: 一、间隔重复与分散学习 遵循艾宾浩斯遗忘曲线:学习后20分钟遗忘58%,1天后遗忘66%。通过设定复习节点(如学后1天、3天、1周…...

conda更换清华源

1、概览 anaconda更换速度更快、更稳定的下载源,在linux环境测试通过。 2、conda源查看 在修改之前可以查看下现有conda源是什么,查看conda配置信息,如下: cat ~/.condarc 可以看到你的conda源,以我的conda源举例&am…...

5月15日星期四今日早报简报微语报早读

5月15日星期四,农历四月十八,早报#微语早读。 1、中国至越南河内国际道路运输线路正式开通; 2、免签国1,中乌(兹别克斯坦)互免签证协定6月生效; 3、杭州“放大招”支持足球发展:足…...

网络损伤仪功能介绍与应用场景剖析

以下是关于 网络损伤仪(Network Impairment Emulator) 的核心功能介绍及其应用场景的详细说明: 一、网络损伤仪的核心功能 带宽限制(Bandwidth Throttling) 模拟不同网络带宽(如从1Mbps到10Gbps&#xff09…...

超时检测机制和心跳包机制(Heartbeat)

一、超时检测机制 1. I/O 函数超时设置 1.1 select/poll/epoll 的超时参数 select c struct timeval timeout {3, 0}; // 3秒超时 int n select(maxfd1, &readfds, NULL, NULL, &timeout); if (n 0) printf("select timeout\n"); // 超时无事件poll c …...

经典卷积神经网络

目录 经典卷积神经网络 一、卷积神经网络基础回顾 二、LeNet:开启 CNN 先河 三、AlexNet:突破性进展 四、ZFNet:继承与优化 五、GoogLeNet:引入 Inception 模块 六、VggNet:深度与简单结构的融合 七、ResNet&a…...

Reactor模型详解与C++实现

Reactor模型详解与C实现 一、Reactor模型核心思想 Reactor模式是一种事件驱动的并发处理模型,核心通过同步I/O多路复用实现对多个I/O源的监听,当有事件触发时,派发给对应处理器进行非阻塞处理。 关键特征: 非阻塞I/O&#xff…...

观测云产品更新 | 安全监测、事件中心、仪表板AI智能分析等

观测云更新 安全监测 新增 SIEM 功能模块:实时分析企业各类系统(如服务器、应用、网络设备)的日志和事件数据,自动发现潜在威胁,帮助团队迅速定位异常,充分发挥安全监控中枢的作用。 注意:目…...

【HTML】个人博客页面

目录 页面视图​编辑 页面代码 解释&#xff1a; HTML (<body>): 使用了更加语义化的HTML5标签&#xff0c;例如<header>, <main>, <article>, <footer>。文章列表使用了<article>包裹&#xff0c;结构清晰。添加了分页导航。使用了Font…...

OrangePi Zero 3学习笔记(Android篇)10 - SPI和从设备

目录 1. 配置内核 2. 修改设备数 3. 修改权限 4. 验证 Zero 3的板子有2个SPI Master接口&#xff0c;其中SPI0接的是板载16MB大小的SPI Nor Flash&#xff0c;SPI1则是导出到26pin的接口上。 spi和i2c有点不同&#xff0c;spi是直接生成spi虚拟设备&#xff0c;所以在dev里…...

《Java 大视界——Java 大数据在智能电网分布式能源协同调度中的应用与挑战》

随着风电、光伏等分布式能源大规模接入电网&#xff0c;传统调度系统面临数据规模激增、响应延迟显著、多源异构数据融合困难等核心问题。本文聚焦Java生态下的大数据技术体系&#xff0c;深入探讨其在智能电网实时监测、负荷预测、资源优化配置等场景中的落地实践。通过分析Sp…...

基于正点原子探索者开发板的简易音乐播放器

1、概述 本次实验的名称叫做“基于正点原子探索者开发板的简易音乐播放器”。本实验的功能框图如下&#xff1a; 从图上我们可以清晰的看到本实验所需的实现的功能、以及每个功能需要怎么实现。 这次实验使用的是正点原子的探索者开发板&#xff0c;此开发板采用的MCU是STM32F4…...

【CF】Day59——Codeforces Round 914 (Div. 2) D

D. Set To Max 题目&#xff1a; Easy 思路&#xff1a; 简单题 由于题目的数据给的很小&#xff0c;所以我们可以用 n 的复杂度过&#xff0c;那我们来观察一下我们应该怎么操作 显然&#xff0c;如果 a[i] > b[i] 时是无法构造的&#xff0c;同时 a[i] b[i] 时就不用管…...

【Linux专栏】Linux进程间关系和守护进程

文章目录 1、进程间关系1.1 进程组1.2 组长进程 2、会话&#xff1f;2.1 查看会话2.2 创建会话 3、控制终端4、作业控制4.1 前台/后台进程 5、守护进程5.1 如何创建守护进程&#xff1f;5.2 杀掉守护进程 1、进程间关系 主要描述两个名称概念&#xff1a;即进程组和组长进程。…...

AutoVACUUM (PostgreSQL) 与 DBMS_STATS.GATHER_DATABASE_STATS_JOB_PROC (Oracle) 对比

AutoVACUUM (PostgreSQL) 与 DBMS_STATS.GATHER_DATABASE_STATS_JOB_PROC (Oracle) 对比 核心功能对比 特性PostgreSQL AutoVACUUMOracle GATHER_DATABASE_STATS_JOB_PROC主要目的空间回收 统计信息更新仅优化器统计信息收集底层机制MVCC(多版本并发控制)维护CBO(基于成本的…...

go依赖查询工具之godepgraph(分析main.go的依赖树)

文章目录 go依赖查询工具之godepgraph&#xff08;分析main.go的依赖树&#xff09;什么是服务间的隐式耦合&#xff1f;分析main.go的依赖树方法1. godepgraph (配合 Graphviz 可视化) - 最直观【推荐】方法2. go list go依赖查询工具之godepgraph&#xff08;分析main.go的依…...

市场差分探头信号输出形式的一些因素考量

在5G/6G通信、新能源汽车电控等高频测量场景中&#xff0c;差分探头的信号输出架构直接影响测试系统的信噪比与可靠性。根据IEEE仪器与测量协会2024年度报告&#xff0c;单端输出方案的市场渗透率较2020年提升42%&#xff0c;这一趋势背后蕴含着深刻的技术变革逻辑。 一、核心…...

SQL练习——day01

力扣——SQL练习总结 DENSE_RANK()窗口函数 这是排名函数的一种&#xff0c;它在处理相同值时&#xff0c;会给相同的值分配相同的排名&#xff0c;并且后续的排名不会跳过。比如有三个分数并列第一&#xff0c;那么它们的排名都是 1&#xff0c;接下来的分数排名就是 2&#…...

断点续传使用场景,完整前后端实现示例,包括上传,下载,验证

断点续传在多个场景中非常有用&#xff0c;包括但不限于大文件上传、跨国或跨区域文件传输、移动设备文件传输、备份和同步以及软件更新等。接下来&#xff0c;我将为你提供一个基于Java的后端实现示例&#xff0c;结合前端逻辑来完成整个断点续传的功能&#xff0c;包括上传、…...

Xinference推理框架

概述 GitHub&#xff0c;官方文档。 核心优势 性能优化&#xff1a;通过vLLM、SGLang等引擎实现低延迟推理&#xff0c;吞吐量提升2-3倍&#xff1b;企业级支持&#xff1a;支持分布式部署、国产硬件适配及模型全生命周期管理&#xff1b;生态兼容&#xff1a;无缝对接LangC…...

技术更新频繁,团队如何适应变化

构建持续学习机制、引入技术雷达与预研机制、通过敏捷方法快速响应变化、推动跨团队知识协作与传承 是应对技术更新频繁、团队保持适应力的核心策略。其中&#xff0c;构建持续学习机制尤为关键。通过制度化、场景化的学习安排&#xff0c;团队可以主动追踪新技术趋势&#xff…...

解密企业级大模型智能体Agentic AI 关键技术:MCP、A2A、Reasoning LLMs-MCP大模型上下文解析

解密企业级大模型智能体Agentic AI 关键技术&#xff1a;MCP、A2A、Reasoning LLMs-MCP大模型上下文解析 我们首先来看一下 整个MCP的一个基本的一个流程&#xff0c;他解决的一个问题。我们回到这里&#xff0c;他解决的一个问题是什么呢&#xff1f;他解决这个问题就是你的大…...

游戏代码混淆的作用与应用分析

1. 防止逆向工程 核心保护对象&#xff1a;游戏引擎、算法&#xff08;如物理模拟、AI行为树&#xff09;、加密逻辑等。实例&#xff1a;Unity游戏使用 ConfuserEx 混淆C#代码&#xff0c;使反编译工具&#xff08;如dnSpy&#xff09;只能显示杂乱命名&#xff0c;难以理解逻…...

信息系统运行管理员:临阵磨枪版

信息系统运行管理员考试 - 全覆盖详细背诵大纲 (根据考情分析和原始材料&#xff0c;力求完整覆盖考点细节) 第一部分&#xff1a;基础知识与运维概览 Chapter 1: 信息系统运维概述 (上午题 5分) 信息&#xff1a; 含义&#xff1a;香农 - 减少随机不确定性的东西&#xff1b…...

PWM(脉宽调制)的配置参数[预分频器\自动重载值]的自动计算

文章目录 前言一、数据结构二、二分法搜索最佳预分频器和自动重载值三、示例 前言 pwm是嵌入式开发过程中很常见的一个模块&#xff0c;而配置pwm的过程中就少不了频率参数的计算&#xff0c;大多数32位机的pwm频率都由时钟、预分频器&#xff08;prescaler&#xff09;、自动…...

manuskript开源程序是面向作家的开源工具

一、软件介绍 文末提供程序和源码下载 manuskript开源程序是面向作家的开源工具&#xff0c;Manuskript 可在 GNU/Linux、Mac OS X 和 Windows 上运行。 二、Features 特征 Manuskript provides a rich environment to help writers create their first draft and then furt…...

antd 主题色定制

定制方案&#xff1a; 1. 全局定制 整个应用范围内的组件都生效 全局文件 theme.css :root:root {--adm-color-primary: #a062d4; } antd-mobile 中的主题变量也是在 :root 下声明的&#xff0c;所以在有些情况会由于优先级的问题无法覆盖。通过 :root:root 显式地让你所…...