mirror of
https://github.com/chartjs/Chart.js.git
synced 2025-12-08 20:36:08 +00:00
Round canvas.style dimensions to avoid blurring (#9015)
When canvas.height and canvas.width are set, the numbers are rounded to integers. The same rounding must be applied to canvas.style.height and canvas.style.width to avoid scaling of the canvas which would lead to blurring. Acknowledging that canvas.height and canvas.width are integers, the framebuffer is now only redrawn if those integer values change.
This commit is contained in:
parent
a87175f119
commit
c955ffad64
@ -246,19 +246,14 @@ class Chart {
|
||||
const canvas = me.canvas;
|
||||
const aspectRatio = options.maintainAspectRatio && me.aspectRatio;
|
||||
const newSize = me.platform.getMaximumSize(canvas, width, height, aspectRatio);
|
||||
|
||||
// detect devicePixelRation changes
|
||||
const oldRatio = me.currentDevicePixelRatio;
|
||||
const newRatio = options.devicePixelRatio || me.platform.getDevicePixelRatio();
|
||||
|
||||
if (me.width === newSize.width && me.height === newSize.height && oldRatio === newRatio) {
|
||||
return;
|
||||
}
|
||||
|
||||
me.width = newSize.width;
|
||||
me.height = newSize.height;
|
||||
me._aspectRatio = me.aspectRatio;
|
||||
retinaScale(me, newRatio, true);
|
||||
if (!retinaScale(me, newRatio, true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
me.notifyPlugins('resize', {size: newSize});
|
||||
|
||||
|
||||
@ -150,21 +150,40 @@ export function getMaximumSize(canvas, bbWidth, bbHeight, aspectRatio) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('../core/core.controller').default} chart
|
||||
* @param {number} [forceRatio]
|
||||
* @param {boolean} [forceStyle]
|
||||
* @returns {boolean} True if the canvas context size or transformation has changed.
|
||||
*/
|
||||
export function retinaScale(chart, forceRatio, forceStyle) {
|
||||
const pixelRatio = chart.currentDevicePixelRatio = forceRatio || 1;
|
||||
const {canvas, width, height} = chart;
|
||||
const pixelRatio = forceRatio || 1;
|
||||
const deviceHeight = Math.floor(chart.height * pixelRatio);
|
||||
const deviceWidth = Math.floor(chart.width * pixelRatio);
|
||||
|
||||
canvas.height = height * pixelRatio;
|
||||
canvas.width = width * pixelRatio;
|
||||
chart.ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);
|
||||
chart.height = deviceHeight / pixelRatio;
|
||||
chart.width = deviceWidth / pixelRatio;
|
||||
|
||||
const canvas = chart.canvas;
|
||||
|
||||
// If no style has been set on the canvas, the render size is used as display size,
|
||||
// making the chart visually bigger, so let's enforce it to the "correct" values.
|
||||
// See https://github.com/chartjs/Chart.js/issues/3575
|
||||
if (canvas.style && (forceStyle || (!canvas.style.height && !canvas.style.width))) {
|
||||
canvas.style.height = height + 'px';
|
||||
canvas.style.width = width + 'px';
|
||||
canvas.style.height = `${chart.height}px`;
|
||||
canvas.style.width = `${chart.width}px`;
|
||||
}
|
||||
|
||||
if (chart.currentDevicePixelRatio !== pixelRatio
|
||||
|| canvas.height !== deviceHeight
|
||||
|| canvas.width !== deviceWidth) {
|
||||
chart.currentDevicePixelRatio = pixelRatio;
|
||||
canvas.height = deviceHeight;
|
||||
canvas.width = deviceWidth;
|
||||
chart.ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user