Pular para o conteúdo principal

Editor de Fotos Responsivo - HTML, CSS e JavaScript - Tutorial



Editor de Fotos Responsivo:

Aprenda a criar um editor de fotos responsivo com este tutorial completo usando HTML, CSS e JavaScript.

Controles Gerais:

1 - Botão girar à Esquerda:

Funcionalidade: Gira a imagem 90 graus no sentido anti-horário.

2 - Botão girar à Direita:

Funcionalidade: Gira a imagem 90 graus no sentido horário.

3 - Botão inverter Verticalmente:

Funcionalidade: Inverte a imagem no eixo vertical (espelhamento vertical).

4 - Botão limpar Filtros:

Funcionalidade: Restaura todos os filtros aplicados para os valores padrão.

5 - Botão selecionar Nova Imagem:

Funcionalidade: Abre o seletor de arquivos para carregar uma nova imagem.

6 - Botão salvar Imagem:

Funcionalidade: Salva a imagem editada como um arquivo PNG no dispositivo do usuário.

Botões de Filtros:

1 - Botão brilho:

Funcionalidade: Ajusta o brilho da imagem (de 0% a 200%).

2 - Botão contraste:

Funcionalidade: Ajusta o contraste da imagem (de 0% a 200%).

3 - Botão saturação:

Funcionalidade: Ajusta a saturação da imagem (de 0% a 200%).

4 - Botão sépia:

Funcionalidade: Aplica um filtro de sépia à imagem, dando um efeito de tonalidade envelhecida (de 0% a 200%).

5 - Botão desfoque:

Funcionalidade: Aplica um efeito de desfoque na imagem (de 0px a 10px).

6 - Botão negativo:

Funcionalidade: Inverte as cores da imagem, criando um efeito negativo (de 0% a 100%).

Veja o Editor de Fotos Responsivo em funcionamento neste link. Editor de Fotos Responsivo.

Veja o vídeo no YouTube:

Começando o Tutorial:

1° Passo: Abra seu VS Code, ou qualquer IDE da sua preferência e crie três pastas com os nomes... index.html, style.css e script.js.

Logo em seguida copie o código html abaixo e cole na pasta "index.html".



<!DOCTYPE html>
<html lang="pt-br">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Editor de Fotos Responsivo</title>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div class="editor-container">
    <div class="canvas-container">
      <canvas id="canvas"></canvas>
    </div>

    <div class="filter-control">
      <input id="slider" type="range" min="0" max="200" value="100">
    </div>

    <!-- Controles Gerais -->
    <div class="controls">
      <button id="rotate-left" title="Girar à Esquerda">
        <i class="fas fa-undo"></i>
      </button>
      <button id="rotate-right" title="Girar à Direita">
        <i class="fas fa-redo"></i>
      </button>
      <button id="flip-vertical" title="Inverter Verticalmente">
        <i class="fas fa-arrows-alt-v"></i>
      </button>
      <button id="reset-filters" title="Limpar Filtros">
        <i class="fas fa-ban"></i>
      </button>
      <button id="select-image" title="Selecionar Nova Imagem">
        <i class="fas fa-image"></i>
      </button>
      <button id="save" class="save-btn" title="Salvar Imagem">
        <i class="fas fa-save"></i>
      </button>
      <input type="file" id="upload-image" style="display:none">
    </div>

    <!-- Botões de Filtros -->
    <div class="filter-buttons">
      <button id="brightness" class="filter-btn" title="Brilho">
        <i class="fas fa-sun"></i>
      </button>
      <button id="contrast" class="filter-btn" title="Contraste">
        <i class="fas fa-adjust"></i>
      </button>
      <button id="saturation" class="filter-btn" title="Saturação">
        <i class="fas fa-tint"></i>
      </button>
      <button id="sepia" class="filter-btn" title="Sépia">
        <i class="fas fa-fill-drip"></i>
      </button>
      <button id="blur" class="filter-btn" title="Desfoque">
        <i class="fas fa-low-vision"></i>
      </button>
      <button id="invert" class="filter-btn" title="Negativo">
        <i class="fas fa-exclamation-circle"></i>
      </button>
    </div>
  </div>
  <script src="script.js"></script>
