如何将径向 CanvasGradients 与 Chart.js 的圆环图一起使用?

我正在尝试创建两个径向渐变以与Charts.js 圆环图一起使用。

渐变应该看起来有点像下图,但是是红色的。

http://img3.sycdn.imooc.com/64b8fb210001347802700271.jpg

createRadialGradient使用普通 javascript 和 DOM创建渐变 ( ) 非常简单,如下面的代码片段所示:


'use strict'


const red = "hsla(1, 73.7%, 38.8%, 1)"

const redDark = "hsla(1, 60%, 30%, 1)"

const redDarker = "hsla(1, 20%, 20%, 1)"

const redLight = "hsla(1, 73.7%, 48%, 1)"


const canvasList = document.querySelectorAll('canvas.vanilla')


var {ctx, gradient} = createGradient1(canvasList[0].getContext('2d'))

ctx.fillStyle = gradient

drawRect(ctx)


var {ctx, gradient} = createGradient1(canvasList[1].getContext('2d'))

ctx.strokeStyle = gradient

ctx.lineWidth = 42

drawArc(ctx)


var {ctx, gradient} = createGradient2(canvasList[2].getContext('2d'))

ctx.fillStyle = gradient

drawRect(ctx)


var {ctx, gradient} = createGradient2(canvasList[3].getContext('2d'))

ctx.strokeStyle = gradient

ctx.lineWidth = 42

drawArc(ctx)


function createGradient1 (ctx) {

    // The inner circle is at x=110, y=90, with radius=30

    // The outer circle is at x=100, y=100, with radius=70

    // ctx.createRadialGradient(x0, y0, r0, x1, y1, r1)

    const gradient = ctx.createRadialGradient(100,100,31, 100,100,70);


    // Add three color stops

    const innerColor = redDark

    const mainColor = red

    const outerColor = redLight

    gradient.addColorStop(0, innerColor);

    gradient.addColorStop(.04, innerColor);

    gradient.addColorStop(.05, mainColor);

    gradient.addColorStop(1, outerColor);


    return { ctx, gradient }

}

但是当我将相同的 2 个渐变应用于Charts.js时,我得到一个灰色的甜甜圈。使用单一梯度不会改变结果。但是,使用两种 Hsla 颜色可以按预期工作 ( red"white")。



ABOUTYOU
浏览 134回答 1
1回答

慕村225694

问题在于渐变填充样式实际应用于甜甜圈的方式。你和我最初的假设是,chart.js 将负责定位渐变并将其缩放到适当的大小以填充甜甜圈。嗯,事实并非如此。相反,它使用画布上渐变的大小和位置。为了更好地理解,让我们看一下其中一个渐变的代码:const red = "hsla(1, 73.7%, 38.8%, 1)"const gradient = ctx.createRadialGradient(100,100,31, 100,100,70);const innerColor = "hsla(1, 60%, 30%, 1)"const mainColor = redconst outerColor = "hsla(1, 73.7%, 48%, 1)"gradient.addColorStop(0, innerColor);gradient.addColorStop(.04, innerColor);gradient.addColorStop(.05, mainColor);gradient.addColorStop(1, outerColor);这将在 x=100 和 y=100 处产生直径为 140 像素的渐变,如下所示:现在,如果我们进一步挖掘并假设您绘制的实际画布的大小是 797 x 419 像素,我们可以看到问题:渐变完全脱离了甜甜圈的形状!为了解决这个问题,渐变需要位于甜甜圈的中心,并且具有适当的大小以完全填充它。有点像这样:这说起来容易做起来难,因为最初我们不知道画布的确切大小,因为 Chart.js 会自动拉伸它以填充浏览器窗口。因此,我们可以采取以下解决方法:使用 Chart.js 创建甜甜圈,但先不要填充它等到 Chart.js 触发调整大小事件以获取画布的实际大小根据画布的大小计算渐变的尺寸并将其绘制在中心最后用渐变填充甜甜圈的背景颜色这是一个示例(请以“全页”运行,因为我们在 stackoverflow 的迷你预览框架中没有获得正确的窗口大小):const canvas = document.querySelector('.d-goal--canvas');const ctx = canvas.getContext('2d')const red = "hsla(1, 73.7%, 38.8%, 1)"let gradient1;let gradient2;function createGradient1(ctx) {&nbsp; const gradient = ctx.createRadialGradient(canvas.width / 2, canvas.height / 2, canvas.height / 4, canvas.width / 2, canvas.height / 2, canvas.height / 2);&nbsp; const innerColor = "hsla(1, 60%, 30%, 1)"&nbsp; const mainColor = red&nbsp; const outerColor = "hsla(1, 73.7%, 48%, 1)"&nbsp; gradient.addColorStop(0, innerColor);&nbsp; gradient.addColorStop(.12, innerColor);&nbsp; gradient.addColorStop(.121, mainColor);&nbsp; gradient.addColorStop(1, outerColor);&nbsp; return gradient;}function createGradient2(ctx) {&nbsp; const gradient = ctx.createRadialGradient(canvas.width / 2, canvas.height / 2, canvas.height / 4, canvas.width / 2, canvas.height / 2, canvas.height / 2);&nbsp; const innerColor = "hsla(1, 90%, 10%, 1)"&nbsp; const mainColor = "hsla(1, 73.7%, 20%, 1)"&nbsp; const outerColor = "transparent"&nbsp; gradient.addColorStop(0, innerColor);&nbsp; gradient.addColorStop(.12, innerColor);&nbsp; gradient.addColorStop(.121, mainColor);&nbsp; gradient.addColorStop(.99, mainColor);&nbsp; gradient.addColorStop(1, outerColor);&nbsp; return gradient;}function resized() {&nbsp; gradient1 = createGradient1(ctx);&nbsp; gradient2 = createGradient2(ctx);&nbsp; config.data.datasets[0].backgroundColor = [gradient1, gradient2];&nbsp; donut.update();}var config = {&nbsp; type: 'doughnut',&nbsp; data: {&nbsp; &nbsp; labels: [&nbsp; &nbsp; &nbsp; "Pledged",&nbsp; &nbsp; &nbsp; "Missing"&nbsp; &nbsp; ],&nbsp; &nbsp; datasets: [{&nbsp; &nbsp; &nbsp; label: "Donations",&nbsp; &nbsp; &nbsp; data: [420, 80],&nbsp; &nbsp; &nbsp; cubicInterpolationMode: "monotone"&nbsp; &nbsp; }]&nbsp; },&nbsp; options: {&nbsp; &nbsp; onResize: resized,&nbsp; &nbsp; legend: {&nbsp; &nbsp; &nbsp; display: false&nbsp; &nbsp; }&nbsp; }};const donut = new Chart(ctx, config);<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script><canvas class="d-goal--canvas"></canvas>
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript