1. 起因?
2. 基础?
2.1. window.devicePixelRatio
2.2. Sizing the canvas using CSS versus HTML
3. 解决方案?
1. 起因?
2. 基础?
2.1. window.devicePixelRatio
The devicePixelRatio of Window interface returns the ratio of the resolution in physical pixels to the resolution in CSS pixels for the current display device. This value could also be interpreted as the ratio of pixel sizes: the size of one CSS pixel to the size of one physical pixel. In simpler terms, this tells the browser how many of the screen's actual pixels should be used to draw a single CSS pixel.
2.2. Sizing the canvas using CSS versus HTML
The displayed size of the canvas can be changed using CSS, but if you do this the image is scaled during rendering to fit the styled size, which can make the final graphics rendering end up being distorted.
It is better to specify your canvas dimensions by setting the width and height attributes directly on the <canvas> elements, either directly in the HTML or by using JavaScript.
示例:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<canvas id="c1" width="500" height="500" style="border:1px solid blue;"></canvas>
<canvas id="c2" style="width:500px;height:500px; border: 1px solid green;"></canvas>
<script type="text/javascript">
function drawTriangle(ctx){
ctx.beginPath();
ctx.moveTo(75, 50);
ctx.lineTo(200, 120);
ctx.lineTo(230, 16);
ctx.fill();
}
drawTriangle(document.querySelector("#c1").getContext("2d"));
drawTriangle(document.querySelector("#c2").getContext("2d"));
</script>
</body>
</html>
3. 解决方案?
Enabling your canvas to appear crisp on Retina as well as standard-definition displays is as simple as multiplying your canvas instructions by a ratio determined by the screen’s pixel density. First, you need to understand how pixel values are stored in a canvas.
The backing store is where the canvas stores data for each pixel’s color value. The goal is to provide a pixel in the backing store for each display pixel rendered on the canvas. Before the pixels are pushed to the screen, their values are computed here. However, the number of pixels represented in the backing store might not be equal to the number of pixels pushed to the screen. On Retina devices, the canvas width and height is doubled to maintain consistent size and position relative to other HTML elements, and as a result, it stretches and blurs its contents. To counteract this stretching, you need to double the width and height of the backing store when appropriate.
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
// Set display size (css pixels).
var size = 200;
canvas.style.width = size + "px";
canvas.style.height = size + "px";
// Set actual size in memory (scaled to account for extra pixel density).
var scale = window.devicePixelRatio; // Change to 1 on retina screens to see blurry canvas.
canvas.width = Math.floor(size * scale);
canvas.height = Math.floor(size * scale);
// Normalize coordinate system to use css pixels.
ctx.scale(scale, scale);
ctx.fillStyle = "#bada55";
ctx.fillRect(10, 10, 300, 300);
ctx.fillStyle = "#ffffff";
ctx.font = '18px Arial';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
var x = size / 2;
var y = size / 2;
var textString = "I love MDN";
ctx.fillText(textString, x, y);
因此,要使 canvas 适配高倍屏:
参考:
Window.devicePixelRatio: https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio Support Retina Displays From the Start: https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/HTML-canvas-guide/SettingUptheCanvas/SettingUptheCanvas.html High DPI Canvas: https://www.html5rocks.com/en/tutorials/canvas/hidpi/