</body>
</html>

2° Passo: Copie o código abaixo e cole na pasta "style.css".



/* Estilos gerais */
body {
  font-family: 'Arial', sans-serif;
  margin: 0;
  padding: 0;
  background-color: #f4f4f4;
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  color: #333;
}

.editor-container {
  background-color: #fff;
  padding: 20px;
  border-radius: 10px;
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
  max-width: 500px;
  width: 100%;
  margin: 20px;
}

.canvas-container {
  display: flex;
  justify-content: center;
  margin-bottom: 20px;
}

/* Canvas */
canvas {
  width: 100%;
  max-width: 100%;
  border: 1px solid #ddd;
  border-radius: 10px;
}

/* Controles */
.controls {
  display: flex;
  justify-content: space-around;
  margin-bottom: 20px;
}

.controls button {
  margin: 5px;
  width: 50px;
  height: 50px;
  border: none;
  border-radius: 50%;
  background-color: #6c757d;
  color: white;
  font-size: 20px;
  cursor: pointer;
  transition: background-color 0.2s ease;
  display: flex;
  justify-content: center;
  align-items: center;
}

.controls button:hover {
  background-color: #008000;
}

/* Botões de Filtros */
.filter-buttons {
  display: flex;
  justify-content: space-around;
  margin-bottom: 20px;
}

.filter-buttons button {
  margin: 5px;
  width: 50px;
  height: 50px;
  border: none;
  border-radius: 50%;
  background-color: #6c757d;
  color: white;
  font-size: 20px;
  cursor: pointer;
  transition: background-color 0.2s ease;
  display: flex;
  justify-content: center;
  align-items: center;
}

.filter-buttons button:hover {
  background-color: #007bff;
}

/* Slider */
.filter-control {
  text-align: center;
  margin-bottom: 20px;
}

.filter-control input[type="range"] {
  width: 100%;
  max-width: 100%;
}

/* Responsividade */
@media (max-width: 768px) {
  .editor-container {
    padding: 15px;
    width: 100%;
  }

  .controls,
  .filter-buttons {
    flex-wrap: wrap;
  }

  .filter-control input[type="range"] {
    width: 100%;
  }
}

@media (max-width: 480px) {
  .controls button,
  .filter-buttons button {
    margin: 2px;
  }
}

        

3° Passo: Copie o código abaixo e cole na pasta "script.js".



const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const uploadImageInput = document.getElementById('upload-image');
const slider = document.getElementById('slider');
const filterButtons = document.querySelectorAll('.filter-buttons button');
const controls = document.querySelectorAll('.controls button');
const defaultImageUrl = 'https://raw.githubusercontent.com/Ninja1375/Editor-de-Fotos-Responsivo/main/Logo%20editor%20de%20imagens%20.png';

// Configurações padrão
let img = new Image();
let currentFilter = 'brightness'; // Filtro inicial
let filters = {
  brightness: 100,
  contrast: 100,
  saturation: 100,
  sepia: 0,
  blur: 0,
  invert: 0,  // Para o efeito negativo
};

// Carregar imagem padrão ao iniciar
img.src = defaultImageUrl;
img.onload = function () {
  canvas.width = img.width;
  canvas.height = img.height;
  ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
  applyFilters();
};

// Função para aplicar filtros
function applyFilters() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.filter = `
    brightness(${filters.brightness}%)
    contrast(${filters.contrast}%)
    saturate(${filters.saturation}%)
    sepia(${filters.sepia}%)
    blur(${filters.blur}px)
    invert(${filters.invert}%)
  `;
  ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
}

// Selecionar nova imagem
document.getElementById('select-image').addEventListener('click', () => {
  uploadImageInput.click();
});

uploadImageInput.addEventListener('change', (e) => {
  const file = e.target.files[0];
  if (file) {
    const reader = new FileReader();
    reader.onload = function (event) {
      img.src = event.target.result;
    };
    reader.readAsDataURL(file);
  }
});

