📋 Overview del Sistema
Il sistema di gestione texture permette di utilizzare fotografie reali dei tessuti nel configuratore,
mantenendo proporzioni corrette e performance ottimali.
1
Fotografia
Scatta foto dei tessuti
2
Processamento
Ottimizza e crea pattern
3
Integrazione
Carica nel configuratore
4
Applicazione
Visualizza sulla camicia
🚀 Implementazione Rapida
1. Struttura File Consigliata
project/
├── index.html
├── js/
│ └── configurator.js
├── textures/
│ ├── originals/
│ │ ├── cotton-white-hd.jpg
│ │ ├── oxford-blue-hd.jpg
│ │ └── linen-beige-hd.jpg
│ ├── processed/
│ │ ├── cotton-white.jpg
│ │ ├── oxford-blue.jpg
│ │ └── linen-beige.jpg
│ └── thumbnails/
│ ├── cotton-white-thumb.jpg
│ ├── oxford-blue-thumb.jpg
│ └── linen-beige-thumb.jpg
2. Database Texture JSON
const textureDatabase = {
"fabrics": [
{
"id": "cotton-white-001",
"name": "Cotone Bianco Oxford",
"category": "cotone",
"price": 59,
"texture": {
"image": "textures/processed/cotton-white.jpg",
"thumbnail": "textures/thumbnails/cotton-white-thumb.jpg",
"scale": 100,
"rotation": 0,
"seamless": true,
"resolution": "500x500"
},
"properties": {
"weight": "120g/m²",
"composition": "100% Cotone",
"weave": "Oxford",
"stretch": false,
"iron": "easy-iron"
},
"colors": {
"primary": "#ffffff",
"secondary": "#f8f9fa"
}
},
{
"id": "oxford-blue-002",
"name": "Oxford Azzurro",
"category": "cotone",
"price": 59,
"texture": {
"image": "textures/processed/oxford-blue.jpg",
"thumbnail": "textures/thumbnails/oxford-blue-thumb.jpg",
"scale": 100,
"rotation": 0,
"seamless": true,
"resolution": "500x500"
}
}
]
};
3. Classe TextureManager
class TextureManager {
constructor() {
this.loadedTextures = new Map();
this.currentTexture = null;
}
async preloadTextures(textureList) {
const promises = textureList.map(async (texture) => {
const img = new Image();
img.crossOrigin = 'anonymous';
return new Promise((resolve, reject) => {
img.onload = () => {
this.loadedTextures.set(texture.id, {
image: img,
data: texture
});
resolve();
};
img.onerror = reject;
img.src = texture.texture.image;
});
});
await Promise.all(promises);
console.log(`✅ Caricate ${this.loadedTextures.size} texture`);
}
applyTexture(textureId, svgElement) {
const texture = this.loadedTextures.get(textureId);
if (!texture) return;
let defs = svgElement.querySelector('defs');
if (!defs) {
defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
svgElement.prepend(defs);
}
const existingPattern = defs.querySelector('#fabric-pattern');
if (existingPattern) existingPattern.remove();
const pattern = this.createSVGPattern(texture);
defs.appendChild(pattern);
const shirtParts = svgElement.querySelectorAll('.fabric-fill');
shirtParts.forEach(part => {
part.setAttribute('fill', 'url(#fabric-pattern)');
});
this.currentTexture = textureId;
}
createSVGPattern(texture) {
const pattern = document.createElementNS('http://www.w3.org/2000/svg', 'pattern');
pattern.setAttribute('id', 'fabric-pattern');
pattern.setAttribute('patternUnits', 'userSpaceOnUse');
const baseSize = 50;
const scale = texture.data.texture.scale / 100;
const size = baseSize * scale;
pattern.setAttribute('width', size);
pattern.setAttribute('height', size);
if (texture.data.texture.rotation) {
pattern.setAttribute('patternTransform',
`rotate(${texture.data.texture.rotation})`);
}
const image = document.createElementNS('http://www.w3.org/2000/svg', 'image');
image.setAttribute('href', texture.data.texture.image);
image.setAttribute('width', size);
image.setAttribute('height', size);
pattern.appendChild(image);
return pattern;
}
adjustScale(scaleFactor) {
const pattern = document.querySelector('#fabric-pattern');
if (!pattern) return;
const currentWidth = parseFloat(pattern.getAttribute('width'));
const newWidth = currentWidth * scaleFactor;
pattern.setAttribute('width', newWidth);
pattern.setAttribute('height', newWidth);
const image = pattern.querySelector('image');
image.setAttribute('width', newWidth);
image.setAttribute('height', newWidth);
}
}
const textureManager = new TextureManager();
await textureManager.preloadTextures(textureDatabase.fabrics);
textureManager.applyTexture('cotton-white-001', document.querySelector('#shirt-svg'));
⚙️ Ottimizzazione Performance
Strategie Chiave
🖼️
Compressione Intelligente
- JPG 80-85% qualità
- Max 500x500px per pattern
- WebP per browser moderni
⚡
Lazy Loading
- Carica solo texture visibili
- Preload on hover
- Cache browser ottimizzata
🎯
Pattern Seamless
- Bordi perfettamente allineati
- Nessuna discontinuità visibile
- Dimensioni potenze di 2
Script Batch Processing (Node.js)
const sharp = require('sharp');
const fs = require('fs').promises;
const path = require('path');
async function processTextures(inputDir, outputDir) {
const files = await fs.readdir(inputDir);
for (const file of files) {
if (!file.match(/\.(jpg|jpeg|png)$/i)) continue;
const inputPath = path.join(inputDir, file);
const basename = path.basename(file, path.extname(file));
await sharp(inputPath)
.resize(500, 500, {
fit: 'cover',
position: 'centre'
})
.jpeg({
quality: 85,
progressive: true
})
.toFile(path.join(outputDir, 'processed', `${basename}.jpg`));
await sharp(inputPath)
.resize(150, 150, {
fit: 'cover'
})
.jpeg({
quality: 70
})
.toFile(path.join(outputDir, 'thumbnails', `${basename}-thumb.jpg`));
console.log(`✅ Processato: ${basename}`);
}
}
processTextures('./textures/originals', './textures');
📊 Specifiche Tecniche Pattern
| Parametro |
Valore Consigliato |
Note |
| Dimensioni |
500x500px |
Bilancia qualità e performance |
| Formato |
JPG o WebP |
JPG per compatibilità, WebP per modernità |
| Qualità |
80-85% |
Ottimale per texture tessuti |
| DPI |
72-150 |
Web standard |
| Peso File |
< 100KB |
Per caricamento rapido |
| Seamless |
Sì |
Bordi devono combaciare perfettamente |
🎯 Mappatura Texture su Camicia
Sistema di Coordinate UV
Importante: Per mantenere proporzioni realistiche, diverse parti della camicia
possono richiedere scale diverse del pattern.
const shirtMapping = {
"body": {
"scale": 1.0,
"rotation": 0,
"offsetX": 0,
"offsetY": 0
},
"sleeves": {
"scale": 0.9,
"rotation": 0,
"offsetX": 25,
"offsetY": 0
},
"collar": {
"scale": 0.8,
"rotation": 0,
"offsetX": 0,
"offsetY": 10
},
"cuffs": {
"scale": 0.7,
"rotation": 90,
"offsetX": 0,
"offsetY": 0
},
"pocket": {
"scale": 0.6,
"rotation": 0,
"offsetX": 15,
"offsetY": 30
}
};
function applyMappedTexture(svgElement, textureId, partName) {
const mapping = shirtMapping[partName];
const part = svgElement.querySelector(`.shirt-${partName}`);
if (!part || !mapping) return;
const patternId = `pattern-${partName}`;
const pattern = createPatternForPart(textureId, mapping, patternId);
svgElement.querySelector('defs').appendChild(pattern);
part.setAttribute('fill', `url(#${patternId})`);
}
✨ Tips & Tricks Avanzati
1. Creazione Pattern Seamless con Photoshop
- Apri immagine texture (almeno 1000x1000px)
- Filter → Other → Offset
- Horizontal: +250px
- Vertical: +250px
- Wrap Around: ✓
- Usa Clone Stamp per eliminare le giunture visibili
- Filter → Other → Offset di nuovo (-250px) per verificare
- Esporta come JPG 85% qualità
2. Testing Pattern Live
function testTexture(imageUrl) {
const svg = document.querySelector('#shirt-svg');
const pattern = svg.querySelector('#fabric-pattern image');
if (pattern) {
pattern.setAttribute('href', imageUrl);
console.log('✅ Texture applicata!');
}
}
testTexture('https://example.com/my-texture.jpg');
const fileInput = document.querySelector('#texture-upload');
fileInput.onchange = (e) => {
const reader = new FileReader();
reader.onload = (event) => testTexture(event.target.result);
reader.readAsDataURL(e.target.files[0]);
};
3. Gestione Memoria e Cache
Attenzione: Con molte texture ad alta risoluzione, gestisci attentamente la memoria.
class TextureCache {
constructor(maxSize = 10) {
this.cache = new Map();
this.maxSize = maxSize;
}
add(key, value) {
if (this.cache.size >= this.maxSize) {
const firstKey = this.cache.keys().next().value;
this.cache.delete(firstKey);
}
this.cache.set(key, value);
}
get(key) {
const value = this.cache.get(key);
if (value) {
this.cache.delete(key);
this.cache.set(key, value);
}
return value;
}
clear() {
this.cache.clear();
}
}
🚀 Prossimi Passi
Setup Completo in 5 Minuti:
- Copia il codice del TextureManager
- Prepara le tue texture (500x500px JPG)
- Crea il database JSON con i tuoi tessuti
- Integra nel configuratore esistente
- Testa con texture di esempio
Risorse Utili
- Tool Online Pattern: seamless-pattern-maker.com
- Compressione: squoosh.app (Google)
- Test Performance: Chrome DevTools → Rendering → Paint flashing
- CDN Immagini: Cloudinary, Imgix per trasformazioni al volo