Come posso correggere il testo sfocato nella mia tela HTML5?


89

Sono un totale n00b con HTML5e sto lavorando con il canvasrendering di forme, colori e testo. Nella mia app, ho un adattatore di visualizzazione che crea dinamicamente una tela e la riempie di contenuto. Funziona davvero bene, tranne per il fatto che il mio testo è reso molto sfocato / sfocato / allungato. Ho visto un sacco di altri posti sul perché la definizione della larghezza e altezza in CSScauserà questo problema, ma io definire tutto in javascript.

Il codice pertinente (visualizza Fiddle ):

var width  = 500;//FIXME:size.w;
var height = 500;//FIXME:size.h;
    
var canvas = document.createElement("canvas");
//canvas.className="singleUserCanvas";
canvas.width=width;
canvas.height=height;
canvas.border = "3px solid #999999";
canvas.bgcolor = "#999999";
canvas.margin = "(0, 2%, 0, 2%)";
    
var context = canvas.getContext("2d");

//////////////////
////  SHAPES  ////
//////////////////
    
var left = 0;

//draw zone 1 rect
context.fillStyle = "#8bacbe";
context.fillRect(0, (canvas.height*5/6)+1, canvas.width*1.5/8.5, canvas.height*1/6);

left = left + canvas.width*1.5/8.5;

//draw zone 2 rect
context.fillStyle = "#ffe381";
context.fillRect(left+1, (canvas.height*5/6)+1, canvas.width*2.75/8.5, canvas.height*1/6);

left = left + canvas.width*2.75/8.5 + 1;

//draw zone 3 rect
context.fillStyle = "#fbbd36";
context.fillRect(left+1, (canvas.height*5/6)+1, canvas.width*1.25/8.5, canvas.height*1/6);

left = left + canvas.width*1.25/8.5;

//draw target zone rect
context.fillStyle = "#004880";
context.fillRect(left+1, (canvas.height*5/6)+1, canvas.width*0.25/8.5, canvas.height*1/6);

left = left + canvas.width*0.25/8.5;
    
//draw zone 4 rect
context.fillStyle = "#f8961d";
context.fillRect(left+1, (canvas.height*5/6)+1, canvas.width*1.25/8.5, canvas.height*1/6);

left = left + canvas.width*1.25/8.5 + 1;

//draw zone 5 rect
context.fillStyle = "#8a1002";
context.fillRect(left+1, (canvas.height*5/6)+1, canvas.width-left, canvas.height*1/6);

////////////////
////  TEXT  ////
////////////////

//user name
context.fillStyle = "black";
context.font = "bold 18px sans-serif";
context.textAlign = 'right';
context.fillText("User Name", canvas.width, canvas.height*.05);

//AT:
context.font = "bold 12px sans-serif";
context.fillText("AT: 140", canvas.width, canvas.height*.1);

//AB:
context.fillText("AB: 94", canvas.width, canvas.height*.15);
       
//this part is done after the callback from the view adapter, but is relevant here to add the view back into the layout.
var parent = document.getElementById("layout-content");
parent.appendChild(canvas);
<div id="layout-content"></div>

I risultati che vedo (in Safari ) sono molto più distorti di quelli mostrati in Fiddle:

Il mio

Output renderizzato in Safari

Violino

Output reso su JSFiddle

Cosa sto facendo in modo errato? Ho bisogno di una tela separata per ogni elemento di testo? È il carattere? Devo prima definire la tela nel layout HTML5? C'è un errore di battitura? Mi sono perso.


Sembra che tu non stia chiamando clearRect.
David

1
Questo polyfill corregge la maggior parte delle operazioni di base della tela con i browser HiDPI che non eseguono l'upscaling automatico (attualmente Safari è l'unico) ... github.com/jondavidjohn/hidpi-canvas-polyfill
jondavidjohn

Ho sviluppato un framework JS che risolve il problema della sfocatura della tela con il mosaico DIV. Produco
Gonki

Risposte:


160

L'elemento canvas viene eseguito indipendentemente dal rapporto pixel del dispositivo o del monitor.

