SVG 渲染到画布上,在视网膜显示器上模糊 [英] SVG rendered into canvas blurred on retina display

查看:42
本文介绍了SVG 渲染到画布上,在视网膜显示器上模糊的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在将 SVG 渲染到画布时遇到了问题.在 Retina 显示器上,画布呈现为 base64 url​​ 并设置为 SRC into 模糊.

我尝试了下面列表中描述的各种方法,但都没有成功:

现在我不知道我该怎么做才能让它变得更好.请查看我的结果:jsfiddle.net/a8bj5fgj/2/

更新小提琴修复:jsfiddle.net/a8bj5fgj/7/

解决方案

Retina display

视网膜和超高分辨率显示器的像素尺寸小于人眼所能分辨的平均尺寸.渲染一条线最终看起来像一条更亮的线.为了解决检测高分辨率显示的页面所涉及的问题,会将默认的 CSS 像素大小更改为 2.

DOM 知道这一点并调整其渲染以进行补偿.但是 Canvas 并不知道,它的渲染只是放大了.画布的默认显示渲染类型是双线性插值.这可以平滑从一个像素到下一个像素的过渡,这对于照片来说非常有用,但对于线条、文本、SVG 等则不太好.

一些解决方案

  • 首先是在画布上关闭双线性过滤.这可以通过 CSS 规则 image-rendering: pixelated; 来完成,虽然这不会创造在 DOM 上渲染的 SVG 的质量,但会减少一些用户体验的模糊外观.

  • 在将 SVG 渲染到画布时,您应该关闭图像平滑,因为这会降低 svg 图像的质量.SVG 在内部呈现,并且在将内部副本呈现到画布上时不需要额外的平滑处理.

    要做到这一点ctx.imageSmoothingEnabled = false;

  • 检测 CSS 像素大小.窗口变量 devicePixelRatio 返回与实际屏幕物理像素大小相比的 CSS 像素大小.视网膜和高分辨率设备的值通常为 2.然后您可以使用它来设置画布分辨率以匹配物理像素分辨率.

    但是有一个问题,因为devicePixelRatio 并非在所有浏览器上都支持,并且devicePixelRatio 受页面缩放设置的影响.

    因此,最基本的是使用 devicePixelRatio 并假设很少有人放大超过 200%.

Code 假设 canvas.style.widthcanvas.style.height 已经正确设置.

if(devicePixelRatio >= 2){画布宽度 *= 2;画布高度 *= 2;}

既然您已经提高了分辨率,您还必须增加渲染尺寸.这可以通过画布转换完成,最好将其创建为函数.

function setCanvasForRetina(canvas){画布宽度 *= 2;画布高度 *= 2;canvas.setTransform(2,0,0,2,0,0);}

<块引用>

注意我没有通过devicePixelRatio"的值增加像素大小这是因为视网膜设备只有2倍的分辨率,如果纵横比大于2是因为客户端放大了.尊重画布的预期行为,如果可以,我不会针对缩放设置进行调整.虽然这不是规则只是建议.

更好的猜测

以上两种方法要么是止损解决方案,要么是简单的猜测.您可以通过检查某些系统来提高您的胜算.

Retina 显示器目前为一组固定的设备(手机、平板电脑、笔记本电脑)提供一组固定的分辨率.

您可以查询window.screen.widthwindow.screen.height 以确定绝对物理像素分辨率并将其与已知的视网膜显示器分辨率相匹配.您还可以查询 userAgent 以确定设备类型和品牌.

将所有这些放在一起,您可以改进猜测.下一个函数会猜测显示器是否为视网膜.您可以使用类似的方法来确定设备是否为视网膜,然后相应地增加画布分辨率.

以下代码的信息可在 wiki Retina Display Models 中找到此信息可以是机器如果您想保持最新状态,请使用 Wiki 的 SPARQL 接口进行查询.

Demo 猜是否是 Retina.

