Estilo Artístico - Pontilhismo & Cubismo
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
body {
background: linear-gradient(135deg, #1a2a6c, #b21f1f, #1a2a6c);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
background-attachment: fixed;
}
.container {
background: rgba(255, 255, 255, 0.92);
border-radius: 20px;
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.3);
width: 100%;
max-width: 800px;
overflow: hidden;
}
header {
text-align: center;
padding: 30px 20px;
background: linear-gradient(to right, #4facfe, #00f2fe);
color: white;
}
h1 {
font-size: 2.2rem;
margin-bottom: 10px;
text-shadow: 0 2px 4px rgba(0,0,0,0.2);
}
.subtitle {
opacity: 0.9;
font-size: 1.1rem;
}
.upload-section {
padding: 30px;
text-align: center;
}
.file-input-label {
display: inline-block;
padding: 12px 25px;
background: linear-gradient(to right, #ff9a9e, #fad0c4);
color: white;
border-radius: 50px;
cursor: pointer;
font-weight: 600;
transition: all 0.3s ease;
border: none;
}
.file-input-label:hover {
transform: translateY(-3px);
box-shadow: 0 5px 15px rgba(255, 154, 158, 0.4);
}
#imageInput {
display: none;
}
.buttons {
display: flex;
justify-content: center;
gap: 20px;
margin: 25px 0;
flex-wrap: wrap;
}
.art-button {
flex: 1;
min-width: 150px;
padding: 14px 25px;
border: none;
border-radius: 50px;
font-size: 1.1rem;
font-weight: 600;
color: white;
cursor: pointer;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.art-button::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
transition: left 0.5s;
}
.art-button:hover::before {
left: 100%;
}
.art-button:active {
transform: scale(0.97);
}
#pointillismBtn {
background: linear-gradient(to right, #ff7e5f, #feb47b);
}
#cubismBtn {
background: linear-gradient(to right, #a8edea, #fed6e3);
}
.canvas-container {
position: relative;
margin: 0 20px 30px;
border-radius: 15px;
overflow: hidden;
box-shadow: 0 10px 25px rgba(0,0,0,0.15);
}
canvas {
display: block;
width: 100%;
height: auto;
}
#downloadBtn {
display: block;
margin: 0 auto 30px;
padding: 12px 30px;
background: linear-gradient(to right, #6a11cb, #2575fc);
color: white;
border: none;
border-radius: 50px;
font-size: 1.1rem;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
display: none;
}
#downloadBtn:hover {
transform: translateY(-3px);
box-shadow: 0 5px 15px rgba(106, 17, 203, 0.4);
}
.status {
text-align: center;
padding: 15px;
font-size: 1rem;
color: #555;
min-height: 24px;
}
@media (max-width: 480px) {
h1 {
font-size: 1.8rem;
}
.buttons {
flex-direction: column;
}
.art-button {
min-width: 100%;
}
}
Estilo Artístico
Transforme suas imagens em obras de arte com pontilhismo e cubismo
Escolha uma imagem
Selecione uma imagem para começar
Pontilhismo
Cubismo
Baixar Imagem
document.addEventListener('DOMContentLoaded', () => {
const imageInput = document.getElementById('imageInput');
const pointillismBtn = document.getElementById('pointillismBtn');
const cubismBtn = document.getElementById('cubismBtn');
const downloadBtn = document.getElementById('downloadBtn');
const statusEl = document.getElementById('status');
const processedCanvas = document.getElementById('processedCanvas');
const ctx = processedCanvas.getContext('2d');
let originalImage = null;
let isProcessing = false;
// Processamento de imagem
function applyPointillism() {
if (!originalImage || isProcessing) return;
isProcessing = true;
statusEl.textContent = 'Aplicando efeito pontilhismo...';
// Redimensionar para performance mantendo proporção
const maxWidth = 800;
let width = originalImage.width;
let height = originalImage.height;
if (width > maxWidth) {
height = Math.round((height * maxWidth) / width);
width = maxWidth;
}
processedCanvas.width = width;
processedCanvas.height = height;
// Desenhar imagem original no canvas
ctx.clearRect(0, 0, width, height);
ctx.drawImage(originalImage, 0, 0, width, height);
const imageData = ctx.getImageData(0, 0, width, height);
const data = imageData.data;
// Efeito pontilhismo
const pointSize = 2.5;
const step = 4;
ctx.clearRect(0, 0, width, height);
ctx.fillStyle = 'rgba(0,0,0,0)'; // Fundo transparente
for (let y = 0; y < height; y += step) {
for (let x = 0; x < width; x += step) {
const i = (y * width + x) * 4;
const r = data[i];
const g = data[i+1];
const b = data[i+2];
ctx.fillStyle = `rgb(${r},${g},${b})`;
ctx.beginPath();
ctx.arc(x + pointSize/2, y + pointSize/2, pointSize/2, 0, Math.PI * 2);
ctx.fill();
}
}
statusEl.textContent = 'Efeito pontilhismo aplicado!';
downloadBtn.style.display = 'block';
isProcessing = false;
}
function applyCubism() {
if (!originalImage || isProcessing) return;
isProcessing = true;
statusEl.textContent = 'Aplicando efeito cubismo...';
// Redimensionar para performance mantendo proporção
const maxWidth = 800;
let width = originalImage.width;
let height = originalImage.height;
if (width > maxWidth) {
height = Math.round((height * maxWidth) / width);
width = maxWidth;
}
processedCanvas.width = width;
processedCanvas.height = height;
// Desenhar imagem original no canvas
ctx.clearRect(0, 0, width, height);
ctx.drawImage(originalImage, 0, 0, width, height);
const imageData = ctx.getImageData(0, 0, width, height);
const data = imageData.data;
// Efeito cubismo (mosaico de cores médias)
const gridSize = 25;
const cols = Math.ceil(width / gridSize);
const rows = Math.ceil(height / gridSize);
ctx.clearRect(0, 0, width, height);
for (let row = 0; row < rows; row++) {
for (let col = 0; col < cols; col++) {
const xStart = col * gridSize;
const yStart = row * gridSize;
const xEnd = Math.min(xStart + gridSize, width);
const yEnd = Math.min(yStart + gridSize, height);
let r = 0, g = 0, b = 0, count = 0;
for (let y = yStart; y < yEnd; y++) {
for (let x = xStart; x < xEnd; x++) {
const i = (y * width + x) * 4;
r += data[i];
g += data[i+1];
b += data[i+2];
count++;
}
}
const avgR = Math.round(r / count);
const avgG = Math.round(g / count);
const avgB = Math.round(b / count);
ctx.fillStyle = `rgb(${avgR},${avgG},${avgB})`;
ctx.fillRect(xStart, yStart, xEnd - xStart, yEnd - yStart);
}
}
statusEl.textContent = 'Efeito cubismo aplicado!';
downloadBtn.style.display = 'block';
isProcessing = false;
}
// Download da imagem processada
downloadBtn.addEventListener('click', () => {
processedCanvas.toBlob(blob => {
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'estilo-artistico.png';
a.click();
URL.revokeObjectURL(url);
});
});
// Upload de imagem
imageInput.addEventListener('change', e => {
const file = e.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = event => {
const img = new Image();
img.onload = () => {
originalImage = img;
pointillismBtn.disabled = false;
cubismBtn.disabled = false;
statusEl.textContent = 'Imagem carregada! Selecione um efeito artístico.';
downloadBtn.style.display = 'none';
processedCanvas.width = 0;
processedCanvas.height = 0;
};
img.src = event.target.result;
};
reader.readAsDataURL(file);
});
// Eventos dos botões
pointillismBtn.addEventListener('click', applyPointillism);
cubismBtn.addEventListener('click', applyCubism);
});