说明:本文省略部分非关键代码,麻烦自己补全。
一般情况,在高清屏的设备下,任何绘制canvas中的图像、文字、线条、形状都可能会出现模糊的问题。可通过引入 GitHub 中的 hidpi-canvas 有效地解决。
- 首先去 GitHub 下载 hidpi-canvas.js 文件:传送门;
- 在项目中引入 hidpi-canvas.js 文件;
- 调用 getPixelRatio( ) 函数,得到 ratio 值;
- 在 drawImage( ) 中,将 width 和 height 乘以 ratio;
- 效果如下,但抱歉,没做对比图!
在部分 iOS 设备中,可能会存在 image.onload 失效的问题,会导致无法将图片画到 canvas 中。引起该现象的原因可能是:
1、iOS中存在 image.onload 失效的问题(注意:image.onload 执行的前提是图片正常加载完成,如果稍微出错,就会执行 image.onerror 而不是 image.onload);
2、如果 image.src 是 base64 格式文件,不要设置 image.crossOrigin = "anonymous",可能会出现 image.onload 无法执行的问题,从而无法正常画图。
关于 onload 失效的问题,看 Stack Overflow 这个解答,可能收获挺多的:IPhone img onload fails。
// html
<div onclick="makeCanvasToPhoto()" style="width: 100px; padding: 10px 30px;background: #eee;text-align: center">生成图片</div>
<canvas id="canvasBox" style="margin: 50px auto"></canvas>
<!-- 引入js -->
<script type="text/javascript" src="canvas.js"></script>
<script type="text/javascript" src="hidpi-canvas.min.js"></script>
// canvas.js 文件
function makeCanvasToPhoto() {
var that = this;
var canvas = document.getElementById("canvasBox");
var context = canvas.getContext('2d');
var ratio = getPixelRatio(context); // 关键代码
canvas.width = 300 * ratio; // 画布宽度
canvas.height = 300 * ratio; // 画布高度
var divWidth = 300 * ratio; // 用于内容居中
var divHeight = 300 * ratio; // 用于内容居中
// 画矩形
context.beginPath();
context.fillStyle = "#abcdef";
context.fillRect(0, 0, divWidth, divHeight);
context.closePath();
// 图片
context.beginPath();
var imgObj = new Image();
imgObj.crossOrigin = "anonymous"; // 在iOS 9设备中,如果src是base64格式,设置了crossOrigin 属性,会导致无法执行image.onload 而执行image.onerror 函数
imgObj.src = 'http://img0.imgtn.bdimg.com/it/u=458129248,1588126214&fm=26&gp=0.jpg';
imgObj.onload = function () {
var imgWidth = '150';
var imgHeight = '150';
context.drawImage(this, 50, 50, imgWidth * ratio, imgHeight * ratio)
};
context.closePath();
// 文本
context.beginPath();
context.font = '32px bold';
context.fillStyle = '#1a1a1a';
context.textAlign = 'center';
context.textBaseline = 'middle';
context.fillText('文本', 50, 240);
context.closePath();
context.drawImage(canvas, 0, 0, divWidth, divHeight);
var base64Obj = canvas.toDataURL('image/png', 1);
console.log(base64Obj);
}
function getPixelRatio(context) {
var backingStore = context.backingStorePixelRatio ||
context.webkitBackingStorePixelRatio ||
context.mozBackingStorePixelRatio ||
context.msBackingStorePixelRatio ||
context.oBackingStorePixelRatio ||
context.backingStorePixelRatio || 1;
return (window.devicePixelRatio || 1) / backingStore;
};
效果如图: