Chart.js 循环动画(loop)实战:让折线图数据点半径随 hover 无限往复

发布时间:2026/9/18 11:19:39
Chart.js 循环动画(loop)实战:让折线图数据点半径随 hover 无限往复
Chart.js 循环动画loop实战让折线图数据点半径随 hover 无限往复【免费下载链接】Chart.jsSimple HTML5 Charts using thetag项目地址: https://gitcode.com/gh_mirrors/ch/Chart.js本篇文章围绕 Chart.js 官方示例文档 docs/samples/animations/loop.md 展开深入讲解如何在折线图上利用animations配置的loop选项实现数据点半径radius在悬停hover期间无限往复循环的动画效果。你将掌握loop与duration、easing、脚本化Scriptable回调的组合用法理解其底层动画引擎Animation / Animator的工作机制并能在此基础上复刻出可交互的循环动画折线图。示例全景一段可运行的循环动画配置loop.md示例的核心是一个line类型的图表它对点元素的radius属性配置了循环动画同时通过hoverRadius、hoverBackgroundColor与interaction让悬停成为动画的触发条件。完整的配置如下// block:setup:1 const DATA_COUNT 7; const NUMBER_CFG {count: DATA_COUNT, min: -100, max: 100}; const labels Utils.months({count: DATA_COUNT}); const data { labels: labels, datasets: [ { label: Dataset 1, data: Utils.numbers(NUMBER_CFG), borderColor: Utils.CHART_COLORS.red, backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5), tension: 0.4, }, { label: Dataset 2, data: Utils.numbers(NUMBER_CFG), borderColor: Utils.CHART_COLORS.blue, backgroundColor: Utils.transparentize(Utils.CHART_COLORS.blue, 0.5), tension: 0.2, } ] }; // /block:setup // block:config:0 const config { type: line, data: data, options: { animations: { radius: { duration: 400, easing: linear, loop: (context) context.active } }, hoverRadius: 12, hoverBackgroundColor: yellow, interaction: { mode: nearest, intersect: false, axis: x }, plugins: { tooltip: { enabled: false } } }, }; // /block:config module.exports { actions: actions, config: config, };其中Utils是官方示例页的辅助工具模块见 docs/scripts/utils.jsUtils.months用于生成月份标签Utils.numbers生成随机数值序列Utils.CHART_COLORS提供预设颜色Utils.transparentize为颜色叠加透明度。需要注意这些Utils函数仅供示例页面演示使用官方在 docs/samples/utils.md 中明确声明其可能在不通知的情况下发生破坏性变更生产环境不应依赖。拆解动画核心loop选项与脚本化求值在 docs/configuration/animations.md 中animation命名空间options.animation定义了 4 个基础键名称类型默认值说明durationnumber1000一次动画持续的毫秒数easingstringeaseOutQuart使用的缓动函数delaynumberundefined动画开始前的延迟毫秒数loopbooleanundefined设为true时动画无限循环默认值可在源码 src/core/core.animations.defaults.js 中核实。这些键都是**可脚本化Scriptable**的——文档明确说明它们同样支持函数形式会在动画相关上下文中被求值。示例中正是利用了这一点将loop写成一个函数loop: (context) context.active这里的context.active表示当前元素是否处于激活active状态。当鼠标悬停到某个数据点附近时该元素被激活context.active为true于是loop解析为trueradius动画进入无限循环当鼠标移开、元素不再激活时loop解析为false动画随之停止并收束到目标值。从源码层面看脚本化选项的求值发生在 src/helpers/helpers.options.ts 的resolve函数中当配置值typeof value function时会以当前context作为参数调用它并用返回值作为最终配置。无限循环的底层原理Animation 的 tick 计算loop之所以能让动画“永不结束”关键在于 src/core/core.animation.js 中Animation.tick()的因子计算逻辑this._active from ! to (loop || (elapsed duration)); // ... factor (elapsed / duration) % 2; factor loop factor 1 ? 2 - factor : factor; factor this._easing(Math.min(1, Math.max(0, factor))); this._target[prop] this._fn(from, to, factor);其中from与to通过resolve链确定见 src/core/core.animation.jsto resolve([cfg.to, to, currentValue, cfg.from])优先取配置的to否则取目标新值再退回当前值或fromfrom resolve([cfg.from, currentValue, to])优先取配置的from否则取当前值再退回to。动画是否“存活”由loop || (elapsed duration)决定只要loop为真即使时间已经超过duration该动画仍然保持_active从而被动画器持续驱动。循环进度则由(elapsed / duration) % 2计算进度在[0, 2)之间往复当超过 1 时用2 - factor折返实现“正向播放 → 反向播放 → 正向播放……”的往复效果。这正是“循环动画”在数值层面的完整含义。update()方法src/core/core.animation.js则负责处理动画进行中的配置变更它会把剩余时间并入新的duration并重新解析from/to/loop使动画在被chart.update()打断后依然平滑衔接。谁在驱动循环Animator 与 requestAnimationFrame单次动画不会自己前进驱动它的是全局动画器 src/core/core.animator.js 中的单例Animatorstart(chart)将图表标记为运行中并计算所有动画项的最大duration随后通过_refresh()发起requestAnimFrame循环src/core/core.animator.js每一帧调用_update(date)对每个图表的每个动画项执行item.tick(date)只要有任一动画处于激活状态就触发chart.draw()重绘src/core/core.animator.js循环动画由于tick()中_active恒为真永远不会从items中被移除因此图表会被持续重绘——这就是悬停时数据点半径“脉冲式”跳动的直接原因。动画对象的创建与登记发生在 src/core/core.animations.js 的_createAnimations中它从配置的动画属性集合里取出cfg若cfg.duration为空则直接赋值不播动画否则新建Animation并交给animator.add()。configure()src/core/core.animations.js则会把options.animations下每个子配置的属性默认即键名也可用properties数组扩展注册到属性映射中。需要留意的是默认动画集合numbers覆盖[x, y, borderWidth, radius, tension]colors覆盖[color, borderColor, backgroundColor]见 src/core/core.animations.defaults.js。radius本来就在默认动画集合内示例中单独为radius声明loop配置是对默认行为的覆盖与强化。让循环随悬停启停hover 与 interaction 选项示例中另外三个关键配置共同决定了“什么时候触发循环”hoverRadius: 12, hoverBackgroundColor: yellow, interaction: { mode: nearest, intersect: false, axis: x }hoverRadius与hoverBackgroundColor是点元素Point的悬停态样式当元素处于 active 状态时其半径目标值变为 12、背景色变为黄色。其默认值可在 src/elements/element.point.tshoverRadius: 4以及 src/core/core.defaults.jshoverBackgroundColor默认取backgroundColor的悬停加深色中确认。而radius动画的to值正是悬停后的目标半径 12循环就在“当前半径 → 12”之间往复。interaction.mode: nearest表示选取离指针最近的数据点intersect: false表示不需要与元素精确相交只要指针在图表区域内即可命中axis: x限定按 x 轴方向比较距离。三者配合后鼠标在图表上水平移动时会激活 x 方向上最近的数据点从而驱动其半径循环动画。plugins.tooltip.enabled: false关闭默认提示框避免 tooltip 遮挡视觉焦点让循环动画成为唯一的主角。完整 tooltip 配置说明见 docs/configuration/tooltip.md。数据交互配套 actions 让演示更具实战性loop.md示例还提供了一组可点击触发的数据操作按钮展示动画配置在数据增删改场景下的表现Randomize为每个数据集重新生成-100 ~ 100的随机数据并调用chart.update()Add Dataset追加一个使用Utils.namedColor取色、Utils.transparentize半透明化的新数据集Add Data标签数 1并为每个数据集追加一个随机数据点Remove Dataset弹出最后一个数据集Remove Data先labels.splice(-1, 1)删除末尾标签再逐个dataset.data.pop()删除末尾数据点。这些操作都通过chart.update()触发一次新的渲染流程。由于Animations.update()src/core/core.animations.js会复用仍在运行的动画并调用其update()平滑重定向见 src/core/core.animation.js因此即使在循环动画进行中插入新数据图表也不会出现跳变。hoverRadius与hoverBackgroundColor属于点配置见 docs/configuration/elements.md标签数据结构的说明见 docs/general/data-structures.md折线图的完整选项见 docs/charts/line.md。进阶从 loop 到更丰富的动画编排loop只是 Chart.js 动画体系的一个入口。基于同样的配置模型你还可以在 docs/configuration/animations.md 的指导下继续扩展属性级动画在animations下为x、y、tension、borderWidth、颜色等属性分别配置duration、easing、from、to甚至用properties数组让一份配置同时作用于多个属性过渡transitions内置active、hide、reset、resize、show五种模式例如show模式会让颜色从透明淡入active模式将 hover 动画时长覆盖为 400ms见 src/core/core.animations.defaults.js禁用动画将chart.options.animation false即可整体关闭对单个属性设为false或把duration置为 0 则只禁用对应动画见 docs/configuration/animations.md缓动函数除linear外还内置 30 余种 Robert Penner 缓动方程easeInOutQuad、easeOutBack、easeInElastic等完整清单见 docs/configuration/animations.md具体实现在 src/helpers/helpers.easing.ts回调钩子animation.onProgress与animation.onComplete可用于把外部绘制与动画进度同步回调对象含chart、currentStep、initial、numSteps字段示例可参考 docs/samples/advanced/progress-bar.md。掌握了loop与脚本化回调、interaction 的配合方式你就能把 Chart.js 的默认动画改造成各类“呼吸灯”“脉冲点”“循环张力”等动态效果——从 docs/samples/animations/loop.md 出发结合 docs/configuration/animations.md 的完整配置参考与 src/core/core.animation.js 的源码细节即可按需复刻与定制。【免费下载链接】Chart.jsSimple HTML5 Charts using thetag项目地址: https://gitcode.com/gh_mirrors/ch/Chart.js创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考