Sull'iPad 3+, questo rapporto è 2. Ciò significa essenzialmente che la tua tela di 1000 px di larghezza dovrebbe ora riempire 2000 px per corrispondere alla larghezza dichiarata sul display dell'iPad. Fortunatamente per noi, questo viene fatto automaticamente dal browser. D'altra parte, questo è anche il motivo per cui vedi meno definizione sulle immagini e sugli elementi della tela che sono stati realizzati per adattarsi direttamente alla loro area visibile. Poiché la tua tela sa solo come riempire 1000px ma gli viene chiesto di disegnare a 2000px, il browser ora deve riempire in modo intelligente gli spazi tra i pixel per visualizzare l'elemento alla dimensione corretta.

Ti consiglio vivamente di leggere questo articolo di HTML5Rocks che spiega in modo più dettagliato come creare elementi ad alta definizione.

tl; dr? Ecco un esempio (basato sul tut precedente) che utilizzo nei miei progetti per sputare una tela con la risoluzione corretta:

var PIXEL_RATIO = (function () {
    var ctx = document.createElement("canvas").getContext("2d"),
        dpr = window.devicePixelRatio || 1,
        bsr = ctx.webkitBackingStorePixelRatio ||
              ctx.mozBackingStorePixelRatio ||
              ctx.msBackingStorePixelRatio ||
              ctx.oBackingStorePixelRatio ||
              ctx.backingStorePixelRatio || 1;

    return dpr / bsr;
})();


createHiDPICanvas = function(w, h, ratio) {
    if (!ratio) { ratio = PIXEL_RATIO; }
    var can = document.createElement("canvas");
    can.width = w * ratio;
    can.height = h * ratio;
    can.style.width = w + "px";
    can.style.height = h + "px";
    can.getContext("2d").setTransform(ratio, 0, 0, ratio, 0, 0);
    return can;
}

//Create canvas with the device resolution.
var myCanvas = createHiDPICanvas(500, 250);

//Create canvas with a custom resolution.
var myCustomCanvas = createHiDPICanvas(500, 200, 4);

Spero che sia di aiuto!


2
Ho pensato che valesse la pena ricordare che il mio metodo createHiDPI () è un po 'mal nominato. DPI è un termine solo per la stampa e PPI è un acronimo più appropriato in quanto i monitor visualizzano le immagini utilizzando i pixel anziché i punti.
MyNameIsKo

3
Nota che questo rapporto può effettivamente cambiare durante la vita della pagina. Ad esempio, se trascino una finestra di Chrome da un vecchio monitor esterno "standard" res a uno schermo retina integrato di un macbook, il codice calcolerà un rapporto diverso. Solo un FYI se prevedi di memorizzare nella cache questo valore. (esterno era rapporto 1, retina schermo 2 nel caso foste curiosi)
Aardvark

1
Grazie per questa spiegazione. Ma per quanto riguarda le risorse immagine? Dobbiamo fornire ogni immagine su tela a doppia risoluzione e ridimensionarla manualmente?
Kokodoko

1
Altre curiosità: IE di Windows Phone 8 riporta sempre 1 per window.devicePixelRatio (e la chiamata dei pixel di supporto non funziona). Sembra orribile a 1, ma un rapporto di 2 sembra buono. Per ora i miei calcoli del rapporto restituiscono comunque almeno un 2 (soluzione alternativa scadente, ma le mie piattaforme di destinazione sono telefoni moderni che sembrano quasi tutti avere schermi DPI alti). Testato su HTC 8X e Lumia 1020.
Aardvark

1
@Aardvark: sembra anche che msBackingStorePixelRatio sia sempre indefinito. Ho posto una nuova domanda al riguardo qui: stackoverflow.com/questions/22483296/…
TV's Frank

29

Risolto!

Ho deciso di vedere quale modifica degli attributi di larghezza e altezza ho impostato javascriptper vedere come ciò ha influito sulle dimensioni della tela - e non è stato così. Cambia la risoluzione.

Per ottenere il risultato che volevo, ho dovuto anche impostare l' canvas.style.widthattributo, che cambia la dimensione fisica di canvas:

canvas.width=1000;//horizontal resolution (?) - increase for better looking text
canvas.height=500;//vertical resolution (?) - increase for better looking text
canvas.style.width=width;//actual width of canvas
canvas.style.height=height;//actual height of canvas

1
Per risultati ideali, non toccare affatto gli attributi di stile della tela e controllare solo le dimensioni con gli attributi di larghezza e altezza della tela stessa. In questo modo ti assicuri che un pixel sulla tela sia uguale a un pixel sullo schermo.
Philipp

