【发布时间】:2021-02-23 00:22:21
【问题描述】:
我正在尝试创建两个径向渐变以与 Charts.js doughnut chart 一起使用。
使用 vanilla javascript 和 DOM 创建渐变 (createRadialGradient) 非常简单,如下面的代码 sn-p 所示:
'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 }
}
function createGradient2 (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 = "hsla(1, 90%, 10%, 1)"
const mainColor = "hsla(1, 73.7%, 20%, 1)"
const outerColor = "transparent"
gradient.addColorStop(0, innerColor);
gradient.addColorStop(.04, innerColor);
gradient.addColorStop(.05, mainColor);
gradient.addColorStop(.7, mainColor);
gradient.addColorStop(.73, outerColor);
return { ctx, gradient }
}
function drawRect (ctx) {
// ctx.fillRect(x, y, width, height)
ctx.fillRect(20, 20, 160, 160);
}
function drawArc (ctx) {
ctx.beginPath();
// ctx.arc(x, y, radius, startAngle, endAngle [, anticlockwise])
ctx.arc(100, 100, 50, 0, 2 * Math.PI);
ctx.stroke()
}
.vanilla {
display: inline-block;
}
<canvas class="vanilla" width="180" height="180"></canvas>
<canvas class="vanilla" width="180" height="180"></canvas>
<canvas class="vanilla" width="180" height="180"></canvas>
<canvas class="vanilla" width="180" height="180"></canvas>
但是当我将相同的 2 个渐变应用到 Charts.js 时,我得到了一个灰色的甜甜圈。使用单个渐变不会改变结果。但是,使用两种 Hsla 颜色可以按预期工作 (red & "white")。
/** @type {CanvasRenderingContext2D} */
const ctx = document.querySelector('.d-goal--canvas').getContext('2d')
const red = "hsla(1, 73.7%, 38.8%, 1)"
const { gradient1 } = createGradient1(ctx)
const { gradient2 } = createGradient2(ctx)
const donut = new Chart(ctx, {
type: 'doughnut',
data: {
labels: [
"Pledged",
"Missing"
],
datasets: [{
label: "Donations",
data: [420, 80],
cubicInterpolationMode: "monotone",
// borderColor: [red, "white"],
// backgroundColor: [red, "white"],
borderColor: [gradient1, gradient2],
backgroundColor: [gradient1, gradient2],
}]
},
options: {
legend: {
display: false
}
}
})
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 = "hsla(1, 60%, 30%, 1)"
const mainColor = red
const outerColor = "hsla(1, 73.7%, 48%, 1)"
gradient.addColorStop(0, innerColor);
gradient.addColorStop(.04, innerColor);
gradient.addColorStop(.05, mainColor);
gradient.addColorStop(1, outerColor);
return { ctx, gradient }
}
function createGradient2 (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 = "hsla(1, 90%, 10%, 1)"
const mainColor = "hsla(1, 73.7%, 20%, 1)"
const outerColor = "transparent"
gradient.addColorStop(0, innerColor);
gradient.addColorStop(.04, innerColor);
gradient.addColorStop(.05, mainColor);
gradient.addColorStop(.7, mainColor);
gradient.addColorStop(.73, outerColor);
return { ctx, gradient }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
<canvas class="d-goal--canvas"></canvas>
我做错了什么?
我阅读了Jelena Jovanovic's gradient tutorial,这是一个应用于折线图的线性渐变 (createLinearGradient),我看不出我在做什么不同。也许我的渐变区域是错误的,但据我所知,这不应该导致灰色图表。
The Charts.js documentation has a section about colors 在那里他们描述了如何使用CanvasGradient 但仅限于createLinearGradient,这让我认为这可能是 Charts.js 中的一个错误......
【问题讨论】:
-
糟糕!我想我发现了我的错误。
createGradient1和createGradient2返回{ ctx, gradient }而不是gradient1和gradient2!我的解构变量应该是const { gradient: gradient1 } = createGradient1(ctx)和const { gradient: gradient2 } = createGradient2(ctx) -
那解决了您的问题吗?
-
只是问题的一部分。我现在得到第一个渐变,但不是第二个。而且看起来不对,这可能是因为渐变区域与圆环图区域不匹配。当我有时间进一步调查时,我会发布一个解决方案。
标签: javascript dom html5-canvas chart.js