rWidth.textContent = screen.widthrHeight.textContent = 屏幕高度aWidth.textContent = screen.availWidthaHeight.textContent = screen.availHeightpWidth.textContent = 内部宽度pHeight.textContent = 内部高度dWidth.textContent = document.body.clientWidthdHeight.textContent = document.body.clientHeight//doWidth.textContent = document.body.offsetWidth//doHeight.textContent = document.body.offsetHeight//sWidth.textContent = document.body.scrollWidth//sHeight.textContent = document.body.scrollHeightpAspect.textContent = devicePixelRatiouserA.textContent = navigator.userAgent函数 isRetina(){//来源 https://en.wikipedia.org/wiki/Retina_Display#Modelsvar knownRetinaResolutions = [[272,340], [312,390], [960,640], [1136,640], [1334,750], [1920,1080], [2048,1536], [2732,2040]], [2560,1600], [2880,1800], [4096,2304], [5120,2880];var knownPhones = [[960,640], [1136,640], [1334,750], [1920,1080]];var knownPads = [[2048,1536], [2732,2048]];var knownBooks = [[2304,1440], [2560,1600], [2880,1800], [4096,2304], [5120,2880]];var hasRetinaRes = knownRetinaResolutions.some(known => known[0] === screen.width && known[1] === screen.height);var isACrapple =/(iPhone|iPad|iPod|Mac OS X|MacPPC|MacIntel|Mac_PowerPC|Macintosh)/.test(navigator.userAgent);var hasPhoneRes = knownPhones.some(known => known[0] === screen.width && known[1] === screen.height);var isPhone =/iPhone/.test(navigator.userAgent);var hasPadRes = knownPads.some(known => known[0] === screen.width && known[1] === screen.height);var isPad =/iPad/.test(navigator.userAgent);var hasBookRes = knownBooks.some(known => known[0] === screen.width && known[1] === screen.height);var isBook =/Mac OS X|MacPPC|MacIntel|Mac_PowerPC|Macintosh/.test(navigator.userAgent);var isAgentMatchingRes = (isBook && hasBookRes && !isPad && !isPhone) ||(isPad && hasPadRes && !isBook && !isPhone) ||(isPhone && hasPhoneRes && !isBook && !isPad)返回 devicePixelRatio >= 2 &&isACrapple &&hasRetinaRes &&isAgentMatchingRes;}guess.textContent = isRetina() ?是":否";

div, h1, span {字体系列:宋体;}跨度 {字体粗细:粗体}

<h1>系统信息</h1><div>设备分辨率:<span id = "rWidth"></span>通过<span id = "rHeight"></span>像素

<div>可用分辨率:<span id = "aWidth"></span>通过<span id = "aHeight"></span>像素

<div>页面分辨率:<span id = "pWidth"></span>通过 </span>CSS 像素

<div>文档客户端资源:<span id = "dWidth"></span>通过 </span>CSS 像素

<div>像素方面:<span id = "pAspect"></span>

<div>用户代理:<span id="userA"></span>

<h3>最佳猜测是retina "<span id = "guess"></span>!"</h3>

来自你的片段