img.onload = function () {
  canvas.width = img.width;
  canvas.height = img.height;
  applyFilters();
};

// Função para atualizar o filtro
filterButtons.forEach(button => {
  button.addEventListener('click', function () {
    // Desativar todos os botões
    filterButtons.forEach(btn => btn.classList.remove('active'));
    // Ativar o botão clicado
    this.classList.add('active');

    currentFilter = this.id;
    slider.value = filters[currentFilter];

    // Verificar o máximo e mínimo conforme o filtro
    if (currentFilter === 'blur') {
      slider.max = 10;
      slider.min = 0;
    } else if (currentFilter === 'invert') {
      slider.max = 100;
      slider.min = 0;
    } else {
      slider.max = 200;
      slider.min = 0;
    }

    // Garantir que o botão fique azul instantaneamente
    applyFilters();
  });
});

// Atualizar o valor do filtro com o slider
slider.addEventListener('input', function () {
  filters[currentFilter] = this.value;
  applyFilters();
});

// Rotação e Inversão da Imagem
document.getElementById('rotate-left').addEventListener('click', () => {
  rotateImage(-90);
});

document.getElementById('rotate-right').addEventListener('click', () => {
  rotateImage(90);
});

document.getElementById('flip-vertical').addEventListener('click', () => {
  flipImage();
});

// Limpar Filtros
document.getElementById('reset-filters').addEventListener('click', () => {
  // Restaurar os valores dos filtros
  filters = {
    brightness: 100,
    contrast: 100,
    saturation: 100,
    sepia: 0,
    blur: 0,
    invert: 0,
  };
  applyFilters();
  slider.value = 100; // Resetar o slider para 100%

  // Desativar todos os botões de filtro
  filterButtons.forEach(btn => btn.classList.remove('active'));
});

// Funções de rotação e inversão
function rotateImage(degrees) {
  const tempCanvas = document.createElement('canvas');
  const tempCtx = tempCanvas.getContext('2d');

  tempCanvas.width = canvas.height;
  tempCanvas.height = canvas.width;

  tempCtx.translate(tempCanvas.width / 2, tempCanvas.height / 2);
  tempCtx.rotate((degrees * Math.PI) / 180);
  tempCtx.drawImage(canvas, -canvas.width / 2, -canvas.height / 2);

  canvas.width = tempCanvas.width;
  canvas.height = tempCanvas.height;
  ctx.drawImage(tempCanvas, 0, 0);
  applyFilters();
}

function flipImage() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.translate(0, canvas.height);
  ctx.scale(1, -1);
  ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
  applyFilters();
}

// Salvar a imagem editada
document.getElementById('save').addEventListener('click', () => {
  const link = document.createElement('a');
  link.download = 'imagem-editada.png';
  link.href = canvas.toDataURL();
  link.click();
});

        

4° Passo: Testar o Projeto!

Agora, com os três arquivos (index.html, style.css, e script.js) criados, você pode abrir o index.html no seu navegador e ver seu projeto funcionando perfeitamente!

Se preferir os códigos estão no meu Repositório no GitHub.

Resultado vai ser igual o da imagem abaixo:

As postagens do nosso blog te ajudaram?

Nos ajude a manter o blog no ar!

Faça uma doação para manter o blog funcionando!

60% das doações são no valor de R$ 7,00

Antônio José do Carmo Nascimento

Comentários

Mais vistas

Autocode - Significado e Funcionalidade

O Que é Autocode? O Autocode foi uma das primeiras linguagens de programação de computador, desenvolvida em 1952 por Alick Glennie para o computador Mark 1 na Universidade

HTML - Significado e Funcionalidade

O que é HTML? HTML é a sigla em inglês para Hypertext Markup Language, que traduzimos para o português como linguagem de marcação de hipertexto. O HTML é parte fundamental das

Semáforo - HTML, CSS e JavaScript - Tutorial

Semáforo Funcional: Aprenda a criar um semáforo funcional com este tutorial detalhado. Descubra como implementar a lógica de controle de um semáforo usando HTML, CSS e JavaScript.