7
Non sono d'accordo. La modifica degli attributi style.width / height è esattamente il modo in cui crei una tela HiDPI.
MyNameIsKo

2
Nella tua risposta, imposti canvas.width a 1000 e canvas.style.width a metà a 500. Funziona ma solo per un dispositivo con un rapporto pixel di 2. Per qualsiasi cosa al di sotto di questo, come il monitor del desktop, la tela è ora disegnare in pixel non necessari. Per rapporti più alti ora sei tornato al punto di partenza con un elemento / risorsa sfocato a bassa risoluzione. Un altro problema a cui Philipp sembrava alludere è che tutto ciò che disegni nel tuo contesto deve ora essere disegnato sulla tua larghezza / altezza raddoppiata anche se viene visualizzato a metà di quel valore. La soluzione a questo problema è impostare il doppio del contesto della tela.
MyNameIsKo

3
Esiste window.devicePixelRatioed è ben implementato nella maggior parte dei browser moderni.
Chen

6

Ridimensiono l'elemento canvas tramite css per prendere l'intera larghezza dell'elemento genitore. Ho notato che la larghezza e l'altezza del mio elemento non vengono ridimensionate. Stavo cercando il modo migliore per impostare la dimensione che dovrebbe essere.

canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;

In questo modo semplice la tua tela sarà impostata perfettamente, indipendentemente dallo schermo che utilizzerai.


5

Questo ha risolto al 100% per me:

var canvas = document.getElementById('canvas');
canvas.width = canvas.getBoundingClientRect().width;
canvas.height = canvas.getBoundingClientRect().height;

(è vicino alla soluzione di Adam Mańkowski).


4

Ho notato un dettaglio non menzionato nelle altre risposte. La risoluzione della tela viene troncata a valori interi.

Le dimensioni di risoluzione della tela predefinite sono canvas.width: 300ecanvas.height: 150 .

Sul mio schermo window.devicePixelRatio: 1.75 .

Quindi quando imposto canvas.height = 1.75 * 150il valore viene troncato da quello desiderato 262.5a262 .

Una soluzione è scegliere le dimensioni del layout CSS per un dato window.devicePixelRatio modo che il troncamento non si verifichi ridimensionando la risoluzione.

Ad esempio, potrei usare width: 300pxe height: 152pxche produrrebbe numeri interi quando moltiplicato per 1.75.

modificare : un'altra soluzione è sfruttare il fatto che i pixel CSS possono essere frazionari per contrastare il troncamento del ridimensionamento dei pixel della tela.

Di seguito è riportata una demo che utilizza questa strategia.

Modifica : ecco il violino dell'OP aggiornato per utilizzare questa strategia: http://jsfiddle.net/65maD/83/ .

main();

// Rerun on window resize.
window.addEventListener('resize', main);


function main() {
  // Prepare canvas with properly scaled dimensions.
  scaleCanvas();

  // Test scaling calculations by rendering some text.
  testRender();
}


function scaleCanvas() {
  const container = document.querySelector('#container');
  const canvas = document.querySelector('#canvas');

  // Get desired dimensions for canvas from container.
  let {width, height} = container.getBoundingClientRect();

  // Get pixel ratio.
  const dpr = window.devicePixelRatio;
  
  // (Optional) Report the dpr.
  document.querySelector('#dpr').innerHTML = dpr.toFixed(4);

  // Size the canvas a bit bigger than desired.
  // Use exaggeration = 0 in real code.
  const exaggeration = 20;
  width = Math.ceil (width * dpr + exaggeration);
  height = Math.ceil (height * dpr + exaggeration);

  // Set the canvas resolution dimensions (integer values).
  canvas.width = width;
  canvas.height = height;

  /*-----------------------------------------------------------
                         - KEY STEP -
   Set the canvas layout dimensions with respect to the canvas
   resolution dimensions. (Not necessarily integer values!)
   -----------------------------------------------------------*/
  canvas.style.width = `${width / dpr}px`;
  canvas.style.height = `${height / dpr}px`;

  // Adjust canvas coordinates to use CSS pixel coordinates.
  const ctx = canvas.getContext('2d');
  ctx.scale(dpr, dpr);
}


