Flutter Slider自定义形状:用Shape实现菱形/宝石滑块
如果你接手过一个“把滑块改成菱形”的需求大概率和我一开始一样先找找有没有thumbColor、borderRadius之类的参数结果发现无论怎么调滑块始终是那个标准的圆。我前几个月在一个画板类项目里就遇到过这种事UI 给的稿子是一个蓝紫色渐变、倒角明显的宝石状滑钮。我第一反应是去改Slider的thumbColor等真机一跑才发现轨道两端确实换了新颜色但最关键的滑钮还是那个圆。后来翻了源码才明白Flutter 的Slider并不是一个由Container、Icon拼出来的组合组件它本质上是一个自绘组件整个外观全靠Canvas画出来。你想改的颜色只是主题里的几个色值而真正的“形状”全部由藏在SliderThemeData里的一组 Shape 对象决定。这篇文章会把这些 Shape 一层层拆开它们分别是谁、默认长什么样、为什么可以控制外观以及怎么动手写一个完全自定义的滑块形状。适合两种人看一种是像我当时一样被 UI 稿逼着改原生滑块外观的客户端开发者另一种是刚接触 Flutter 自绘体系、想搞清楚SliderComponentShape和SliderTrackShape区别的学习者。我会把实际踩过的坑也一起说了。1. 先搞清楚Slider里到底有哪些Shape1.1 从一次“圆形滑块改成方形”的失败说起先说那次失败过程。当时我第一招是SliderThemeData(thumbColor: Colors.amber)效果不错颜色变了但形状是圆。第二招想给滑块加个圆角矩形背景去查Slider的 API发现压根没有thumb或child这种可插拔的 widget 属性。第三招更蠢用Transform.scale包住整个Slider想把圆压成椭圆结果轨道也跟着变形了分分钟被设计打回。这些尝试的根源是我把Slider想成了一个“可组合控件”。实际上 Flutter 官方的Slider是一个典型的RenderObjectWidget它的外观不依赖 widget 树而是在paint阶段用 Canvas 一笔笔画出来的。既然外观来自绘制代码就要去动绘制那层的东西也就是主题里的 Shape。一个很反直觉的点是Slider 的轨道和滑块虽然显示在同一个组件里但它们用的不是同一个绘制接口。轨道走的是SliderTrackShape而滑块、覆盖层和刻度线走的是SliderComponentShape。这两个抽象类的方法签名和绘制坐标都不一样如果不分清楚后面写自定义形状会非常别扭。1.2 SliderThemeData里的Shape家族打开SliderThemeData的源码你会看到一大排以 Shape 结尾的字段。我直接列一张表字段名类型作用默认实现activeTrackShapeSliderTrackShape控制 thumb 左侧已选中轨道RoundedRectSliderTrackShape()inactiveTrackShapeSliderTrackShape控制 thumb 右侧未选中轨道RoundedRectSliderTrackShape()thumbShapeSliderComponentShape控制可拖动的滑钮外观RoundSliderThumbShape()overlayShapeSliderComponentShape控制按压时水波纹/外圈反馈RoundSliderOverlayShape()tickMarkShapeSliderTickMarkShape控制离散模式下刻度点RoundSliderTickMarkShape()使用时一般用SliderTheme包住目标Slider再通过copyWith只覆盖需要的字段。例如想换一个方形滑钮可以做SliderTheme( data: SliderTheme.of(context).copyWith( thumbShape: const CustomThumbShape(), ), child: Slider( value: _value, min: 0, max: 100, onChanged: (v) setState(() _value v), ), )注意activeTrackShape和inactiveTrackShape是分开的两个字段如果你只设置了activeTrackShape左边轨道变了右边轨道还是默认圆角矩形两边视觉对不上。1.3 Shape接口与绘制坐标系理解这两个抽象接口是核心。SliderTrackShape的职责是“在一段给定的轨道区域里画出轨道”它拿到的核心信息是一个RenderBox和一个thumbCenter偏移。SliderComponentShape的职责是“以某个点为中心画一个小部件”它拿到的核心信息是一个Offset center以及两个动画activationAnimation和enableAnimation。可以这样类比Slider是一块画板trackShape负责画底色和进度条thumbShape负责画一个可以在画板上移动的贴纸。贴纸的位置由 Slider 内部根据 value 算出来但你贴纸长什么样、多大、怎么旋转、怎么响应按压全由你自己的绘制代码决定。坐标系也值得说。SliderComponentShape.paint里的center是滑钮中心点不是左上角。所有绘制的Path、Canvas.drawCircle都要围绕这个center展开。你如果照着Rect.fromLTWH(0, 0, w, h)这种惯性写法画出来的东西会跑到滑块的左上角去怎么调都不对。2. 默认Shape源码拆解圆和方的出处2.1 RoundedRectSliderTrackShape的秘密默认轨道看起来就是一根 2 像素高的圆角矩形条但它其实是四个RRect拼出来的逻辑轨道被 thumb 分成了 active 和 inactive 两部分分别由activeTrackShape和inactiveTrackShape绘制。RoundedRectSliderTrackShape在绘制时会根据thumbCenter计算左右两段矩形再各自加上圆角。圆角半径不是写死的而是trackHeight / 2。所以当你把trackHeight从默认的 2 调大到 8轨道两端会自动变成半圆不需要额外处理。这里有个常见坑有人为了做“中间高两边细”的夸张轨道自己继承SliderTrackShape去画三角形或者曲线。但如果只改了形状没有考虑thumbCenter和左右偏移thumb 拖动时轨道端点会和滑块脱节。默认形状之所以可靠就是因为它精确计算了左右偏移而不是简单画一个全宽矩形。自定义时不要偷懒。2.2 RoundSliderThumbShape 为什么是正圆RoundSliderThumbShape的核心参数是enabledThumbRadius默认 10。它并不是简单地画一个drawCircle至少做了三件事先画底圆再画一个细边框最后根据activationAnimation做一个放大效果。源码里你还会看到它用Paint的maskFilter或colorFilter处理阴影这也是为什么默认滑块拖起来有轻微的“浮起感”。getPreferredSize对这个类来说也很关键。它会返回一个以enabledThumbRadius为半径的方形尺寸Slider 在布局时会用这个尺寸给滑块预留空间。如果你自定义的 shape 没有正确返回getPreferredSize滑块可能被裁切或者轨道两端多出奇怪的间隙。听完这些你应该意识到改写一个滑块形状本质不是“改图片”而是“实现一个会响应位置和动画的绘制函数”。2.3 Overlay与TickMark辅助Shape的作用overlayShape默认是RoundSliderOverlayShape它负责在按下时画出一圈更大更淡的圆用来提示“这个滑块可以拖动”。不仔细看会觉得它是阴影其实它是一个独立的绘制层颜色由overlayColor控制。tickMarkShape则只在divisions ! null的离散模式下出现。默认的RoundSliderTickMarkShape会在每个刻度点画一个半径为tickMarkRadius的实心圆颜色由activeTickMarkColor和inactiveTickMarkColor区分。如果你做的是音乐播放器进度条这种“不要刻度、只要连续滑动”的需求可以直接把 divisions 置空。3. 手搓一个自定义Slider Shape从菱形到心形3.1 实现SliderComponentShape的最小骨架现在我们动手实现一个菱形滑钮。先继承SliderComponentShape实现两个方法。不同 Flutter 版本的paint参数略有差异我按当前稳定版的常见写法来如果你的 SDK 编译报错打开项目里的slider_theme.dart对一下签名就行。import dart:ui as ui; import package:flutter/material.dart; class DiamondSliderThumb extends SliderComponentShape { final double size; final Color color; final Color borderColor; final double borderWidth; const DiamondSliderThumb({ this.size 24.0, required this.color, this.borderColor Colors.white, this.borderWidth 2.0, }); override Size getPreferredSize(bool isEnabled, bool isDiscrete) { return Size(size, size); } override void paint( Canvas canvas, Offset center, { required Animationdouble activationAnimation, required Animationdouble enableAnimation, required bool isDiscrete, required TextPainter labelPainter, required RenderBox parentBox, required SliderThemeData sliderTheme, required TextDirection textDirection, required double value, required double textScaleFactor, required Size sizeWithOverlay, }) { final half size / 2; final Path diamond Path() ..moveTo(center.dx, center.dy - half) ..lineTo(center.dx half, center.dy) ..lineTo(center.dx, center.dy half) ..lineTo(center.dx - half, center.dy) ..close(); final fillPaint Paint()..color color; final strokePaint Paint() ..color borderColor ..style PaintingStyle.stroke ..strokeWidth borderWidth; canvas.drawPath(diamond, fillPaint); canvas.drawPath(diamond, strokePaint); } }把thumbShape设置为DiamondSliderThumb(color: Colors.indigo)后就能看到滑块变成菱形。注意getPreferredSize一定要和size匹配否则轨道会按错误的尺寸预留空间。3.2 给Track换成双段渐变圆角轨道接下来把轨道也换掉。这里要继承SliderTrackShape。下面这个例子实现了一个带渐变色的圆角轨道左半段用两个颜色渐变右半段保持灰色。class GradientTrackShape extends SliderTrackShape { const GradientTrackShape(); override void paint( PaintingContext context, Offset offset, { required RenderBox parentBox, required SliderThemeData sliderTheme, required Animationdouble enableAnimation, required TextDirection textDirection, required Offset thumbCenter, Offset? secondaryOffset, bool isDiscrete false, bool isEnabled false, }) { final canvas context.canvas; final trackHeight sliderTheme.trackHeight; final trackRect Rect.fromLTWH( offset.dx, offset.dy (parentBox.size.height - trackHeight) / 2, parentBox.size.width, trackHeight, ); final inactivePaint Paint() ..color sliderTheme.inactiveTrackColor ?? Colors.grey.shade300; final radius Radius.circular(trackHeight / 2); // 先画右侧未选中部分 if (thumbCenter.dx trackRect.left) { final rightRect Rect.fromLTRB( thumbCenter.dx, trackRect.top, trackRect.right, trackRect.bottom, ); canvas.drawRRect( RRect.fromRectAndRadius(rightRect, radius), inactivePaint, ); } // 再画左侧选中部分使用渐变 if (thumbCenter.dx trackRect.left) { final leftRect Rect.fromLTRB( trackRect.left, trackRect.top, thumbCenter.dx, trackRect.bottom, ); final gradient ui.Gradient.linear( leftRect.bottomLeft, leftRect.bottomRight, [ Colors.blue, Colors.purple, ], ); final activePaint Paint()..shader gradient; canvas.drawRRect( RRect.fromRectAndRadius(leftRect, radius), activePaint, ); } } }这个实现刻意简化了左右两端圆角的处理当 thumb 靠近边界时左边圆角可能会显得不自然。真实的RoundedRectSliderTrackShape会分别处理左右圆角并且在 thumb 不在端点时使用本地圆角而不是全局radius。建议你把它当作启发式代码不要直接用于生产。3.3 形态组合做一个“宝石滑块”的完整主题把前面两个自定义 shape 通过SliderTheme组合起来SliderTheme( data: SliderTheme.of(context).copyWith( trackHeight: 6, activeTrackShape: const GradientTrackShape(), inactiveTrackShape: const GradientTrackShape(), thumbShape: const DiamondSliderThumb( size: 28, color: Color(0xFF5C6BC0), borderColor: Colors.white, ), overlayShape: const RoundSliderOverlayShape(overlayRadius: 22), ), child: Slider( value: _value, min: 0, max: 100, onChanged: (v) setState(() _value v), ), )这样做出来的滑块效果是宝石型滑钮、渐变轨道、按压时有圆形水波纹反馈。整个过程没有引入任何额外 widget也没有破坏 Slider 原生的手势和语义对比我之前用Stack手工拼接的方案干净得多。4. 实际项目中绕不开的三道坎4.1 点击命中区域与视觉形状不匹配自定义形状最容易踩的坑就是视觉上是一个细长的菱形但真正的点击区域却比视觉大很多或小很多。这背后的原因是 Slider 的命中判定并不基于你画的 Path而是基于 Slider 组件本身的布局矩形和材质规范里对最小点击尺寸的要求。Flutter 对可点击控件有一个默认的最小触摸目标大约是 48x48 逻辑像素。当你的 thumb 视觉尺寸很小比如size: 16Slider 内部并不会因此把命中区域缩小到 16它仍然会以整个轨道区域和高层的 Material 规则来决定手势是否命中。这导致两个极端体验要么视觉上滑块很小但用户轻轻点在轨道边缘也能拖到要么视觉滑块占了很大地方但真正能抓住的区域反而因为形状镂空而手感奇特。我的建议是getPreferredSize的返回值要比视觉尺寸稍微大一圈然后在paint里用center对齐绘制这样视觉居中但实际占位更稳健。另外把overlayRadius调大一些因为覆盖层不仅负责视觉反馈也间接扩大了用户对“可拖区域”的感知。4.2 形状动画与状态切换的同步默认滑块在按住时会有轻微放大的动画这个动画本质上来自activationAnimation。自定义 shape 如果不能感知这个动画就会给人一种“按了但没反应”的僵硬感。正确的做法是在paint里读取activationAnimation.value把它作为一个尺度因子应用到你自己的 Path 或 Canvas 变换上。比如前面画菱形可以这样接住动画final scale 1.0 0.15 * activationAnimation.value; canvas.save(); canvas.translate(center.dx, center.dy); canvas.scale(scale); canvas.translate(-center.dx, -center.dy); // 继续画菱形 canvas.restore();另一个容易忽略的是enableAnimation它对应滑块从禁用状态切换到启用状态时的淡入淡出。如果你画的 Path 里有自己的颜色记得把enableAnimation.value和颜色透明度乘一下否则禁用态滑块会显得特别突兀。4.3 无障碍与屏幕阅读器适配滑块换形状不意味着无障碍语义可以不管。默认情况下Slider内部已经包了一层Semantics会向屏幕阅读器播报 slider、value、min、max 等信息。但如果你在 thumb 内部绘制了文字或图标比如画了一个播放按钮、一个音量符号那么最好额外提供一个Semantics(label: 音量)或使用semanticFormatterCallback把数值格式化成更友好的文案。还有一个小细节自定义 thumb 尺寸如果小于建议的最小触摸目标部分屏幕阅读器在触点定位时可能会不准。我并不建议单纯为了无障碍把 thumb 做得特别大这会影响视觉。更合理的做法是把 overlay 的半径加大让视觉 thumb 保持精致但实际按压反馈半径足够。5. 不要急于封装设计决策和实用模板5.1 Shape方案 vs StackTransform手工方案很多团队遇到“滑块形状不符合默认组件”的第一反应是放弃 Slider用GestureDetectorStackPositioned手工做。这个方案不是不行但它至少要处理三件事手势换算从像素到数值、触摸边界判断、语义播报。每一项都不比写一个 Shape 简单。我个人的判断是静态形状、简单状态反馈优先做自定义 Shape如果需求里涉及复杂的组合动画比如拖拽时 thumb 内部还有多个元素的位移动画可以考虑保留原生 Slider 作为手势层同时把视觉层用ListenableBuilder叠加在上面。但即便如此你仍然需要把原生 thumb 的透明度降到接近零而不是直接拿掉 thumb shape因为 Slider 的一些布局和 HitTest 依赖 thumb 的存在。5.2 主题层级与覆盖陷阱使用SliderTheme时要注意继承关系。如果你在MaterialApp的theme里自定义了SliderThemeData又在某个局部页面用SliderTheme(data: SliderTheme.of(context).copyWith(thumbShape: ...))那这个局部的copyWith是在继承了父级全部配置的基础上只覆盖 thumbShape没问题。但如果你直接写SliderTheme(data: SliderThemeData(thumbShape: ...))没有先copyWith那父级的轨道颜色、高度、阴影全部会被重置成默认值。这个坑我在一个深色主题项目里遇到过局部页面只为了改滑钮颜色结果整个滑块从深色配色变成了亮色看起来像主题失效。排查很久才发现是SliderThemeData(...)的构造函数把所有未命名字段都设为了 null而copyWith才能保留父级设置。5.3 一个可复用的自定义Shape模板最后分享一个我平时复制频率很高的模板后续遇到“滑块要变成五角星”“变成三角形”“变成自定义图标”都可以套class TemplateSliderThumb extends SliderComponentShape { final double width; final double height; const TemplateSliderThumb({this.width 24, this.height 24}); override Size getPreferredSize(bool isEnabled, bool isDiscrete) { return Size(width, height); } override void paint( Canvas canvas, Offset center, { required Animationdouble activationAnimation, required Animationdouble enableAnimation, required bool isDiscrete, required TextPainter labelPainter, required RenderBox parentBox, required SliderThemeData sliderTheme, required TextDirection textDirection, required double value, required double textScaleFactor, required Size sizeWithOverlay, }) { // 从这里开始画所有坐标都基于 center final Path path Path(); // path.addPath(...); final paint Paint() ..color sliderTheme.thumbColor ?? Colors.blueGrey; canvas.drawPath(path, paint); } }拿到模板先别急着写代码我习惯先在纸上把坐标画出来。比如五角星每条边的夹角是 36 度三角形的高是宽的多少倍这些在纸上算清楚再写 Path效率远高于在真机上加print调坐标。测试时可以打开debugPaintSizeEnabled true看看组件实际占位能更直观地发现命中区域和视觉区域的偏差。这个模板后来在我项目里被反复改造成不同版本音频进度条的胶囊形、双端 RangeSlider 的左端箭头形、以及一个需要自定义标签浮层的版本。每次改动基本都是围绕paint里的 Path 和activationAnimation的处理核心结构不需要动。如果你正准备自定义 Flutter Slider希望这篇文章能帮你少走几步弯路。

相关新闻

同一篇论文AIGC检测各章AI率差很多:分段差异成因与逐章应对

同一篇论文AIGC检测各章AI率差很多:分段差异成因与逐章应对

一份AIGC检测报告摊开,有人看到摘要标红、材料方法却干净,也有人恰好相反——讨论章被标红,综述段落反而安静。同一份稿子,各章读数为何对不上?下面从章节写作惯例讲起,先说差异从哪来,再按章节…

2026/10/18 22:19:35 阅读更多 →
手把手教你从文献综述里提炼概念与概念关系,判断理论框架的推进方向

手把手教你从文献综述里提炼概念与概念关系,判断理论框架的推进方向

从读过的文献里找出站得住脚的概念,再理清彼此的联系,这一步做扎实,理论框架自然就有了骨架。下面按可复用的顺序拆开讲:在文献里定位概念,接着分层归类,随后判断关系类型,末了用判据校验方向。…

2026/10/18 22:19:35 阅读更多 →
AI鉴伪实战:从噪声指纹到融合特征的虚假图片鉴别

AI鉴伪实战:从噪声指纹到融合特征的虚假图片鉴别

AI鉴伪到底在鉴什么?一个机器视觉工程师的虚假图片鉴别实战笔记先说结论:虚假图片鉴别这块,很多人第一反应是“拿个二分类模型,真图打0,假图打1,不就完事了”。如果你真这么干,大概率会在验证集…

2026/10/18 22:19:35 阅读更多 →

最新新闻

Hermes Agent接入飞书:TaoToken统一Key打通消息与任务流

Hermes Agent接入飞书:TaoToken统一Key打通消息与任务流

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 23:13:21 阅读更多 →
Windows 下 Neo4j 5.25.1 安装配置与避坑指南

Windows 下 Neo4j 5.25.1 安装配置与避坑指南

简介:Neo4j社区版5.25.1的Windows安装包,面向在Windows环境下开发图数据库应用的开发者、技术团队及图数据库初学者。它解决的是复杂关联数据的高效存储与查询问题,适用于社交网络分析、推荐系统、欺诈检测、知识图谱构建等场景,社…

2026/10/18 23:13:21 阅读更多 →
Sharpe为负也值得学:读懂ml-quant-trading-synthetic-mlp的metrics.json回测指标与成本拖累

Sharpe为负也值得学:读懂ml-quant-trading-synthetic-mlp的metrics.json回测指标与成本拖累

【免费下载链接】ml-quant-trading-synthetic-mlp 项目地址: https://ai.gitcode.com/hf_mirrors/dddyym/ml-quant-trading-synthetic-mlp 点击查看 免费下载 新手第一次看量化交易项目的回测报告,最常见的困惑是:为什么这个模型的夏普比率&…

2026/10/18 23:13:21 阅读更多 →
大模型做视频的真相:五步流水线从代码到成片

大模型做视频的真相:五步流水线从代码到成片

1. 先厘清一个被标题带偏的认知:模型不产视频,产的是"可渲染的中间态"很多人第一次看到"用大模型做视频"这个说法,脑子里浮现的画面是:敲一句话,模型吐出一个 mp4 文件。我一开始也这么以为&#…

2026/10/18 23:13:21 阅读更多 →
DeepSeek Harness 插件化底座:从零搭建可扩展 Agent 系统

DeepSeek Harness 插件化底座:从零搭建可扩展 Agent 系统

1. 从"模型即产品"到"模型即底座"的认知转变过去两年,绝大多数人接触大模型的方式,是打开一个对话框,输入问题,等待回答。这种交互模式把模型本身当成了最终产品——你用的是"某个模型"&#xff0c…

2026/10/18 23:13:21 阅读更多 →
SINUMERIK STEP 7 Toolbox V16.0 配置加速器实战指南

SINUMERIK STEP 7 Toolbox V16.0 配置加速器实战指南

简介:本资源是西门子SINUMERIK数控系统专用编程工具箱SINUMERIK STEP 7 Toolbox V16-0的完整安装包,面向自动化工程师、数控系统调试人员及工业控制领域技术人员,用于高效开发、仿真与调试SINUMERIK平台下的PLC逻辑与运动控制程序。压缩包共1…

2026/10/18 23:12:20 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →