Tela redimensionar tela para adaptarse a la pantalla

Actualmente estoy desarrollando una aplicación en dispositivos móviles (android y iPhone) con ionic y cordova. Me gustaría editar una foto. Yo uso la biblioteca fabric.js para hacer eso. Fabric.js convierte una imagen y otros elementos en lienzo. A continuación, añadir alguna imagen en el lienzo (pegatinas) y exportar como una imagen (dataURL). Así que el tamaño del lienzo es realmente importante porque es un factor de calidad (exportar una imagen basada en lienzo pequeño resultará en mala calidad). El tamaño de la lona es de aproximadamente 607 * 1080 píxeles (dependiendo del dispositivo que tomó la foto). Me gustaría encajar en la pantalla sin perder calidad (como se explica a continuación no puedo cambiar el tamaño del lienzo sin perder calidad).

He intentado 3 ideas, pero nadie ha trabajado.

  1. Cambiar el tamaño del lienzo : resulta en calidad perdida (la imagen exportada tendrá tamaño de lienzo)
  2. Adaptar viewport : cordova no permite cambiar la ventana de visualización en el dispositivo móvil. Hay una solución pero romperá mi diseño (muy pequeño navbar, menú más pequeño, …)
  3. Utilice las propiedades de zoom CSS3 : Funciona como un encanto en el escritorio, pero hay un problema de asignación de eventos en el dispositivo móvil (no probé ios pero el problema ocurrió en android Webview). La asignación de eventos no se amplía. El lienzo se aleja pero es imposible interactuar con elementos de lienzo. Si un elemento de lienzo (etiqueta adhesiva) se encuentra en x: 100 y: 100, cuando establezco la propiedad de zoom a 0,5, el elemento será la ubicación en (50,50) y no más en (100,100). ¿Hay alguna forma de corregir la asignación de eventos dependiendo de la propiedad zoom de la vista web de Android?

No sé si hay otras maneras de hacer eso, pero estoy estancado con este problema durante 3 días y he pasado mucho tiempo en los foros, doc de fabricjs y google y no encuentro ninguna solución de trabajo o Otra cosa que me puede ayudar.

EDIT: Hay 2 solución de trabajo a continuación. Revisa mi respuesta para ver cómo hacerlo con css.

1. Utilice css para establecer su resolución correcta para el lienzo:

var canvas = document.getElementById("canvas"), ctx = canvas.getContext("2d"); canvas.width = 800; canvas.height = 600; 

Css

 /* media query 1 */ #canvas{ width: 400px; height: 250px; } /* media query 2 */ #canvas{ width: 200px; height: 120px; } 

Pros

Toda la resolución está dada por el ancho y la altura de la lona (800/600)

contras:

Se adapta bien a la relación de aspecto de cuadros cuadrados (1: 1), problemas con la salida para las proporciones de aspecto extraño donde necesita calcular su altura css basado,

 original height / original width * new width = new height; 

Esto es fuera de mi liga en css …

Leído hace algún tiempo en la sección de temas de fabric.js git donde, la técnica (css cambiar el tamaño) no se recomienda debido a la lentitud y las transacciones de objetos incorrectos, esto puede cambiarse Sé que probé y los objetos eran incorrectos de tamaño (píxeles de color aleatorio, Las sombras de las transacciones permanecen en lona, ​​en otras palabras un lío)

2. Re-tamaño de su lienzo a la dimensión exacta (resolución) cuando se necesita para enviar, y luego obtener la imagen generada

Simplemente vuelva a clasificar el tamaño de su lienzo en el re-tamaño de la ventana (lienzo responsivo) y cuando necesite exportar a la dimensión exacta necesita re tamaño de su lienzo para la resolución exacta de píxeles, o crear otro lienzo oculto.

Este ejemplo es para el lienzo de racionamiento 1: 1 (necesita aplicar relación de aspecto a lienzo y objetos dentro):

 $(window).resize(function (){ if (canvas.width != $(".container").width()) { var scaleMultiplier = $(".container").width() / canvas.width; var objects = canvas.getObjects(); for (var i in objects) { objects[i].scaleX = objects[i].scaleX * scaleMultiplier; objects[i].scaleY = objects[i].scaleY * scaleMultiplier; objects[i].left = objects[i].left * scaleMultiplier; objects[i].top = objects[i].top * scaleMultiplier; objects[i].setCoords(); } canvas.setWidth(canvas.getWidth() * scaleMultiplier); canvas.setHeight(canvas.getHeight() * scaleMultiplier); canvas.renderAll(); canvas.calcOffset(); } }); 

Al enviar los datos de lienzo de exportación de tamaño de la lona a la resolución deseada, voila:

 function GetCanvasAtResoution(newWidth) { if (canvas.width != newWidth) { var scaleMultiplier = newWidth / canvas.width; var objects = canvas.getObjects(); for (var i in objects) { objects[i].scaleX = objects[i].scaleX * scaleMultiplier; objects[i].scaleY = objects[i].scaleY * scaleMultiplier; objects[i].left = objects[i].left * scaleMultiplier; objects[i].top = objects[i].top * scaleMultiplier; objects[i].setCoords(); } canvas.setWidth(canvas.getWidth() * scaleMultiplier); canvas.setHeight(canvas.getHeight() * scaleMultiplier); canvas.renderAll(); canvas.calcOffset(); } return canvas.toDataURL(); } ); 

No es un gran problema con las raciones diferentes entonces 1: 1 que necesita para calcular la escala multijugador de altura, así, fácil de entender relación: http://andrew.hedges.name/experiments/aspect_ratio/

He encontrado un truco para hacer eso sin tener que copiar el lienzo. Esta solución está muy cerca de la propiedad de zoom css, pero los eventos se manejan correctamente.

Este es un ejemplo para mostrar el lienzo de tamaño medio:

 -webkit-transform : scale(0.5); -webkit-transform-origin : 0 0; 
  • Android: ¿Cómo manejar el dibujo con métodos de lienzo en diferentes tamaños de pantalla?
  • Dibuja el texto dentro de un rectángulo relleno mediante el uso de Canvas Android
  • Dibujar una línea con un cierto ancho de píxel
  • Problema con ComposeShader en Android 4.1.1
  • Cómo dibujar una porción de mapa de bits a través de lienzo DrawBitmap
  • Implementación de Fling en lienzo android
  • Cómo corregir "lienzo: intentando utilizar un error de mapa de bits reciclado"?
  • Dibujo sobre lienzo - PorterDuff.Mode.CLEAR dibuja negro! ¿Por qué?
  • Android - dibujo táctil
  • ¿Cómo configurar un filtro de color para XWalkView? (Resuelto)
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.