You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Chart.js渐变背景浏览器缩放时显示异常问题解决方案

问题描述

使用Chart.js开发图表时配置了渐变背景效果,浏览器缩放比例为100%时渐变背景显示完全正常;但通过快捷键Ctrl++或Ctrl+-调整浏览器缩放比例后,渐变背景无法适配缩放后的画布尺寸,显示效果异常。

复现代码

HTML 代码

<div>
  <canvas id="myChart"></canvas>
</div>

JavaScript 代码

const labels = [
  'January',
  'February',
  'March',
  'April',
  'May',
  'June',
];

const data = {
  labels: labels,
  datasets: [{
    label: 'My First dataset',
    backgroundColor: 'rgb(255, 99, 132)',
    borderColor: 'rgb(255, 99, 132)',
    data: [0, 10, 5, 2, 20, 30, 45],
  }]
};

const plugin_gradient = {
  beforeDraw: function(chart, args, options) {
    const ctx = chart.ctx;
    const canvas = chart.canvas;
    const chartArea = chart.chartArea;
    var gradientBack = canvas.getContext("2d").createLinearGradient(0, canvas.height, canvas.width, 0);
    gradientBack.addColorStop(1, "rgba(255, 120, 120, 1)");
    gradientBack.addColorStop(.5, "rgba(255, 255, 120, 1)");
    gradientBack.addColorStop(0, "rgba(120, 255, 120, 1)");
    ctx.fillStyle = gradientBack;
    ctx.fillRect(chartArea.left, chartArea.bottom, chartArea.right - chartArea.left, chartArea.top - chartArea.bottom);
  }
};

const config = {
  type: 'line',
  data: data,
  plugins: [plugin_gradient],
  options: {}
};

const myChart = new Chart(
  document.getElementById('myChart'),
  config
);

问题原因

该异常的核心诱因是浏览器缩放时,Canvas的实际渲染像素尺寸和DOM层面读取到的canvas.width/canvas.height属性值存在缩放倍率差。原有代码创建渐变时直接取用了整个Canvas的宽高作为渐变起止坐标,但实际填充渐变的区域是图表内部的chartArea范围,二者坐标不匹配,缩放后偏差会被放大,最终导致渐变显示错位。

修复方案

调整渐变创建逻辑,让渐变的起止坐标和实际填充矩形的坐标范围完全对齐,不再使用整个Canvas的宽高生成渐变,修改后的渐变插件代码如下:

const plugin_gradient = {
  beforeDraw: function(chart, args, options) {
    const ctx = chart.ctx;
    const { chartArea } = chart;
    // 渐变坐标与填充区域坐标完全对齐,自动适配任意缩放比例
    const gradientBack = ctx.createLinearGradient(
      chartArea.left,
      chartArea.bottom,
      chartArea.right,
      chartArea.top
    );
    gradientBack.addColorStop(1, "rgba(255, 120, 120, 1)");
    gradientBack.addColorStop(0.5, "rgba(255, 255, 120, 1)");
    gradientBack.addColorStop(0, "rgba(120, 255, 120, 1)");
    
    ctx.save();
    ctx.fillStyle = gradientBack;
    ctx.fillRect(
      chartArea.left,
      chartArea.bottom,
      chartArea.right - chartArea.left,
      chartArea.top - chartArea.bottom
    );
    ctx.restore();
  }
};

修复说明

  • 渐变生成的坐标范围与后续填充矩形的范围完全一致,从根源上避免缩放带来的坐标偏移
  • 新增ctx.save()和ctx.restore()逻辑,避免自定义填充样式污染Chart.js后续的图表元素绘制流程
  • 无需额外监听浏览器缩放事件,Chart.js在缩放触发重绘时会自动执行beforeDraw钩子,实时适配最新的画布尺寸。

内容的提问来源于stack exchange,提问作者mickna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 01:09:57