Crea fácilmente fondos de pantalla para cualquier dispositivo con Transloadit
Elegir un nuevo fondo de pantalla para tus dispositivos siempre es una tarea difícil. Y no hay nada peor que encontrar el fondo de pantalla perfecto y descubrir que no encaja del todo. Si te ha pasado, ¡estamos aquí para ayudarte! Mira cómo puedes usar la potencia de Transloadit para redimensionar cualquier fondo de pantalla y lograr que encaje a la perfección en cualquier dispositivo.

Template
Como dice (en parte) el refrán: «Enseña a un hombre a pescar y lo alimentarás toda la vida». Por eso vamos a enseñarte a crear un sitio web que redimensione automáticamente cualquier fondo de pantalla para que se ajuste a cualquier tamaño de pantalla 🎣
El primer paso para crear nuestro sitio web es crear un Template de Transloadit. Un
Template es una serie de Assembly Instructions que Transloadit usará después para
redimensionar nuestro fondo de pantalla a las dimensiones correctas, usando fillcrop
como estrategia de redimensionado. A continuación está el
Template que usaremos hoy.
{
"steps": {
":original": {
"robot": "/upload/handle"
},
"crop_thumbed": {
"use": ":original",
"robot": "/image/resize",
"height": "${fields.height}",
"width": "${fields.width}",
"imagemagick_stack": "v3",
"resize_strategy": "fillcrop"
},
"exported": {
"use": ["crop_thumbed"],
"robot": "/s3/store",
"credentials": "S3_CREDENTIALS",
"result": true
}
}
}
Quizá notes que usamos ${fields.height} y ${fields.width}. Son campos que
se pueden pasar dinámicamente a un Template, de modo que podamos ajustar el comportamiento
en tiempo de ejecución. Dicho de forma más general, son Assembly Variables, y hay una gran
variedad de ellas que puedes usar en tus Assemblies. Obtén más información sobre los distintos
usos de las Assembly Variables aquí.
Antes de desplegar públicamente, usa firmas generadas en el servidor y valida
las dimensiones solicitadas en tu servidor. Mantén tu Auth Secret fuera del código del navegador. El
ejemplo de navegador que aparece abajo muestra el comportamiento de subida y de vista previa usando
tu propio Template y tu propia Auth Key. Sustituye S3_CREDENTIALS por el nombre de tus
credenciales de Template guardadas; no pegues secretos de S3 en el ejemplo.
HTML y CSS
No vamos a profundizar en el HTML y el CSS tanto como solemos hacerlo, pero échales un vistazo a ambos más abajo, por si quieres copiarlos y pegarlos en tu propio proyecto.
<head>
<link href="https://releases.transloadit.com/uppy/v3.7.0/uppy.min.css" rel="stylesheet" />
</head>
<div class="content">
<h1>Wallpaper Resizer</h1>
<div class="button-list" id="preview-buttons"></div>
<label>Choose a photo <input id="photo-input" type="file" accept="image/*" /></label>
<p>You can also drop a photo over the frame</p>
<div id="preview-box"><img id="preview-image" alt="Resized wallpaper preview" hidden /></div>
<div id="progress-bar"></div>
<div class="button-list">
<a id="download" hidden>View wallpaper</a>
<button id="clear">Clear</button>
</div>
</div>
#preview-box {
border: 1px solid black;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
width: 384px;
max-width: 100%;
aspect-ratio: 16 / 9;
overflow: clip;
position: relative;
}
#preview-image {
position: absolute;
inset: 0;
height: 100%;
width: 100%;
object-fit: cover;
}
.content {
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
font-family: Helvetica;
}
.button-list {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 10px;
}
JavaScript
Ahora podemos ver mi parte favorita de cada blog, el código de integración.
Coloca este script después del HTML dentro de una etiqueta <script type="module">. Sustituye los
marcadores de posición de la Auth Key y el Template ID por tus propios valores.
import {
Uppy,
DropTarget,
Informer,
ProgressBar,
Transloadit,
} from 'https://releases.transloadit.com/uppy/v3.7.0/uppy.min.mjs'
const uppy = new Uppy({
restrictions: {
allowedFileTypes: ['image/*'],
maxNumberOfFiles: 1,
},
autoProceed: true,
})
.use(DropTarget, {
target: '#preview-box',
})
.use(Informer, {
target: 'body',
})
.use(ProgressBar, {
target: '#progress-bar',
fixed: true,
})
.use(Transloadit, {
waitForEncoding: true,
assemblyOptions: () => ({
params: {
auth: { key: 'YOUR_AUTH_KEY' },
template_id: 'YOUR_TEMPLATE_ID',
},
fields: { height: cropHeight, width: cropWidth },
}),
})
.on('transloadit:complete', setPreviewImage)
const previewBox = document.getElementById('preview-box')
const previewImage = document.getElementById('preview-image')
let cropHeight = 1080
let cropWidth = 1920
const resolutions = [
[1920, 1080],
[1080, 1920],
[2560, 1080],
[1080, 2560],
[1366, 768],
[768, 1366],
]
const previewScale = 0.2
resolutions.forEach(appendButton)
document.getElementById('clear').addEventListener('click', clearPreview)
document.getElementById('photo-input').addEventListener('change', (event) => {
const file = event.currentTarget.files[0]
if (file == null) return
clearPreview()
try {
uppy.addFile({ name: file.name, type: file.type, data: file })
} catch {
uppy.info('Choose one image file and try again.', 'error', 5000)
}
event.currentTarget.value = ''
})
function setPreviewImage(assembly) {
const url = assembly.results.exported?.[0]?.ssl_url
if (typeof url !== 'string') {
uppy.info('No wallpaper was returned. Please try again.', 'error', 5000)
return
}
previewImage.hidden = false
previewImage.src = url
const downloadButton = document.getElementById('download')
downloadButton.href = url
for (const file of uppy.getFiles()) uppy.removeFile(file.id)
downloadButton.hidden = false
}
function clearPreview() {
previewImage.hidden = true
previewImage.removeAttribute('src')
const downloadButton = document.getElementById('download')
downloadButton.hidden = true
downloadButton.removeAttribute('href')
for (const file of uppy.getFiles()) uppy.removeFile(file.id)
}
function appendButton(resolution) {
const buttonTextEl = document.createElement('button')
buttonTextEl.className = 'button'
buttonTextEl.innerText = `${resolution[0]}x${resolution[1]}`
buttonTextEl.setAttribute('data-width', resolution[0])
buttonTextEl.setAttribute('data-height', resolution[1])
buttonTextEl.addEventListener('click', setPreviewBoxDimensions)
document.getElementById('preview-buttons').appendChild(buttonTextEl)
}
function setPreviewBoxDimensions(e) {
cropHeight = Number(e.currentTarget.getAttribute('data-height'))
cropWidth = Number(e.currentTarget.getAttribute('data-width'))
previewBox.style.width = `${cropWidth * previewScale}px`
previewBox.style.aspectRatio = `${cropWidth} / ${cropHeight}`
clearPreview()
}
Repasemos el código línea por línea.
Como estamos creando un sitio web, empezamos naturalmente importando el mejor gestor de subidas de
archivos del mundo, Uppy. Primero necesitamos crear una nueva instancia de Uppy y
luego inicializar todos nuestros plugins. Para la demo de hoy usaremos:
el plugin Drop target,
el plugin Informer,
el plugin Progress bar y, por último, el
plugin Transloadit. Es importante que establezcamos autoProceed en
true, para que nuestro archivo se suba a Transloadit en cuanto soltemos una imagen sobre la vista previa.
Después de esto, declaramos algunas variables y constantes que usaremos más adelante en nuestras
funciones, así como un array de resoluciones. Luego podemos llamar a la función appendButton para cada resolución y
crear un botón correspondiente a cada tamaño de pantalla al que queremos apuntar.
Funciones
Pasemos ahora a cada una de las funciones a las que hacemos referencia.
La función setPreviewImage se llama desde el evento transloadit:complete de Uppy, que se
activa cada vez que termina la Assembly de Transloadit. Después inspeccionamos el Assembly
JSON de nuestro resultado y recuperamos el ssl_url del archivo en nuestro bucket de S3. Luego podemos
ajustar la visibilidad de la imagen de vista previa y asignarle la imagen correcta.
Ya que estamos estableciendo una imagen de vista previa, ¡también vamos a querer borrarla! Ahí es
donde entra en juego la función, con un nombre muy acertado, clearPreview. Esta función cumple
dos tareas muy básicas: oculta el elemento de la imagen de vista previa y elimina cualquier archivo
pendiente de Uppy. Una vez que se muestra un resultado, setPreviewImage también libera el archivo
completado, de modo que se pueda soltar otra foto sin pulsar antes Clear.
El plugin de Transloadit se instala una sola vez. Su función assemblyOptions lee las dimensiones
enteras seleccionadas al inicio de cada subida y las envía como campos junto con los parámetros. Por
lo tanto, cambiar la resolución no reinstala el plugin ni deduce el número de píxeles a partir de las
dimensiones escaladas de la vista previa. El campo de selección de archivos también permite elegir
una foto sin arrastrar y soltar.
¡Le sigue appendButton! La funcionalidad aquí se explica bastante por sí sola. Creamos un
elemento de botón usando uno de los pares de resolución. Cabe destacar que añadimos dos atributos de
datos, data-width y data-height, solo para que después nos resulte un poco más fácil recuperar estos valores
del botón.
Por último, pero no menos importante, está setPreviewBoxDimensions. Aquí recuperamos los atributos de
datos mencionados anteriormente y los usamos para redimensionar nuestra caja de vista previa con la
misma relación de aspecto, solo que reducida un poco para que quepa en la página.
Resultados finales
Combina el HTML, el CSS y el script de módulo, configura tu Template y sirve la página en local.
Elige una resolución, selecciona o suelta una foto y abre el fondo de pantalla resultante para guardarlo desde tu navegador. La imagen redimensionada se ajusta al dispositivo seleccionado, desde un smartphone Samsung Galaxy hasta un monitor de escritorio ultraancho.
¡Y con esto llegamos al final del blog de hoy! Si esperas con ganas el próximo blog, no olvides suscribirte al boletín para recibir novedades sobre los últimos avances de Transloadit, así como artículos técnicos que nos parecen interesantes.
