Créer facilement des fonds d’écran pour tout appareil avec Transloadit
Choisir un nouveau fond d’écran pour vos appareils est toujours une entreprise difficile. Pourtant, rien n’est pire que de tomber sur le fond d’écran parfait et de constater qu’il n’est pas tout à fait adapté. Si cela vous est déjà arrivé, nous sommes là pour vous aider ! Découvrez comment exploiter la puissance de Transloadit pour redimensionner n’importe quel fond d’écran et l’adapter parfaitement à tout appareil.

Template
Comme le dit (en partie) le proverbe : « Apprends-lui à pêcher, et il mangera toute sa vie. » C’est pourquoi nous allons vous apprendre à créer un site web qui redimensionne automatiquement n’importe quel fond d’écran pour l’adapter à toutes les tailles d’écran 🎣
La première étape de la création de notre site consiste à créer un Template Transloadit. Un
Template est une série d’Assembly Instructions que Transloadit utilisera ensuite
pour redimensionner notre fond d’écran aux bonnes dimensions, en utilisant fillcrop comme
stratégie de redimensionnement. Voici ci-dessous le
Template que nous utiliserons aujourd’hui.
{
"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
}
}
}
Vous remarquerez peut-être que nous utilisons ${fields.height} et ${fields.width}. Il s’agit de champs qui
peuvent être transmis dynamiquement à un Template, afin que nous puissions ajuster son comportement à l’exécution.
Plus généralement, ce sont des Assembly Variables, et il en existe toute une variété
que vous pouvez utiliser dans vos Assemblies. Découvrez les différentes utilisations des Assembly
Variables ici.
Avant tout déploiement public, utilisez des signatures générées côté serveur et validez
les dimensions demandées sur votre serveur. Gardez votre Auth Secret hors du code exécuté dans le
navigateur. L’exemple pour navigateur ci-dessous illustre le comportement du téléversement et de
l’aperçu avec votre propre Template et votre propre Auth Key.
Remplacez S3_CREDENTIALS par le nom de votre
ensemble d’informations d’identification de Template enregistré ; ne collez pas de secrets S3
dans l’exemple.
HTML et CSS
Nous n’allons pas examiner le HTML et le CSS aussi en détail que d’habitude, mais n’hésitez pas à jeter un œil aux deux ci-dessous si vous souhaitez les copier-coller dans votre propre projet.
<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
Nous pouvons maintenant examiner ma partie préférée de chaque article de blog : le code d’intégration.
Placez ce script après le HTML, dans une balise <script type="module">. Remplacez les espaces réservés de
l’Auth Key et de l’identifiant de Template par vos propres valeurs.
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()
}
Passons le code au peigne fin, ligne par ligne.
Comme nous créons un site web, nous commençons naturellement par importer le meilleur outil de
téléversement de fichiers au monde, Uppy. Nous devons d’abord créer une nouvelle instance
d’Uppy, puis initialiser tous nos plugins. Pour la démo d’aujourd’hui, nous utiliserons :
le plugin Drop target,
le plugin Informer,
le plugin de barre de progression et enfin, le
plugin Transloadit. Point important : nous définissons autoProceed sur
true, afin que notre fichier soit téléversé vers Transloadit dès que nous déposons une image sur l’aperçu.
Ensuite, nous déclarons quelques variables et constantes qui serviront plus tard dans nos fonctions,
ainsi qu’un tableau de résolutions. Nous pourrons ensuite appeler la fonction appendButton pour
chaque résolution afin de créer un bouton correspondant à chaque taille d’écran que nous voulons cibler.
Fonctions
Passons maintenant à chacune des fonctions auxquelles nous faisons référence.
La fonction setPreviewImage est appelée depuis l’événement transloadit:complete d’Uppy, qui se déclenche
chaque fois que l’Assembly Transloadit est terminée. Nous inspectons ensuite le JSON de
l’Assembly de notre résultat et récupérons la valeur ssl_url du fichier dans notre bucket S3. Nous
pouvons alors rendre l’image d’aperçu visible et lui attribuer la bonne image.
Puisque nous définissons une image d’aperçu, nous voudrons aussi pouvoir l’effacer ! C’est là
qu’intervient clearPreview, au nom bien choisi. Cette fonction accomplit deux tâches très simples :
elle masque l’élément de l’image d’aperçu et retire d’Uppy tout fichier en attente. Une fois un
résultat affiché, setPreviewImage libère également le fichier terminé, afin qu’une autre photo puisse
être déposée sans devoir d’abord appuyer sur Clear.
Le plugin Transloadit est installé une seule fois. Sa fonction assemblyOptions lit les dimensions entières
sélectionnées au début de chaque téléversement et les envoie sous forme de champs avec les
paramètres. Changer de résolution ne réinstalle donc pas le plugin et ne calcule pas le nombre de
pixels à partir des dimensions mises à l’échelle de l’aperçu. Le champ de fichier permet également
de choisir une photo sans glisser-déposer.
Vient ensuite appendButton ! Son fonctionnement parle de lui-même. Nous créons un élément bouton à
partir de l’une des paires de résolution. À noter : nous ajoutons deux attributs data, data-width et
data-height, simplement pour pouvoir récupérer plus facilement ces valeurs depuis le bouton par la
suite.
Dernière fonction, mais non la moindre : setPreviewBoxDimensions. Ici, nous récupérons les attributs data
mentionnés précédemment et les utilisons pour redimensionner notre zone d’aperçu au même rapport
hauteur/largeur, simplement un peu réduite pour tenir dans la page.
Résultats finaux
Combinez le HTML, le CSS et le script de module, configurez votre Template, puis servez la page en local.
Choisissez une résolution, sélectionnez ou déposez une photo, puis ouvrez le fond d’écran obtenu pour l’enregistrer depuis votre navigateur. L’image redimensionnée s’adapte à l’appareil sélectionné, d’un smartphone Samsung Galaxy à un écran de bureau ultra-large.
Et voilà, nous arrivons à la fin de l’article d’aujourd’hui ! Si vous attendez avec impatience le prochain article, n’oubliez pas de vous inscrire à la newsletter pour recevoir les dernières nouvelles sur les évolutions de Transloadit, ainsi que des articles techniques que nous trouvons intéressants.
