fix: perspektif crop

This commit is contained in:
2026-01-18 21:30:10 +08:00
parent 1cd7db0fcc
commit 3935519d02
6 changed files with 388 additions and 320 deletions

View File

@@ -19,30 +19,7 @@
</div>
</div>
<!-- Modal Crop -->
<div class="modal fade" id="modalCrop" tabindex="-1" role="dialog" aria-labelledby="modalCropLabel" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modalCropLabel">Potong & Putar Foto</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div class="img-container" style="max-height: 500px;">
<img id="image-to-crop" src="" style="max-width: 100%; display: block;">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" id="btnRotateLeft" title="Putar Kiri"><i class="fas fa-undo"></i></button>
<button type="button" class="btn btn-secondary" id="btnRotateRight" title="Putar Kanan"><i class="fas fa-redo"></i></button>
<button type="button" class="btn btn-secondary" data-dismiss="modal">Batal</button>
<button type="button" class="btn btn-primary" id="btnCrop">Potong & Simpan</button>
</div>
</div>
</div>
</div>
<?php include 'admin/scanner_modal.php'; ?>
<div class="form-group row">
<label class="col-sm-2 col-form-label">NIK</label>
@@ -164,72 +141,31 @@
<script>
window.addEventListener('load', function() {
// Cropper Logic
var cropper;
var image = document.getElementById('image-to-crop');
// Scanner Logic
var inputImage = document.getElementById('foto_ktp');
var modal = $('#modalCrop');
var preview = document.getElementById('preview_ktp');
var hiddenInput = document.getElementById('foto_cropped');
// Defines callback for scanner modal
window.handleScannerResult = function(base64) {
// Show Preview
preview.src = base64;
preview.style.display = 'block';
// Set Hidden Input
hiddenInput.value = base64;
};
inputImage.addEventListener('change', function(e) {
var files = e.target.files;
var done = function(url) {
inputImage.value = ''; // Clear input to avoid double submit issues if cancelled
image.src = url;
modal.modal('show');
};
var reader;
var file;
var url;
if (files && files.length > 0) {
file = files[0];
if (URL) {
done(URL.createObjectURL(file));
} else if (FileReader) {
reader = new FileReader();
reader.onload = function(e) {
done(reader.result);
};
reader.readAsDataURL(file);
// Open Smart Scanner
if (window.openScanner) {
window.openScanner(files[0]);
} else {
alert("Scanner library not loaded!");
}
}
});
modal.on('shown.bs.modal', function() {
cropper = new Cropper(image, {
aspectRatio: 1.58, // KTP Ratio
viewMode: 1,
autoCropArea: 1,
});
}).on('hidden.bs.modal', function() {
cropper.destroy();
cropper = null;
});
document.getElementById('btnRotateLeft').addEventListener('click', function() {
cropper.rotate(-90);
});
document.getElementById('btnRotateRight').addEventListener('click', function() {
cropper.rotate(90);
});
document.getElementById('btnCrop').addEventListener('click', function() {
var canvas;
if (cropper) {
canvas = cropper.getCroppedCanvas({
width: 1000,
});
var base64 = canvas.toDataURL('image/jpeg');
// Show Preview
var output = document.getElementById('preview_ktp');
output.src = base64;
output.style.display = 'block';
// Set Hidden Input
document.getElementById('foto_cropped').value = base64;
modal.modal('hide');
// Clear input so same file can be selected again if needed
inputImage.value = '';
}
});

View File

@@ -41,30 +41,7 @@
</div>
</div>
<!-- Modal Crop -->
<div class="modal fade" id="modalCrop" tabindex="-1" role="dialog" aria-labelledby="modalCropLabel" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modalCropLabel">Potong & Putar Foto</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div class="img-container" style="max-height: 500px;">
<img id="image-to-crop" src="" style="max-width: 100%; display: block;">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" id="btnRotateLeft" title="Putar Kiri"><i class="fas fa-undo"></i></button>
<button type="button" class="btn btn-secondary" id="btnRotateRight" title="Putar Kanan"><i class="fas fa-redo"></i></button>
<button type="button" class="btn btn-secondary" data-dismiss="modal">Batal</button>
<button type="button" class="btn btn-primary" id="btnCrop">Potong & Simpan</button>
</div>
</div>
</div>
</div>
<?php include 'admin/scanner_modal.php'; ?>
<div class="form-group row">
<label class="col-sm-2 col-form-label">NIK</label>
@@ -215,66 +192,23 @@
<script>
// Preview Image
window.addEventListener('load', function() {
// Cropper Logic
var cropper;
var image = document.getElementById('image-to-crop');
// Scanner Logic
var inputImage = document.getElementById('foto_ktp');
var modal = $('#modalCrop');
var preview = document.getElementById('preview_ktp');
var hiddenInput = document.getElementById('foto_cropped');
window.handleScannerResult = function(base64) {
preview.src = base64;
hiddenInput.value = base64;
};
inputImage.addEventListener('change', function(e) {
var files = e.target.files;
var done = function(url) {
inputImage.value = ''; // Clear
image.src = url;
modal.modal('show');
};
var reader;
var file;
var url;
if (files && files.length > 0) {
file = files[0];
if (URL) {
done(URL.createObjectURL(file));
} else if (FileReader) {
reader = new FileReader();
reader.onload = function(e) {
done(reader.result);
};
reader.readAsDataURL(file);
if (window.openScanner) {
window.openScanner(files[0]);
}
}
});
modal.on('shown.bs.modal', function() {
cropper = new Cropper(image, {
aspectRatio: 1.58,
viewMode: 1,
autoCropArea: 1,
});
}).on('hidden.bs.modal', function() {
cropper.destroy();
cropper = null;
});
document.getElementById('btnRotateLeft').addEventListener('click', function() {
cropper.rotate(-90);
});
document.getElementById('btnRotateRight').addEventListener('click', function() {
cropper.rotate(90);
});
document.getElementById('btnCrop').addEventListener('click', function() {
var canvas;
if (cropper) {
canvas = cropper.getCroppedCanvas({ width: 1000 });
var base64 = canvas.toDataURL('image/jpeg');
var output = document.getElementById('preview_ktp');
output.src = base64;
document.getElementById('foto_cropped').value = base64;
modal.modal('hide');
inputImage.value = '';
}
});