function testRender() {
  const canvas = document.querySelector('#canvas');
  const ctx = canvas.getContext('2d');
  
  // fontBaseline is the location of the baseline of the serif font
  // written as a fraction of line-height and calculated from the top
  // of the line downwards. (Measured by trial and error.)
  const fontBaseline = 0.83;
  
  // Start at the top of the box.
  let baseline = 0;

  // 50px font text
  ctx.font = `50px serif`;
  ctx.fillText("Hello World", 0, baseline + fontBaseline * 50);
  baseline += 50;

  // 25px font text
  ctx.font = `25px serif`;
  ctx.fillText("Hello World", 0, baseline + fontBaseline * 25);
  baseline += 25;

  // 12.5px font text
  ctx.font = `12.5px serif`;
  ctx.fillText("Hello World", 0, baseline + fontBaseline * 12.5);
}
/* HTML is red */

#container
{
  background-color: red;
  position: relative;
  /* Setting a border will mess up scaling calculations. */
  
  /* Hide canvas overflow (if any) in real code. */
  /* overflow: hidden; */
}

/* Canvas is green */ 

#canvas
{
  background-color: rgba(0,255,0,.8);
  animation: 2s ease-in-out infinite alternate both comparison;
}

/* animate to compare HTML and Canvas renderings */

@keyframes comparison
{
  33% {opacity:1; transform: translate(0,0);}
  100% {opacity:.7; transform: translate(7.5%,15%);}
}

/* hover to pause */

#canvas:hover, #container:hover > #canvas
{
  animation-play-state: paused;
}

/* click to translate Canvas by (1px, 1px) */

#canvas:active
{
  transform: translate(1px,1px) !important;
  animation: none;
}

/* HTML text */

.text
{
  position: absolute;
  color: white;
}

.text:nth-child(1)
{
  top: 0px;
  font-size: 50px;
  line-height: 50px;
}

.text:nth-child(2)
{
  top: 50px;
  font-size: 25px;
  line-height: 25px;
}

.text:nth-child(3)
{
  top: 75px;
  font-size: 12.5px;
  line-height: 12.5px;
}
<!-- Make the desired dimensions strange to guarantee truncation. -->
<div id="container" style="width: 313.235px; height: 157.122px">
  <!-- Render text in HTML. -->
  <div class="text">Hello World</div>
  <div class="text">Hello World</div>
  <div class="text">Hello World</div>
  
  <!-- Render text in Canvas. -->
  <canvas id="canvas"></canvas>
</div>

<!-- Interaction instructions. -->
<p>Hover to pause the animation.<br>
Click to translate the green box by (1px, 1px).</p>

<!-- Color key. -->
<p><em style="color:red">red</em> = HTML rendered<br>
<em style="color:green">green</em> = Canvas rendered</p>

<!-- Report pixel ratio. -->
<p>Device pixel ratio: <code id="dpr"></code>
<em>(physical pixels per CSS pixel)</em></p>

<!-- Info. -->
<p>Zoom your browser to re-run the scaling calculations.
(<code>Ctrl+</code> or <code>Ctrl-</code>)</p>


3

Ho adattato leggermente il codice MyNameIsKo sotto canvg ( libreria SVG to Canvas js). Sono stato confuso per un po 'e ho passato un po' di tempo per questo. Spero che questo aiuti qualcuno.

HTML

<div id="chart"><canvas></canvas><svg>Your SVG here</svg></div>

Javascript

window.onload = function() {

var PIXEL_RATIO = (function () {
    var ctx = document.createElement("canvas").getContext("2d"),
        dpr = window.devicePixelRatio || 1,
        bsr = ctx.webkitBackingStorePixelRatio ||
              ctx.mozBackingStorePixelRatio ||
              ctx.msBackingStorePixelRatio ||
              ctx.oBackingStorePixelRatio ||
              ctx.backingStorePixelRatio || 1;

    return dpr / bsr;
})();

setHiDPICanvas = function(canvas, w, h, ratio) {
    if (!ratio) { ratio = PIXEL_RATIO; }
    var can = canvas;
    can.width = w * ratio;
    can.height = h * ratio;
    can.style.width = w + "px";
    can.style.height = h + "px";
    can.getContext("2d").setTransform(ratio, 0, 0, ratio, 0, 0);
}

var svg = document.querySelector('#chart svg'),
    canvas = document.querySelector('#chart canvas');

var svgSize = svg.getBoundingClientRect();
var w = svgSize.width, h = svgSize.height;
setHiDPICanvas(canvas, w, h);

var svgString = (new XMLSerializer).serializeToString(svg);
var ctx = canvas.getContext('2d');
ctx.drawSvg(svgString, 0, 0, w, h);

}

