جافاسكريبت - تعيين لون الخلفية لحفظ مخطط الكانفاس
أنا أستخدم ChartJS وأقوم بحفظها محليًا، محولًا صورة الرسم البياني على اللوحة إلى كائن بيانات ثم حفظه. لكنني أواجه مشكلة في تعيين لون خلفية لأي رسم بياني على اللوحة أحفظه، حيث يمكنني حفظ الرسم البياني فقط بدون لون خلفية، مما يربك المستخدم.
ما جربته حتى الآن كان:
- غيّر نوع image/png إلى image/jpg
- قم بإنشاء مستند بأسلوب وألحقه كطفل إلى document.createElement الخاص بي والذي سيكون لديه الصورة
- امنح أسلوبًا لـ 'الرابط' الخاص بي يكون مساويًا لـ document.createElement أعلاه
لكن بدون نجاح، تم تنزيل الصورة بشكل صحيح بدون الخلفية.
كنت أبحث ووجدت بعض المواضيع:
إنشاء لوحة مع صورة خلفية وحفظها
حفظ اللوحة مع صورة الخلفية
لكن، في نهاية كل العمل، لم أتمكن من إيجاد الحل لي.
رسم بياني الخاص بي على HTML هو:
<canvas id="divName"></canvas>
دالة TypeScript لحفظ الصورة، إنشاء كتلة جديدة (blob) بمصفوفة البايت ونوع الصورة هو: (هذا الكود يحتوي على جميع المحاولات لإضافة لون خلفية)
saveimg(divName){
let canvas:any;
let style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = '.cssClass { background-color: "aquamarine"; }';
if(this.deviceValue != null) {
canvas = document.getElementById(this.deviceValue);
}
else {
canvas = document.getElementById(divName);
}
//SOLUTION that works BY Caleb Miller ***********
fillCanvasBackground(canvas, 'white');
function fillCanvasBackground(canvasc, color)
{
const context = canvasc.getContext('2d');
context.save();
context.globalCompositeOperation = 'destination-over';
context.fillStyle = color;
context.fillRect(0, 0, canvasc.width, canvasc.height);
context.restore();
}
// end***********************
let dataURL = canvas.toDataURL();
let datablob = dataURL.substring(dataURL.indexOf(",") + 1);
let byteCharacters = atob(datablob);
let byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
let byteArray = new Uint8Array(byteNumbers);
let blob = new Blob([byteArray], {"type": "image/jpg"});
if(navigator.msSaveBlob){
let filename = this.chartTitle + ' - ' + this.entityName;
navigator.msSaveBlob(blob, filename);
} else {
let filename =this.chartTitle + ' - ' + this.entityName;
let link = document.createElement("a");
link.onload = function() {
canvas.drawImage(0,0);
};
document.getElementsByTagName('a')[0].appendChild(style);
link.href = URL.createObjectURL(blob);
link.setAttribute('visibility','hidden');
link.download = filename;
link.style.backgroundColor = "lightblue repeat-x center";
document.body.appendChild(link).style.background = "lightblue repeat-x center";
link.click();
document.body.removeChild(link);
}
this.deviceValue = null;
}
صور لتوضيح المشكلة:
على الموقع الصورة هي:
عندما أحمله
هل من الممكن إضافة لون خلفية لصورة على اللوحة؟
الإجابة رقم 1
كما اكتشفت، canvas.toDataURL() لا يلتقط أي تنسيقات بصرية مطبقة عبر CSS. إنه يلتقط فقط بيانات البكسل الخام من الصورة النقطية التي تدعم كائن اللوحة. هذا مقصود.
لكي تستخدم لون خلفية مخصص، تحتاج إلى رسمه مباشرة على اللوحة. إليك مثال على دالة تملأ خلفية اللوحة المعطاة باللون المعطى. يجب أن تشرح تعليقاتي المضمنة كيفية عملها.
function fillCanvasBackgroundWithColor(canvas, color) {
// Get the 2D drawing context from the provided canvas.
const context = canvas.getContext('2d');
// We're going to modify the context state, so it's
// good practice to save the current state first.
context.save();
// Normally when you draw on a canvas, the new drawing
// covers up any previous drawing it overlaps. This is
// because the default `globalCompositeOperation` is
// 'source-over'. By changing this to 'destination-over',
// our new drawing goes behind the existing drawing. This
// is desirable so we can fill the background, while leaving
// the chart and any other existing drawing intact.
// Learn more about `globalCompositeOperation` here:
// https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation
context.globalCompositeOperation = 'destination-over';
// Fill in the background. We do this by drawing a rectangle
// filling the entire canvas, using the provided color.
context.fillStyle = color;
context.fillRect(0, 0, canvas.width, canvas.height);
// Restore the original context state from `context.save()`
context.restore();
}
لاستخدام الدالة، قم باستدعائها قبل كود الحفظ الخاص بك، مع تزويدها بلوحة الرسم البياني واللون. ينبغي أن تبدو شيئًا مثل هذا:
const canvas = document.getElementById('yourCanvasId');
fillCanvasBackgroundWithColor(canvas, 'aquamarine');
// ...the rest of your save code
يجب أن تحتوي الصورة المحفوظة على لون خلفية.
