Crie wallpapers facilmente para todo aparelho com a Transloadit
Escolher um novo wallpaper para os seus dispositivos é sempre uma tarefa difícil. E não há nada pior do que encontrar o wallpaper perfeito e descobrir que ele não se encaixa muito bem. Se isso já aconteceu com você, estamos aqui para ajudar! Veja como você pode usar o poder da Transloadit para redimensionar qualquer wallpaper e fazê-lo se encaixar perfeitamente em qualquer dispositivo.

Template
Como diz (parte do) ditado: “Ensine um homem a pescar e você o alimentará por toda a vida.” Por isso, vamos ensinar você a criar um site que redimensiona automaticamente qualquer wallpaper para se ajustar a qualquer tamanho de tela 🎣
O primeiro passo para criar o nosso site é criar um Template da Transloadit. Um
Template é uma série de Assembly Instructions que a Transloadit usará depois
para redimensionar o nosso wallpaper para as dimensões corretas, usando a estratégia fillcrop,
uma das estratégias de redimensionamento. Abaixo está o
Template que vamos usar hoje.
{
"steps": {
":original": {
"robot": "/upload/handle"
},
"crop_thumbed": {
"use": ":original",
"robot": "/image/resize",
"height": "${fields.height}",
"width": "${fields.width}",
"imagemagick_stack": "v3.0.1",
"resize_strategy": "fillcrop"
},
"exported": {
"use": ["crop_thumbed"],
"robot": "/s3/store",
"credentials": "S3_CREDENTIALS",
"result": true
}
}
}
Você deve ter notado que estamos usando ${fields.height} e ${fields.width}. São campos que
podem ser passados dinamicamente para um Template, para que possamos ajustar o comportamento em tempo de execução.
De modo mais geral, essas são Assembly Variables, e há uma variedade delas
que você pode usar nas suas Assemblies. Saiba mais sobre os diferentes usos das Assembly
Variables aqui.
Antes de publicar, use assinaturas geradas no servidor e valide
as dimensões solicitadas no seu servidor. Mantenha o seu Auth Secret fora do código do navegador. O
exemplo para navegador abaixo demonstra o comportamento de upload e de pré-visualização usando o seu
próprio Template e a sua própria Auth Key. Substitua S3_CREDENTIALS pelo nome das suas
Credenciais de Template salvas; não cole segredos do S3 no exemplo.
HTML e CSS
Não vamos nos aprofundar tanto no HTML e no CSS quanto costumamos fazer, mas fique à vontade para dar uma olhada nos dois abaixo, caso queira copiá-los e colá-los no seu próprio projeto.
<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
Agora podemos dar uma olhada na minha parte favorita de cada post do blog: o código de integração.
Coloque este script depois do HTML, dentro de uma tag <script type="module">. Substitua os placeholders da Auth Key
e do Template ID pelos seus próprios 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.crop_thumbed?.[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()
}
Vamos analisar o código linha por linha.
Como estamos criando um site, naturalmente começamos importando o melhor uploader de arquivos do mundo,
o Uppy. Primeiro, precisamos criar uma nova instância do Uppy e, em seguida, inicializar todos
os nossos plugins. Para a demonstração de hoje, vamos usar o:
plugin Drop Target,
plugin Informer,
plugin Progress Bar e, por fim, o
plugin Transloadit. É importante notar que definimos autoProceed como
true, para que o nosso arquivo seja enviado por upload à Transloadit assim que soltarmos uma imagem sobre a pré-visualização.
Depois disso, declaramos algumas variáveis e constantes que serão usadas mais tarde nas nossas funções,
além de um array de resoluções. Depois, podemos chamar a função appendButton para cada resolução e
criar um botão correspondente a cada tamanho de tela que queremos atender.
Funções
Agora vamos passar para cada uma das funções que mencionamos.
A função setPreviewImage é chamada a partir do evento transloadit:complete do Uppy, que é
disparado sempre que a Assembly da Transloadit é concluída. Em seguida, inspecionamos o JSON
da Assembly do nosso resultado e obtemos a ssl_url do arquivo no nosso bucket S3. Então,
podemos definir a visibilidade da imagem de pré-visualização e atribuir a ela a imagem correta.
Como estamos definindo uma imagem de pré-visualização, também vamos querer limpá-la! É aí que entra a
função de nome bem apropriado clearPreview. Essa função realiza duas tarefas bem simples: ela oculta o
elemento da imagem de pré-visualização e remove qualquer arquivo pendente do Uppy. Depois que um resultado é exibido, setPreviewImage
também libera o arquivo concluído, para que outra foto possa ser solta sem que você precise antes pressionar Clear.
O plugin Transloadit é instalado uma única vez. A função assemblyOptions dele lê as dimensões
selecionadas, expressas em números inteiros de pixels, no início de cada upload e as envia como campos
junto com os parâmetros. Por isso, mudar a resolução não reinstala o plugin nem calcula a quantidade
de pixels a partir das dimensões redimensionadas da pré-visualização. O campo de arquivo também permite escolher uma foto sem arrastar e soltar.
Em seguida vem appendButton! O funcionamento aqui é bem autoexplicativo. Criamos um elemento
de botão usando um dos pares de resolução. Vale destacar que adicionamos dois atributos de dados, data-width e
data-height, só para facilitar um pouco a obtenção desses valores a partir do
botão mais tarde.
Por último, mas não menos importante, temos setPreviewBoxDimensions. Aqui, obtemos os atributos de dados
mencionados anteriormente e os usamos para redimensionar a nossa caixa de pré-visualização para a mesma
proporção, apenas um pouco reduzida para caber na página.
Resultados finais
Combine o HTML, o CSS e o script de módulo, configure o seu Template e sirva a página localmente.
Escolha uma resolução, selecione ou solte uma foto e abra o wallpaper resultante para salvá-lo pelo seu navegador. A imagem redimensionada se ajusta ao dispositivo selecionado, desde um smartphone Samsung Galaxy até um monitor ultrawide de desktop.
E com isso chegamos ao fim do post de hoje! Se você está ansioso pelo próximo post, não deixe de se inscrever na newsletter para receber novidades sobre os desenvolvimentos mais recentes da Transloadit, além de artigos de tecnologia que achamos interessantes.