2

Per quelli di voi che lavorano in reactjs, ho adattato la risposta di MyNameIsKo e funziona alla grande. Ecco il codice.

import React from 'react'

export default class CanvasComponent extends React.Component {
    constructor(props) {
        this.calcRatio = this.calcRatio.bind(this);
    } 

    // Use componentDidMount to draw on the canvas
    componentDidMount() {  
        this.updateChart();
    }

    calcRatio() {
        let ctx = document.createElement("canvas").getContext("2d"),
        dpr = window.devicePixelRatio || 1,
        bsr = ctx.webkitBackingStorePixelRatio ||
          ctx.mozBackingStorePixelRatio ||
          ctx.msBackingStorePixelRatio ||
          ctx.oBackingStorePixelRatio ||
          ctx.backingStorePixelRatio || 1;
        return dpr / bsr;
    }

    // Draw on the canvas
    updateChart() {

        // Adjust resolution
        const ratio = this.calcRatio();
        this.canvas.width = this.props.width * ratio;
        this.canvas.height = this.props.height * ratio;
        this.canvas.style.width = this.props.width + "px";
        this.canvas.style.height = this.props.height + "px";
        this.canvas.getContext("2d").setTransform(ratio, 0, 0, ratio, 0, 0);
        const ctx = this.canvas.getContext('2d');

       // now use ctx to draw on the canvas
    }


    render() {
        return (
            <canvas ref={el=>this.canvas=el} width={this.props.width} height {this.props.height}/>
        )
    }
}

In questo esempio, passo la larghezza e l'altezza della tela come oggetti di scena.


2

Prova questa riga di CSS sulla tua tela: image-rendering: pixelated

Secondo MDN :

Quando si ridimensiona l'immagine, è necessario utilizzare l'algoritmo del vicino più vicino, in modo che l'immagine sembri composta da pixel grandi.

Quindi impedisce completamente l'anti-aliasing.


2

Anche se la risposta di @ MyNameIsKo funziona ancora, è un po 'obsoleta ora nel 2020 e può essere migliorata:

function createHiPPICanvas(w, h) {
    let ratio = window.devicePixelRatio;
    let cv = document.createElement("canvas");
    cv.width = w * ratio;
    cv.height = h * ratio;
    cv.style.width = w + "px";
    cv.style.height = h + "px";
    cv.getContext("2d").scale(ratio, ratio);
    return cv;
}

In generale, apportiamo i seguenti miglioramenti:

  • Rimuoviamo i backingStorePixelRatioriferimenti, poiché questi non sono realmente implementati in nessun browser in alcun modo importante (infatti, solo Safari restituisce qualcosa di diverso daundefined , e questa versione funziona ancora perfettamente in Safari);
  • Sostituiamo tutto quel codice di rapporto con window.devicePixelRatio, che ha un supporto fantastico
  • Ciò significa anche che dichiariamo una proprietà globale in meno --- evviva !!
  • Possiamo anche rimuovere il || 1fallback su window.devicePixelRatio, poiché è inutile: tutti i browser che non supportano questa proprietà non lo supportano .setTransformo non lo supportano .scale, quindi questa funzione non funzionerà su di loro, fallback o no;
  • Possiamo sostituire .setTransformcon .scale, poiché passare in larghezza e altezza è un po 'più intuitivo che passare in una matrice di trasformazione.
  • La funzione è stata rinominata da createHiDPICanvasa createHiPPICanvas. Come gli stessi @MyNameIsKo menzionano nei commenti della loro risposta, DPI (Dots per Inch) sta stampando la terminologia (poiché le stampanti creano immagini con piccoli punti di inchiostro colorato). Sebbene simili, i monitor visualizzano le immagini utilizzando i pixel e, in quanto tale, PPI (Pixel per pollice) è un acronimo migliore per il nostro caso d'uso.

Un grande vantaggio di queste semplificazioni è che questa risposta può ora essere utilizzata in TypeScript senza // @ts-ignore(poiché TS non ha tipi per backingStorePixelRatio).


0

