Introdução
Este projeto irá guiá-lo através do processo de criação de uma ferramenta simples de corte de imagens. No final, você terá uma aplicação interativa que permite aos usuários carregar, exibir e cortar imagens.
👀 Pré-visualização

🎯 Tarefas
Neste projeto, você aprenderá:
- Como criar a estrutura HTML para a ferramenta de corte de imagem
- Como estilizar a página web usando CSS para torná-la visualmente atraente
- Como inicializar variáveis e event listeners (ouvintes de eventos) usando JavaScript para lidar com as interações do usuário
- Como lidar com o carregamento e exibição de imagens usando a API FileReader em JavaScript
- Como implementar o mecanismo de corte usando a API Canvas em JavaScript
- Como salvar a imagem cortada e exibir o resultado
🏆 Conquistas
Após concluir este projeto, você será capaz de:
- Compreender as tags (etiquetas) e a estrutura HTML
- Aplicar propriedades e seletores CSS de forma eficaz
- Utilizar a sintaxe JavaScript, variáveis e event listeners
- Aproveitar a API FileReader em JavaScript para lidar com uploads (carregamentos) de arquivos
- Implementar a manipulação de imagens usando a API Canvas em JavaScript
Definir a Estrutura HTML
Requisitos:
- Conhecimento de tags (etiquetas) e estrutura HTML.
Funcionalidade:
- Projetar uma interface para permitir que os usuários carreguem uma imagem e acionem o processo de corte.
Incorpore o código HTML em seu index.html.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>HTML5 Crop Image</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<input type="file" name="file" id="post_file" />
<button id="save_button">SAVE</button>
<div id="label">
<canvas id="get_image"></canvas>
<p>
<canvas id="cover_box"></canvas>
<canvas id="edit_pic"></canvas>
</p>
</div>
<p>
<span id="show_edit"></span>
<span id="show_pic"><img src="" /></span>
</p>
<script type="text/javascript" src="main.js"></script>
</body>
</html>
As três tags <canvas> mencionadas acima são usadas para processar conteúdo relacionado a imagens. O tratamento detalhado será fornecido no código js (JavaScript) subsequente. Os elementos com o id show_edit e o id show_pic são para visualizar a imagem e ver o resultado final da geração da imagem.
Estilizar a Página Web
Requisitos:
- Familiaridade com propriedades e seletores CSS.
Funcionalidade:
- Estilizar os elementos HTML para tornar a interface amigável e visualmente atraente.
Incorpore o CSS em seu style.css.
body {
background-color: #f6f6f6;
margin: 0;
padding: 20px;
text-align: center;
}
#label {
border: 1px solid #ccc;
background-color: #fff;
text-align: center;
height: 300px;
width: 300px;
margin: 20px auto;
position: relative;
}
#get_image {
position: absolute;
}
#edit_pic {
position: absolute;
display: none;
background: #000;
}
#cover_box {
position: absolute;
z-index: 9999;
display: none;
top: 0px;
left: 0px;
}
#show_edit {
margin: 0 auto;
display: inline-block;
}
#show_pic {
height: 100px;
width: 100px;
border: 2px solid #000;
overflow: hidden;
margin: 0 auto;
display: inline-block;
}
canvas {
position: absolute;
top: 0;
left: 0;
}
#save_button {
padding: 8px 16px;
background-color: #3498db;
color: #fff;
border: none;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.2s;
}
#save_button:hover {
background-color: #2980b9;
}
input[type="file"] {
margin-bottom: 20px;
}
Inicializar Variáveis e Event Listeners
Requisitos:
- Compreensão fundamental da sintaxe JavaScript, variáveis e event listeners (ouvintes de eventos).
Funcionalidade:
- Inicializar propriedades e configurações para a ferramenta de corte. Adicionar um event listener (ouvinte de evento) para processar a imagem carregada.
Em main.js, escreva o código para inicializar as propriedades da ferramenta de corte e configurar os event listeners (ouvintes de eventos).
var postFile = {
init: function () {
var t = this;
t.regional = document.getElementById("label");
t.getImage = document.getElementById("get_image");
t.editPic = document.getElementById("edit_pic");
t.editBox = document.getElementById("cover_box");
t.px = 0; //background image x
t.py = 0; //background image y
t.sx = 15; //crop area x
t.sy = 15; //crop area y
t.sHeight = 150; //crop area height
t.sWidth = 150; //crop area width
document
.getElementById("post_file")
.addEventListener("change", t.handleFiles, false);
}
};
Todas as nossas funções e variáveis são encapsuladas dentro do objeto postFile. A função init mencionada acima define principalmente alguns valores iniciais.
t.px = 0;
t.py = 0;
t.sx = 15;
t.sy = 15;
t.sHeight = 100;
t.sWidth = 100;
As variáveis t.px e t.py representam as coordenadas da imagem de fundo na área de visualização em tempo real; t.sx, t.sy, t.sHeight e t.sWidth representam as coordenadas x, y e a largura e altura da imagem, respectivamente.
Também obtemos vários elementos que operaremos mais tarde através de document.getElementById.
document
.getElementById("post_file")
.addEventListener("change", t.handleFiles, false);
Estamos ouvindo o evento change do formulário input com o id post_file para processar os arquivos carregados pelo usuário. Aqui, delegamos isso à função handleFiles. Então, em seguida, implementaremos a função handleFiles.
Gerenciar Upload e Exibição de Imagens
Requisitos:
- Conhecimento básico da API FileReader em JavaScript.
Funcionalidade:
- Garantir que, quando os usuários carregam uma imagem, ela seja processada, lida e exibida corretamente na tela.
Expanda seu main.js com as funções para processar e exibir a imagem carregada.
Para implementar a função
handleFilesAqui, estamos usando a API File do HTML5. Primeiro, invocando
new FileReader(), instanciamos um objeto FileReader chamadooFReader. Em seguida, chamamos seu métodoreadAsDataURL()para ler o conteúdo do arquivo e convertê-lo em um formato codificado em base64.Finalmente, quando o arquivo é totalmente lido e carregado, processamos a imagem que lemos usando
postFile.paintImage(oFREvent.target.result). Em termos simples, estamos redesenhando os dados da imagem que lemos no navegador.
handleFiles: function () {
var fileList = this.files[0];
var oFReader = new FileReader();
oFReader.readAsDataURL(fileList);
oFReader.onload = function (oFREvent) {
postFile.paintImage(oFREvent.target.result);
};
},
Para implementar a função
paintImageA etapa mais crucial aqui é desenhar a imagem de acordo com o tamanho do contêiner usando canvas. Na etapa anterior, usando o FileReader da API File, já obtivemos a URL da imagem que queremos carregar (o valor de
oFREvent.target.result). A próxima etapa é usar canvas para desenhar esta imagem. Primeiro, usamosgetImage.getContextpara obter o conteúdo 2d de<canvas id="get_image"></canvas>, que pode ser simplesmente entendido como o conteúdo da imagem. Depois disso, usamosnew Image()para criar um elemento<img>e definir seu valor de atributosrc.
paintImage: function (url) {
var t = this;
var createCanvas = t.getImage.getContext("2d");
var img = new Image();
img.src = url;
img.onload = function () {
if (
img.width < t.regional.offsetWidth &&
img.height < t.regional.offsetHeight
) {
t.imgWidth = img.width;
t.imgHeight = img.height;
} else {
var pWidth = img.width / (img.height / t.regional.offsetHeight);
var pHeight = img.height / (img.width / t.regional.offsetWidth);
t.imgWidth = img.width > img.height ? t.regional.offsetWidth : pWidth;
t.imgHeight =
img.height > img.width ? t.regional.offsetHeight : pHeight;
}
t.px = (t.regional.offsetWidth - t.imgWidth) / 2 + "px";
t.py = (t.regional.offsetHeight - t.imgHeight) / 2 + "px";
t.getImage.height = t.imgHeight;
t.getImage.width = t.imgWidth;
t.getImage.style.left = t.px;
t.getImage.style.top = t.py;
createCanvas.drawImage(img, 0, 0, t.imgWidth, t.imgHeight);
t.imgUrl = t.getImage.toDataURL();
t.cutImage();
t.drag();
};
},
Dentro da função img.onload, nosso objetivo principal é redesenhar a imagem em seu tamanho original, mantendo suas proporções, e é por isso que temos uma condição if. Em última análise, usamos a linha de código createCanvas.drawImage(img,0,0,t.imgWidth,t.imgHeight); para realmente renderizar a imagem.
Implementar o Mecanismo de Corte (Cropping)
Requisitos:
- Familiaridade com a API Canvas em JavaScript para desenho e manipulação de imagens.
Funcionalidade:
- Adicionar uma região de corte na imagem exibida e tornar essa região arrastável. Isso oferece aos usuários a flexibilidade de selecionar a área desejada para cortar.
Adicione os métodos relevantes em main.js.
Crie um método
cutImageO método
cutImageé principalmente responsável por duas tarefas: uma é criar uma camada de máscara, e a outra é usar a propriedade CSSbackgroundpara fornecer uma visualização em tempo real da área de corte selecionada.
cutImage: function () {
var t = this;
t.editBox.height = t.imgHeight;
t.editBox.width = t.imgWidth;
t.editBox.style.display = "block";
t.editBox.style.left = t.px;
t.editBox.style.top = t.py;
var cover = t.editBox.getContext("2d");
cover.fillStyle = "rgba(0, 0, 0, 0.5)";
cover.fillRect(0, 0, t.imgWidth, t.imgHeight);
cover.clearRect(t.sx, t.sy, t.sHeight, t.sWidth);
document.getElementById("show_edit").style.background =
"url(" + t.imgUrl + ")" + -t.sx + "px " + -t.sy + "px no-repeat";
document.getElementById("show_edit").style.height = t.sHeight + "px";
document.getElementById("show_edit").style.width = t.sWidth + "px";
},
- Crie um método
drag
drag: function () {
var t = this;
var draging = false;
var startX = 0;
var startY = 0;
document.getElementById("cover_box").onmousemove = function (e) {
var pageX = e.pageX - (t.regional.offsetLeft + this.offsetLeft);
var pageY = e.pageY - (t.regional.offsetTop + this.offsetTop);
if (
pageX > t.sx &&
pageX < t.sx + t.sWidth &&
pageY > t.sy &&
pageY < t.sy + t.sHeight
) {
this.style.cursor = "move";
this.onmousedown = function () {
draging = true;
t.ex = t.sx;
t.ey = t.sy;
startX = e.pageX - (t.regional.offsetLeft + this.offsetLeft);
startY = e.pageY - (t.regional.offsetTop + this.offsetTop);
};
window.onmouseup = function () {
draging = false;
};
if (draging) {
if (t.ex + (pageX - startX) < 0) {
t.sx = 0;
} else if (t.ex + (pageX - startX) + t.sWidth > t.imgWidth) {
t.sx = t.imgWidth - t.sWidth;
} else {
t.sx = t.ex + (pageX - startX);
}
if (t.ey + (pageY - startY) < 0) {
t.sy = 0;
} else if (t.ey + (pageY - startY) + t.sHeight > t.imgHeight) {
t.sy = t.imgHeight - t.sHeight;
} else {
t.sy = t.ey + (pageY - startY);
}
t.cutImage();
}
} else {
this.style.cursor = "auto";
}
};
},
Para entender este método, você precisa entender os seguintes pontos-chave:
var pageX = e.pageX - (t.regional.offsetLeft + this.offsetLeft);
var pageY = e.pageY - (t.regional.offsetTop + this.offsetTop);
Com as duas linhas de código acima, obtemos a distância entre o mouse e a imagem de fundo. e.pageX representa a distância do mouse para a borda esquerda do navegador, e t.regional.offsetLeft + this.offsetLeft calcula a distância da imagem para a borda esquerda do navegador. Da mesma forma, a distância superior pode ser deduzida.
if ( pageX > t.sx && pageX < t.sx + t.sWidth && pageY > t.sy && pageY < t.sy + t.sHeight )
Tendo entendido a distância entre o mouse e a imagem de fundo, isso deve ser fácil de entender: ele determina se o mouse está dentro da região da imagem.
t.ex = t.sx;
t.ey = t.sy;
startX = e.pageX - (t.regional.offsetLeft + this.offsetLeft);
startY = e.pageY - (t.regional.offsetTop + this.offsetTop);
Esses dois trechos de código valem a pena destacar. As duas primeiras linhas registram as coordenadas da última captura de tela (ou, se não houve uma anterior, então as coordenadas iniciais); as duas linhas seguintes registram as coordenadas quando o mouse é pressionado. Você pode inspecionar esses valores separadamente usando console.log().
if (draging) {
if (t.ex + (pageX - startX) < 0) {
t.sx = 0;
} else if (t.ex + (pageX - startX) + t.sWidth > t.imgWidth) {
t.sx = t.imgWidth - t.sWidth;
} else {
t.sx = t.ex + (pageX - startX);
}
if (t.ey + (pageY - startY) < 0) {
t.sy = 0;
} else if (t.ey + (pageY - startY) + t.sHeight > t.imgHeight) {
t.sy = t.imgHeight - t.sHeight;
} else {
t.sy = t.ey + (pageY - startY);
}
t.cutImage();
}
O código acima essencialmente diz: se estamos no meio do arrastar, precisamos atualizar os valores de t.sx e t.sy em tempo real com base nas mudanças de coordenadas e chamar o método cutImage para fornecer uma visualização ao vivo.
As coordenadas da área de corte durante o movimento = última posição registrada + (posição atual do mouse - posição quando o mouse foi pressionado)
Salvar a Imagem Cortada
Requisitos:
- Conhecimento de como usar canvas para extrair e exibir dados de imagem.
Funcionalidade:
- Após cortar a área desejada da imagem, permitir que os usuários salvem esta região cortada, exibindo o resultado na tela.
Melhore a função de inicialização em main.js para lidar com a salvamento da imagem cortada.
var postFile = {
init: function () {
// ...
document.getElementById("save_button").onclick = function () {
t.editPic.height = t.sHeight;
t.editPic.width = t.sWidth;
var ctx = t.editPic.getContext("2d");
var images = new Image();
images.src = t.imgUrl;
images.onload = function () {
ctx.drawImage(
images,
t.sx,
t.sy,
t.sHeight,
t.sWidth,
0,
0,
t.sHeight,
t.sWidth
);
document.getElementById("show_pic").getElementsByTagName("img")[0].src =
t.editPic.toDataURL();
};
};
}
};
postFile.init();
Semelhante à implementação do método paintImage, primeiro ouvimos o evento de clique no botão salvar. Em seguida, usamos o método drawImage para renderizar a região da imagem selecionada. Finalmente, empregamos o método toDataURL para converter a imagem em um formato codificado em base64. Este valor é então atribuído ao atributo src da img sob show_pic. Desta forma, o corte e salvamento da imagem são concluídos.
Testar a Ferramenta
- Abra
index.htmlem um navegador web.
- Carregue uma imagem e teste a funcionalidade de corte.
- O efeito da página é o seguinte:

Resumo
Parabéns! Você construiu uma ferramenta básica de corte de imagem usando HTML5 e JavaScript. Esta base pode ser utilizada para funcionalidades mais avançadas ou outras tarefas de manipulação de imagem. Pratique aprimorando a ferramenta ou explorando outros projetos de desenvolvimento web!