这可能会做你想做的.由于我没有任何苹果产品,因此除了在 isRetina 上强制设置为 true 之外,我无法对其进行测试.

 function isRetina() {//来源 https://en.wikipedia.org/wiki/Retina_Display#Modelsvar knownRetinaResolutions = [[272, 340], [312, 390], [960, 640], [1136, 640], [1334, 750], [1920, 1080], [2048, 1536], [2738]], [2304, 1440], [2560, 1600], [2880, 1800], [4096, 2304], [5120, 2880];var knownPhones = [[960, 640], [1136, 640], [1334, 750], [1920, 1080]];var knownPads = [[2048, 1536], [2732, 2048]];var knownBooks = [[2304, 1440], [2560, 1600], [2880, 1800], [4096, 2304], [5120, 2880]];var hasRetinaRes = knownRetinaResolutions.some(known => known[0] === screen.width && known[1] === screen.height);var isACrapple =/(iPhone|iPad|iPod|Mac OS X|MacPPC|MacIntel|Mac_PowerPC|Macintosh)/.test(navigator.userAgent);var hasPhoneRes = knownPhones.some(known => known[0] === screen.width && known[1] === screen.height);var isPhone =/iPhone/.test(navigator.userAgent);var hasPadRes = knownPads.some(known => known[0] === screen.width && known[1] === screen.height);var isPad =/iPad/.test(navigator.userAgent);var hasBookRes = knownBooks.some(known => known[0] === screen.width && known[1] === screen.height);var isBook =/Mac OS X|MacPPC|MacIntel|Mac_PowerPC|Macintosh/.test(navigator.userAgent);var isAgentMatchingRes = (isBook && hasBookRes && !isPad && !isPhone) ||(isPad && hasPadRes && !isBook && !isPhone) ||(isPhone && hasPhoneRes && !isBook && !isPad);返回 devicePixelRatio >= 2 &&isACrapple &&hasRetinaRes &&isAgentMatchingRes;}函数 svgToImage(svg){函数 svgAsImg() {无功画布,ctx;canvas = document.createElement("canvas");ctx = canvas.getContext("2d");var width = this.width;var height = this.height;无功比例= 1;如果(是视网膜()){宽度 *= 2;高度*= 2;规模= 2;}canvas.width = 宽度;canvas.height = 高度;ctx.setTransform(scale, 0, 0, scale, 0, 0);ctx.imageSmoothingEnabled = false;//SVG 渲染效果更好,平滑关闭ctx.drawImage(this,0,0);DOMURL.revokeObjectURL(url);尝试{var image = new Image();image.src = canvas.toDataURL();imageContainer.appendChild(image);image.width = this.width;image.height = this.height;}catch(e){//如果 CORS 错误回退到画布canvas.style.width = this.width + "px";//在 CSS 像素中不是物理像素canvas.style.height = this.height + "px";imageContainer.appendChild(canvas);//只需使用画布,因为它也是一个图像}};变量网址;var img = new Image();var DOMURL = window.URL ||window.webkitURL ||窗户;img.src = url = DOMURL.createObjectURL(new Blob([svg], {type: 'image/svg+xml'}));img.onload = svgAsImg;}svgToImage(svgContainer.innerHTML);

<div id="svgContainer"><svg width="31" height="40" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 43 55" fill="#736b9e"><path d="m 40.713968,30.966202 c 0.0028,0.05559 -0.01078.80404041.545645,2.974287 -2.853499,5.591663 -4.339695,7.673668 -0.788573,1.104704 -2.095869,2.778673 -2.874223,3.773068 -0.994236,1.02684 -6.879641,7.657944 -6.167884,7.049648 -1.292899,1.235403 -5.717368,5.476022 -5.717368,5.476022 0,0-4.323294,-3.985179 -5.928388,-5.591297ç14.037321,47.920078 10.708239,43.994015 9.6976253,42.770306 8.6870114,41.546601 8.5086687,40.900753 6.8441265,38.818752 5.8958518,37.63265 4.1376268,34.24638 3.0745121,32.156026 2.9037625,31.86435 2.7398218,31.568267 2.5826899,31.268005 2.5509386,31.2284982.5238331,31.18779 2.5044312,31.145084 2.4575955,31.041974 2.4164305,30.951055 2.3805569,30.87146 0.95511134,28.003558 0.15221914,24.771643 0.15221914,21.351725 C 0,-11.829154 9.58943056,-21.41858234 21.41858286,-21.41858234 11.829152,0 21.418583,9.58942834 21.418583,21.41858234 0,3.457576 -0.820406,6.72314 -2.275417,9.614477 Z M 21.52596,1.5031489Ç-10.866018,0 -19.6746717,8.8086521 -19.6746717,19.6746741 0,10.866016 8.8086537,19.674669 19.6746717,19.674669 10.866018,0 19.674672,-8.808648 19.674672,-19.674669 0,-10.866022 -8.808654,-19.6746741 -19.674672,-19.6746741 Z /><克变换=" 翻译(6.5,6)规模(0.060546875) ><路径d =" M32 384h272v32H32zM400 384h80v32h-80zM384 447.5c0 17.949-14.327 32.5-32 32.5-17.673 0-32-14.551-32-32.5v-95c0-17.949 14.327-32.5 32-32.5 17.673 0 32 14.55132 32.5v95z ></路径>< g取代;<路径d =" M32 240h80v32H32zM208 240h272v32H208zM192 303.5c0 17.949-14.327 32.5-32 32.5-17.673 0-32-14.551-32-32.5v-95c0-17.949 14.327-32.5 32-32.5 17.673 0 32 14.551 32 32.5v95z ></路径></g取代;< g取代;<路径d =" M32 96h272v32H32zM400 96h80v32h-80zM384 159.5c0 17.949-14.327 32.5-32 32.5-17.673 0-32-14.551-32-32.5v-95c0-17.949 14.327-32.5 32-32.5 17.673 0 32 14.551 32 32.5v95z"</path></g></g></svg>

<div id="imageContainer"></div>

请注意.

大多数拥有 6/6 视力(帝国国家为 20/20)的人很难看到画布略微模糊的显示和清晰的 DOM 之间的区别.你应该问问自己,你是否需要仔细看看才能确定?你能在正常的观看距离看到模糊吗?

也有一些人将显示放大到 200% 有充分的理由(视力受损)并且不会感谢您绕过他们的设置.

I have an issue with SVG rendered into canvas. On retina displays canvas rendered as base64 url and set as SRC into is blurred.

I've tried various methods that was described in list below with no luck:

Now i don't know what should i do to make it better. Please look into my result: jsfiddle.net/a8bj5fgj/2/

Edit:

Updated fiddle with fix: jsfiddle.net/a8bj5fgj/7/

解决方案

Retina display

Retina and very high resolution displays have pixel sizes that are smaller than the average human eye can resolve. Rendering a single line then ends up looking a like a lighter line. To fix the issues involved pages that detect the high res display will change the default CSS pixel size to 2.

The DOM knows this and adjusts its rendering to compensate. But the Canvas is not aware and its rendering is just scaled up. The default display rendering type for the canvas is bilinear interpolation. This smooths the transition from one pixel to the next which is great for photos, but not so great for lines, text, SVG and the like.

Some solutions

Code Assuming that the canvas.style.width and canvas.style.height are already correctly set.

if(devicePixelRatio >= 2){        
    canvas.width *= 2;
    canvas.height *= 2;
}

Now that you have increased the resolution you must also increase the rendering size. This can be done via the canvas transform, and better yet create it as a function.

function setCanvasForRetina(canvas){
    canvas.width *= 2;
    canvas.height *= 2;
    canvas.setTransform(2,0,0,2,0,0);
}

Note I do not increase the pixel size by the value of "devicePixelRatio" This is because retina devices will only have a resolution of 2 times, if the aspect ratio is greater than 2 it is because the client has zoomed in. To honor the expected behaviour of the canvas I do not adjust for zoom setting if I can. Though that is not a rule just a suggestion.

A better Guess

The two methods above are either a stop gap solution or a simple guess. You can improve your odds by examining some of the system.

Retina displays currently come in a fixed set of resolutions for a fixed set of devices (phones, pads, notebooks).

You can query the window.screen.width and window.screen.height to determine the absolute physical pixel resolution and match that against known retina displays resolutions. You can also query the userAgent to determine the device type and brand.

Putting it all together you can improve the guess. The next function makes a guess if the display is retina. You can use something similar to determin if the device is retina and then increase the canvas resolution accordingly.

Information for the following code found at wiki Retina Display Models This information can be machine queried using Wiki's SPARQL interface if you want to keep it up to date.

Demo Guess if Retina.

rWidth.textContent = screen.width
rHeight.textContent = screen.height

aWidth.textContent = screen.availWidth
aHeight.textContent = screen.availHeight

pWidth.textContent = innerWidth
pHeight.textContent = innerHeight

dWidth.textContent = document.body.clientWidth
dHeight.textContent = document.body.clientHeight

//doWidth.textContent = document.body.offsetWidth
//doHeight.textContent = document.body.offsetHeight

//sWidth.textContent = document.body.scrollWidth
//sHeight.textContent = document.body.scrollHeight

pAspect.textContent = devicePixelRatio

userA.textContent = navigator.userAgent



function isRetina(){
  // source https://en.wikipedia.org/wiki/Retina_Display#Models
  var knownRetinaResolutions = [[272,340], [312,390], [960,640], [1136,640 ], [1334,750 ], [1920,1080], [2048,1536], [2732,2048], [2304,1440], [2560,1600], [2880,1800], [4096,2304], [5120,2880]];
  var knownPhones =  [[960,640], [1136,640 ], [1334,750 ], [1920,1080]];
  var knownPads =  [[2048,1536], [2732,2048]];
  var knownBooks = [[2304,1440], [2560,1600], [2880,1800], [4096,2304], [5120,2880]];

  var hasRetinaRes = knownRetinaResolutions.some(known => known[0] === screen.width && known[1] === screen.height);
  var isACrapple = /(iPhone|iPad|iPod|Mac OS X|MacPPC|MacIntel|Mac_PowerPC|Macintosh)/.test(navigator.userAgent);
  var hasPhoneRes =  knownPhones.some(known => known[0] === screen.width && known[1] === screen.height);
  var isPhone = /iPhone/.test(navigator.userAgent);
  var hasPadRes =  knownPads.some(known => known[0] === screen.width && known[1] === screen.height);
  var isPad = /iPad/.test(navigator.userAgent);
  var hasBookRes =  knownBooks.some(known => known[0] === screen.width && known[1] === screen.height);
  var isBook = /Mac OS X|MacPPC|MacIntel|Mac_PowerPC|Macintosh/.test(navigator.userAgent);

  var isAgentMatchingRes = (isBook && hasBookRes && !isPad && !isPhone) ||
      (isPad && hasPadRes && !isBook && !isPhone) ||
      (isPhone && hasPhoneRes && !isBook && !isPad)
  return devicePixelRatio >= 2 && 
         isACrapple && 
         hasRetinaRes && 
          isAgentMatchingRes;
}

guess.textContent = isRetina() ? "Yes" : "No";
    

div, h1, span {
  font-family : arial;
}
span {
  font-weight : bold
}

<div class="r-display" id="info">
  <h1>System info</h1>
  <div>Device resolution : 
    <span id = "rWidth"></span> by <span id = "rHeight"></span> pixels
  </div>
  <div>Availabe resolution : 
    <span id = "aWidth"></span> by <span id = "aHeight"></span> pixels
  </div>
  <div>Page resolution : 
    <span id = "pWidth"></span> by <span id = "pHeight">  </span> CSS pixels
  </div>
  <div>Document client res : 
    <span id = "dWidth"></span> by <span id = "dHeight">  </span> CSS pixels
  </div>
  <div>Pixel aspect : 
    <span id = "pAspect"></span>
  </div>
  <div>User agent :
    <span id="userA"></span>
  </div>
  <h3>Best guess is retina "<span id = "guess"></span>!"</h3>
</div>
  

From your snippet

This may do what you want. As I don't own any apple products I can not test it apart from forcing true on isRetina.

    function isRetina() {
        // source https://en.wikipedia.org/wiki/Retina_Display#Models
        var knownRetinaResolutions = [[272, 340], [312, 390], [960, 640], [1136, 640], [1334, 750], [1920, 1080], [2048, 1536], [2732, 2048], [2304, 1440], [2560, 1600], [2880, 1800], [4096, 2304], [5120, 2880]];
        var knownPhones = [[960, 640], [1136, 640], [1334, 750], [1920, 1080]];
        var knownPads = [[2048, 1536], [2732, 2048]];
        var knownBooks = [[2304, 1440], [2560, 1600], [2880, 1800], [4096, 2304], [5120, 2880]];

        var hasRetinaRes = knownRetinaResolutions.some(known => known[0] === screen.width && known[1] === screen.height);
        var isACrapple = /(iPhone|iPad|iPod|Mac OS X|MacPPC|MacIntel|Mac_PowerPC|Macintosh)/.test(navigator.userAgent);
        var hasPhoneRes = knownPhones.some(known => known[0] === screen.width && known[1] === screen.height);
        var isPhone = /iPhone/.test(navigator.userAgent);
        var hasPadRes = knownPads.some(known => known[0] === screen.width && known[1] === screen.height);
        var isPad = /iPad/.test(navigator.userAgent);
        var hasBookRes = knownBooks.some(known => known[0] === screen.width && known[1] === screen.height);
        var isBook = /Mac OS X|MacPPC|MacIntel|Mac_PowerPC|Macintosh/.test(navigator.userAgent);

        var isAgentMatchingRes = (isBook && hasBookRes && !isPad && !isPhone) ||
            (isPad && hasPadRes && !isBook && !isPhone) ||
            (isPhone && hasPhoneRes && !isBook && !isPad);
      
      
        return devicePixelRatio >= 2 && isACrapple && hasRetinaRes && isAgentMatchingRes;
    }
    
    function svgToImage(svg){
        function svgAsImg() {
            var canvas, ctx;
            canvas = document.createElement("canvas");
            ctx = canvas.getContext("2d");
            var width = this.width;
            var height = this.height;
            var scale = 1;
            if(isRetina()){
                width *= 2;
                height *= 2;
                scale = 2;
            }

            canvas.width = width;
            canvas.height = height;
            ctx.setTransform(scale, 0, 0, scale, 0, 0);
            ctx.imageSmoothingEnabled = false;  // SVG rendering is better with smoothing off
            ctx.drawImage(this,0,0);
            DOMURL.revokeObjectURL(url);
            try{
                var image = new Image();
                image.src = canvas.toDataURL();              
                imageContainer.appendChild(image);
                image.width = this.width;
                image.height = this.height;
            }catch(e){  // in case of CORS error fallback to canvas
                canvas.style.width = this.width + "px";  // in CSS pixels not physical pixels
                canvas.style.height = this.height + "px";
                imageContainer.appendChild(canvas);  // just use the canvas as it is an image as well
            }
        };
        var url;
        var img = new Image();
        var DOMURL = window.URL || window.webkitURL || window;
        img.src = url = DOMURL.createObjectURL(new Blob([svg], {type: 'image/svg+xml'}));           
        img.onload = svgAsImg;
    }
    
    svgToImage(svgContainer.innerHTML);
   

<div id="svgContainer"><svg width="31" height="40" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 43 55" fill="#736b9e"><path d="m 40.713968,30.966202 c 0.0028,0.05559 -0.01078,0.114956 -0.044,0.178882 -1.545645,2.974287 -2.853499,5.591663 -4.339695,7.673668 -0.788573,1.104704 -2.095869,2.778673 -2.874223,3.773068 -0.994236,1.02684 -6.879641,7.657944 -6.167884,7.049648 -1.292899,1.235403 -5.717368,5.476022 -5.717368,5.476022 0,0 -4.323294,-3.985179 -5.928388,-5.591297 C 14.037321,47.920078 10.708239,43.994015 9.6976253,42.770306 8.6870114,41.546601 8.5086687,40.900753 6.8441265,38.818752 5.8958518,37.63265 4.1376268,34.24638 3.0745121,32.156026 2.9037625,31.86435 2.7398218,31.568267 2.5826899,31.268005 2.5509386,31.228498 2.5238331,31.18779 2.5044312,31.145084 2.4575955,31.041974 2.4164305,30.951055 2.3805569,30.87146 0.95511134,28.003558 0.15221914,24.771643 0.15221914,21.351725 c 0,-11.829154 9.58943056,-21.41858234 21.41858286,-21.41858234 11.829152,0 21.418583,9.58942834 21.418583,21.41858234 0,3.457576 -0.820406,6.72314 -2.275417,9.614477 z M 21.52596,1.5031489 c -10.866018,0 -19.6746717,8.8086521 -19.6746717,19.6746741 0,10.866016 8.8086537,19.674669 19.6746717,19.674669 10.866018,0 19.674672,-8.808648 19.674672,-19.674669 0,-10.866022 -8.808654,-19.6746741 -19.674672,-19.6746741 z" /><g transform="translate(6.5,6) scale(0.060546875)"><path d="M32 384h272v32H32zM400 384h80v32h-80zM384 447.5c0 17.949-14.327 32.5-32 32.5-17.673 0-32-14.551-32-32.5v-95c0-17.949 14.327-32.5 32-32.5 17.673 0 32 14.551 32 32.5v95z"></path><g><path d="M32 240h80v32H32zM208 240h272v32H208zM192 303.5c0 17.949-14.327 32.5-32 32.5-17.673 0-32-14.551-32-32.5v-95c0-17.949 14.327-32.5 32-32.5 17.673 0 32 14.551 32 32.5v95z"></path></g><g><path d="M32 96h272v32H32zM400 96h80v32h-80zM384 159.5c0 17.949-14.327 32.5-32 32.5-17.673 0-32-14.551-32-32.5v-95c0-17.949 14.327-32.5 32-32.5 17.673 0 32 14.551 32 32.5v95z"></path></g></g></svg>
</div>    
<div id="imageContainer"></div>

Please Note.

Most people who have 6/6 vision (20/20 for imperial countries) will be hard pressed to see the difference between the slightly blurry display of the canvas and the crisp DOM. You should ask yourself, did you need to have a closer look to make sure? can you see the blur at normal viewing distance?

Also some people who have zoomed the display to 200% do so for good reason (vision impaired) and will not appreciate you circumventing their settings.

这篇关于SVG 渲染到画布上,在视网膜显示器上模糊的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