Per me, solo una combinazione di diverse tecniche di "pixel perfetto" ha aiutato ad archiviare i risultati:

  1. Ottieni e ridimensiona con un rapporto pixel come suggerito da @MyNameIsKo.

    pixelRatio = window.devicePixelRatio / ctx.backingStorePixelRatio

  2. Ridimensiona la tela sul ridimensionamento (evita il ridimensionamento predefinito della tela).

  3. moltiplicare la lineWidth con pixelRatio per trovare il corretto spessore della linea pixel 'reale':

    context.lineWidth = spessore * pixelRatio;

  4. Controlla se lo spessore della linea è pari o dispari. aggiungere metà del pixelRatio alla posizione della linea per i valori di spessore dispari.

    x = x + pixelRatio / 2;

La linea dispari verrà posizionata al centro del pixel. La linea sopra è usata per spostarlo un po '.

function getPixelRatio(context) {
  dpr = window.devicePixelRatio || 1,
    bsr = context.webkitBackingStorePixelRatio ||
    context.mozBackingStorePixelRatio ||
    context.msBackingStorePixelRatio ||
    context.oBackingStorePixelRatio ||
    context.backingStorePixelRatio || 1;

  return dpr / bsr;
}


var canvas = document.getElementById('canvas');
var context = canvas.getContext("2d");
var pixelRatio = getPixelRatio(context);
var initialWidth = canvas.clientWidth * pixelRatio;
var initialHeight = canvas.clientHeight * pixelRatio;


window.addEventListener('resize', function(args) {
  rescale();
  redraw();
}, false);

function rescale() {
  var width = initialWidth * pixelRatio;
  var height = initialHeight * pixelRatio;
  if (width != context.canvas.width)
    context.canvas.width = width;
  if (height != context.canvas.height)
    context.canvas.height = height;

  context.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);
}

function pixelPerfectLine(x) {

  context.save();
  context.beginPath();
  thickness = 1;
  // Multiple your stroke thickness  by a pixel ratio!
  context.lineWidth = thickness * pixelRatio;

  context.strokeStyle = "Black";
  context.moveTo(getSharpPixel(thickness, x), getSharpPixel(thickness, 0));
  context.lineTo(getSharpPixel(thickness, x), getSharpPixel(thickness, 200));
  context.stroke();
  context.restore();
}

function pixelPerfectRectangle(x, y, w, h, thickness, useDash) {
  context.save();
  // Pixel perfect rectange:
  context.beginPath();

  // Multiple your stroke thickness by a pixel ratio!
  context.lineWidth = thickness * pixelRatio;
  context.strokeStyle = "Red";
  if (useDash) {
    context.setLineDash([4]);
  }
  // use sharp x,y and integer w,h!
  context.strokeRect(
    getSharpPixel(thickness, x),
    getSharpPixel(thickness, y),
    Math.floor(w),
    Math.floor(h));
  context.restore();
}

function redraw() {
  context.clearRect(0, 0, canvas.width, canvas.height);
  pixelPerfectLine(50);
  pixelPerfectLine(120);
  pixelPerfectLine(122);
  pixelPerfectLine(130);
  pixelPerfectLine(132);
  pixelPerfectRectangle();
  pixelPerfectRectangle(10, 11, 200.3, 443.2, 1, false);
  pixelPerfectRectangle(41, 42, 150.3, 443.2, 1, true);
  pixelPerfectRectangle(102, 100, 150.3, 243.2, 2, true);
}

function getSharpPixel(thickness, pos) {

  if (thickness % 2 == 0) {
    return pos;
  }
  return pos + pixelRatio / 2;

}

rescale();
redraw();
canvas {
  image-rendering: -moz-crisp-edges;
  image-rendering: -webkit-crisp-edges;
  image-rendering: pixelated;
  image-rendering: crisp-edges;
  width: 100vh;
  height: 100vh;
}
<canvas id="canvas"></canvas>

L'evento Resize non viene attivato nello snipped, quindi puoi provare il file su GitHub


0

Per me non era solo immagine, ma il testo aveva una cattiva qualità. La soluzione di lavoro cross browser più semplice per i display retina / non retina era quella di rendere l'immagine due volte più grande del previsto e ridimensionare il contesto della tela come suggerito da questo ragazzo: https://stackoverflow.com/a/53921030/4837965

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.