亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何將徑向 CanvasGradients 與 Chart.js 的圓環圖一起使用?

如何將徑向 CanvasGradients 與 Chart.js 的圓環圖一起使用?

ABOUTYOU 2023-07-20 17:14:42
我正在嘗試創建兩個徑向漸變以與Charts.js 圓環圖一起使用。漸變應該看起來有點像下圖,但是是紅色的。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 = gradientdrawRect(ctx)var {ctx, gradient} = createGradient1(canvasList[1].getContext('2d'))ctx.strokeStyle = gradientctx.lineWidth = 42drawArc(ctx)var {ctx, gradient} = createGradient2(canvasList[2].getContext('2d'))ctx.fillStyle = gradientdrawRect(ctx)var {ctx, gradient} = createGradient2(canvasList[3].getContext('2d'))ctx.strokeStyle = gradientctx.lineWidth = 42drawArc(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")。
查看完整描述

1 回答

?
慕村225694

TA貢獻1880條經驗 獲得超4個贊

問題在于漸變填充樣式實際應用于甜甜圈的方式。你和我最初的假設是,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 = 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);

這將在 x=100 和 y=100 處產生直徑為 140 像素的漸變,如下所示:

http://img1.sycdn.imooc.com//64b8fb4a0001f41701860187.jpg

現在,如果我們進一步挖掘并假設您繪制的實際畫布的大小是 797 x 419 像素,我們可以看到問題:

http://img1.sycdn.imooc.com//64b8fb560001f4ec06510341.jpg

漸變完全脫離了甜甜圈的形狀!

為了解決這個問題,漸變需要位于甜甜圈的中心,并且具有適當的大小以完全填充它。有點像這樣:

http://img1.sycdn.imooc.com//64b8fb61000159c406480340.jpg

這說起來容易做起來難,因為最初我們不知道畫布的確切大小,因為 Chart.js 會自動拉伸它以填充瀏覽器窗口。

因此,我們可以采取以下解決方法:

  • 使用 Chart.js 創建甜甜圈,但先不要填充它

  • 等到 Chart.js 觸發調整大小事件以獲取畫布的實際大小

  • 根據畫布的大小計算漸變的尺寸并將其繪制在中心

  • 最后用漸變填充甜甜圈的背景顏色

這是一個示例(請以“全頁”運行,因為我們在 stackoverflow 的迷你預覽框架中沒有獲得正確的窗口大?。?/p>

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) {

  const gradient = ctx.createRadialGradient(canvas.width / 2, canvas.height / 2, canvas.height / 4, canvas.width / 2, canvas.height / 2, canvas.height / 2);


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

  const mainColor = red

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

  gradient.addColorStop(0, innerColor);

  gradient.addColorStop(.12, innerColor);

  gradient.addColorStop(.121, mainColor);

  gradient.addColorStop(1, outerColor);


  return gradient;

}


function createGradient2(ctx) {

  const gradient = ctx.createRadialGradient(canvas.width / 2, canvas.height / 2, canvas.height / 4, canvas.width / 2, canvas.height / 2, canvas.height / 2);


  const innerColor = "hsla(1, 90%, 10%, 1)"

  const mainColor = "hsla(1, 73.7%, 20%, 1)"

  const outerColor = "transparent"

  gradient.addColorStop(0, innerColor);

  gradient.addColorStop(.12, innerColor);

  gradient.addColorStop(.121, mainColor);

  gradient.addColorStop(.99, mainColor);

  gradient.addColorStop(1, outerColor);


  return gradient;

}


function resized() {

  gradient1 = createGradient1(ctx);

  gradient2 = createGradient2(ctx);

  config.data.datasets[0].backgroundColor = [gradient1, gradient2];

  donut.update();

}

var config = {

  type: 'doughnut',

  data: {

    labels: [

      "Pledged",

      "Missing"

    ],

    datasets: [{

      label: "Donations",

      data: [420, 80],

      cubicInterpolationMode: "monotone"

    }]

  },

  options: {

    onResize: resized,

    legend: {

      display: false

    }

  }

};

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>


查看完整回答
反對 回復 2023-07-20
  • 1 回答
  • 0 關注
  • 158 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號