Skip to content

Instantly share code, notes, and snippets.

@dantetesta
Created September 23, 2024 13:22
Show Gist options
  • Save dantetesta/04771f24df209a808a5fb3220cc3bb18 to your computer and use it in GitHub Desktop.
Save dantetesta/04771f24df209a808a5fb3220cc3bb18 to your computer and use it in GitHub Desktop.
Cropper Bom
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Editar Foto de Perfil</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/cropper/4.1.0/cropper.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
<style>
body {
font-family: 'Arial', sans-serif;
margin: 0;
padding: 0;
background-color: #f0f2f5;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
.profile-container {
background-color: white;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
padding: 20px;
text-align: center;
max-width: 400px;
width: 90%;
}
.avatar-container {
position: relative;
width: 150px;
height: 150px;
margin: 0 auto 20px;
}
.avatar {
width: 100%;
height: 100%;
border-radius: 50%;
object-fit: cover;
border: 3px solid #fff;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.edit-button {
position: absolute;
bottom: 0;
right: 0;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 50%;
width: 40px;
height: 40px;
font-size: 18px;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
transition: background-color 0.3s;
}
.edit-button:hover {
background-color: #45a049;
}
.modal {
display: none;
position: fixed;
z-index: 1000;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.5);
}
.modal-content {
background-color: #fefefe;
margin: 5% auto;
padding: 20px;
border-radius: 8px;
max-width: 600px;
width: 90%;
}
.close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
cursor: pointer;
}
.close:hover {
color: #000;
}
#image-container {
max-width: 100%;
max-height: 300px;
margin: 20px 0;
}
#actions, #extra-controls {
margin-top: 20px;
}
.btn {
padding: 10px 20px;
margin: 5px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
transition: background-color 0.3s;
}
.btn-primary {
background-color: #4CAF50;
color: white;
}
.btn-primary:hover {
background-color: #45a049;
}
.btn-secondary {
background-color: #f1f1f1;
color: #333;
}
.btn-secondary:hover {
background-color: #ddd;
}
.control-group {
margin-bottom: 10px;
}
.control-group button {
margin-right: 5px;
}
@media (max-width: 768px) {
.modal-content {
margin: 10% auto;
width: 95%;
}
}
</style>
</head>
<body>
<div class="profile-container">
<div class="avatar-container">
<img src="https://via.placeholder.com/150" alt="Avatar" class="avatar" id="profile-avatar">
<button class="edit-button" id="edit-avatar-btn">
<i class="fas fa-pencil-alt"></i>
</button>
</div>
<h2>Nome do Usuário</h2>
</div>
<div id="avatar-modal" class="modal">
<div class="modal-content">
<span class="close">&times;</span>
<h2>Editar Foto de Perfil</h2>
<input type="file" id="file-input" accept="image/*" style="display: none;">
<button class="btn btn-secondary" id="upload-btn">Escolher Imagem</button>
<div id="image-container"></div>
<div id="extra-controls" style="display: none;">
<div class="control-group">
<button class="btn btn-secondary" id="zoom-in"><i class="fas fa-search-plus"></i> Zoom In</button>
<button class="btn btn-secondary" id="zoom-out"><i class="fas fa-search-minus"></i> Zoom Out</button>
</div>
<div class="control-group">
<button class="btn btn-secondary" id="flip-horizontal"><i class="fas fa-arrows-alt-h"></i> Flip H</button>
<button class="btn btn-secondary" id="flip-vertical"><i class="fas fa-arrows-alt-v"></i> Flip V</button>
</div>
<div class="control-group">
<button class="btn btn-secondary" id="rotate-left"><i class="fas fa-undo"></i> Rotate -15°</button>
<button class="btn btn-secondary" id="rotate-right"><i class="fas fa-redo"></i> Rotate +15°</button>
</div>
<div id="actions" style="display: none;">
<button class="btn btn-secondary aspect-ratio-button" data-ratio="1:1">1:1</button>
<button class="btn btn-secondary aspect-ratio-button" data-ratio="1:2">1:2</button>
<button class="btn btn-secondary aspect-ratio-button" data-ratio="2:1">2:1</button>
<button class="btn btn-primary" id="crop-button">Salvar</button>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.12/cropper.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
var modal = document.getElementById('avatar-modal');
var editBtn = document.getElementById('edit-avatar-btn');
var closeBtn = document.getElementsByClassName('close')[0];
var fileInput = document.getElementById('file-input');
var uploadBtn = document.getElementById('upload-btn');
var imageContainer = document.getElementById('image-container');
var actions = document.getElementById('actions');
var extraControls = document.getElementById('extra-controls');
var cropButton = document.getElementById('crop-button');
var aspectRatioButtons = document.querySelectorAll('.aspect-ratio-button');
var profileAvatar = document.getElementById('profile-avatar');
var cropper;
editBtn.onclick = function() {
modal.style.display = "block";
}
closeBtn.onclick = function() {
modal.style.display = "none";
}
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
uploadBtn.onclick = function() {
fileInput.click();
}
fileInput.addEventListener('change', function (e) {
var file = e.target.files[0];
var reader = new FileReader();
reader.onload = function (e) {
if (cropper) {
cropper.destroy();
}
var img = document.createElement('img');
img.id = 'image';
img.src = e.target.result;
imageContainer.innerHTML = '';
imageContainer.appendChild(img);
cropper = new Cropper(img, {
aspectRatio: 1,
viewMode: 1,
});
actions.style.display = 'block';
extraControls.style.display = 'block';
};
reader.readAsDataURL(file);
});
aspectRatioButtons.forEach(function(button) {
button.addEventListener('click', function() {
var ratio = this.getAttribute('data-ratio').split(':');
var aspectRatio = parseInt(ratio[0]) / parseInt(ratio[1]);
cropper.setAspectRatio(aspectRatio);
});
});
document.getElementById('zoom-in').addEventListener('click', function() {
cropper.zoom(0.1);
});
document.getElementById('zoom-out').addEventListener('click', function() {
cropper.zoom(-0.1);
});
document.getElementById('flip-horizontal').addEventListener('click', function() {
cropper.scaleX(-cropper.getData().scaleX || -1);
});
document.getElementById('flip-vertical').addEventListener('click', function() {
cropper.scaleY(-cropper.getData().scaleY || -1);
});
document.getElementById('rotate-left').addEventListener('click', function() {
cropper.rotate(-15);
});
document.getElementById('rotate-right').addEventListener('click', function() {
cropper.rotate(15);
});
cropButton.addEventListener('click', function () {
var croppedCanvas = cropper.getCroppedCanvas();
profileAvatar.src = croppedCanvas.toDataURL('image/jpeg');
modal.style.display = "none";
});
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment