如何在chartjs-plugin-datalabels v2.1.0中用图片替换幸运转盘标签文本
问题描述
使用chartjs-plugin-datalabels v2.1.0制作幸运转盘,需要将标签列中的文本(如'2'、'3')替换为图片,现有代码中标签行的值为文本,希望替换为图片。
解决方案
chartjs-plugin-datalabels默认不支持直接渲染HTML元素(如<img>),因为Chart.js基于Canvas绘制,需通过Canvas的drawImage方法实现图片绘制。以下是修改后的完整代码:
修改后的JavaScript代码
const spinWheel = document.getElementById("spinWheel"); const spinBtn = document.getElementById("spin_btn"); const text = document.getElementById("text"); const spinValues = [ { minDegree: 31, maxDegree: 60, value: "Ноутбук игровой MSI Katana GF76 12UD-263RU" }, { minDegree: 0, maxDegree: 30, value: "Lush3 + Ridge x 1 + Микрофон HyperX Quadcast S" }, { minDegree: 61, maxDegree: 90, value: "Беззеркальная камера Canon EOS R50 Body" }, { minDegree: 331, maxDegree: 360, value: "Lovense Webcam + Domi 2" }, { minDegree: 301, maxDegree: 330, value: '"Капуста"' }, { minDegree: 271, maxDegree: 300, value: '"Картошка"' }, { minDegree: 211, maxDegree: 240, value: "Apple iPhone 15" }, { minDegree: 241, maxDegree: 270, value: '"Морковь"' }, { minDegree: 181, maxDegree: 210, value: "Cougar Throne – кресло для геймеров" }, { minDegree: 151, maxDegree: 180, value: "Сертификат ВБ", }, ]; const size = [10, 10, 10, 10, 10, 10, 10, 10, 10, 10]; var spinColors = ["#303032", "#303032", "#303032", "#303032", "#303032", "#303032", "#303032", "#303032", "#303032", "#303032"]; // 预加载所有图片,避免绘制时图片未加载完成 const preloadImages = (imagePaths) => { return Promise.all(imagePaths.map(path => { return new Promise((resolve, reject) => { const img = new Image(); img.src = path; img.onload = () => resolve(img); img.onerror = reject; }); })); }; // 定义每个扇形对应的图片路径 const labelImages = [ "/img/11.png", "/img/2.png", "/img/3.png", "/img/4.png", "/img/5.png", "/img/6.png", "/img/7.png", "/img/8.png", "/img/9.png", "/img/10.png" ]; // 预加载图片后初始化图表 preloadImages(labelImages).then(images => { let spinChart = new Chart(spinWheel, { plugins: [ChartDataLabels], type: "pie", data: { labels: labelImages, // 用图片路径作为标签标识 datasets: [ { backgroundColor: spinColors, data: size, }, ], }, options: { responsive: true, animation: { duration: 0 }, plugins: { tooltip: false, legend: { display: false, }, datalabels: { rotation: 90, display: true, formatter: () => '', // 禁用默认文本输出 draw: function(context) { const { ctx, dataIndex } = context; const image = images[dataIndex]; if (!image) return; // 获取扇形中心位置 const { x, y } = context.rect; // 计算图片尺寸(取扇形最小边的60%,避免超出边界) const imgSize = Math.min(context.rect.width, context.rect.height) * 0.6; // 旋转画布匹配标签旋转角度 ctx.save(); ctx.translate(x, y); ctx.rotate((90 * Math.PI) / 180); // 居中绘制图片 ctx.drawImage(image, -imgSize/2, -imgSize/2, imgSize, imgSize); ctx.restore(); } }, }, }, }); const generateValue = (angleValue) => { for (let i of spinValues) { if (angleValue >= i.minDegree && angleValue <= i.maxDegree) { text.innerHTML = `<p>Поздравляем, вы выиграли: <br> ${i.value} ! </p>`; spinBtn.disabled = false; break; } } }; let count = 0; let resultValue = 101; spinBtn.addEventListener("click", () => { spinBtn.disabled = true; text.innerHTML = `<p>Желаю Удачи!</p>`; let randomDegree = Math.floor(Math.random() * (355 - 0 + 1) + 0); let rotationInterval = window.setInterval(() => { spinChart.options.rotation = spinChart.options.rotation + resultValue; spinChart.update(); if (spinChart.options.rotation >= 360) { count += 1; resultValue -= 5; spinChart.options.rotation = 0; } else if (count > 15 && spinChart.options.rotation >= randomDegree) { generateValue(randomDegree); clearInterval(rotationInterval); count = 0; resultValue = 101; } }, 10); }); }).catch(err => { console.error("图片加载失败:", err); });
修改后的HTML代码
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-datalabels/2.1.0/chartjs-plugin-datalabels.min.js"></script> <div> <canvas id="spinWheel"></canvas> </div> <div id="spin_btn">spin_btn</div> <div id="text">text</div>
关键改动说明
- 预加载图片:通过
preloadImages函数提前加载所有转盘图片,确保绘制时图片已加载完成,避免空白。 - 替换labels数组:将原文本标签替换为图片路径,用于关联对应的图片资源。
- 自定义datalabels绘制逻辑:使用
draw回调函数,利用Canvas的drawImage方法在扇形中心绘制图片,同时匹配原有的旋转角度,保证图片方向正确。 - 动态调整图片尺寸:根据扇形大小计算图片显示尺寸,确保图片在扇形内适配显示。
内容的提问来源于stack exchange,提问作者HaoSed
相关产品推荐
相关产品推荐

