Skip to content

Instantly share code, notes, and snippets.

@FerraBraiZ
Last active March 10, 2024 14:11
Show Gist options
  • Save FerraBraiZ/d77a750174a0cd1c84a53843319cf380 to your computer and use it in GitHub Desktop.
Save FerraBraiZ/d77a750174a0cd1c84a53843319cf380 to your computer and use it in GitHub Desktop.
POC - Jquery pinch-to-zoom-picture
<!doctype html>
<html lang="pt-br">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ config('app.name', '') }}</title>
<!-- Styles -->
@if ( (app()->environment()) ==='production' )
<link href="{{ secure_asset('css/3rd-party/bootstrap.min-v5.3.2.css').'?v='.\time() }}" rel="stylesheet">
@else
<link href="{{ e(asset('css/3rd-party/bootstrap.min-v5.3.2.css')).'?v='.\time() }}" rel="stylesheet">
@endif
<style>
#viewport {
cursor: grab;
display: flex;
align-items: center;
justify-content: center;
}
#photo-container img {
width: auto;
height: auto;
margin: auto;
}
#photo-container div {
position: absolute;
}
button {
width: 140px;
}
#photo-container {
transition: transform 0.25s ease 0s;
transform: translate(0px, 0px) scale(0.0907738);
}
#fileInput {
display: none;
}
#zoom-controls {
display: none !important;
}
#modal-controls{
display:flex !important;
justify-content: space-around !important;
align-items: center !important;
margin-top:20px;
margin-bottom:20px;
}
</style>
</head>
<body>
<div class="container">
<form>
<input type="file" accept="image/*" capture="camera" id="fileInput" name="fileInput">
</form>
<h5>Adicionar Fotos</h5>
<br>
<div class="ratio ratio-4x3 rounded bg-secondary overflow-hidden">
<div id="viewport" style="cursor: grab;">
<div id="photo-container">
<img id="preview" src="" alt="image">
</div>
</div>
</div>
<div id="zoom-controls" class="d-flex justify-content-between my-3">
<button data-zoom-down="" class="btn btn-info">Zoom Down</button>
<input data-zoom-range="" type="range" class="flex-fill mx-3" value="0" max="25">
<button data-zoom-up="" class="btn btn-info ml-auto">Zoom Up</button>
</div>
<div id="modal-controls" class="">
<div>
<button type="button" class="btn btn-danger">Fechar</button>
</div>
<div>
<button type="button" class="btn btn-success">Enviar</button>
</div>
<div>
<svg xmlns="http://www.w3.org/2000/svg" id="camera" style="cursor: pointer;" width="64" height="64"
viewBox="0 0 512 512">
<path d="M417.5 160h-61.7c-32.1-36-42.2-48-54.5-48h-88.5c-12.3 0-22.2 12-54.5
48H145v-16h-34v16H97.5C79.9 160 64 173.2 64 190.7v176c0 17.5 15.9 33.3 33.5
33.3h320c17.6 0 30.5-15.8 30.5-33.3v-176c0-17.5-12.9-30.7-30.5-30.7zM256 360.5c-47.1
0-85.5-38.4-85.5-85.5s38.4-85.5 85.5-85.5 85.5 38.4 85.5 85.5-38.4 85.5-85.5 85.5zM369
209h-17v-17h17v17z"></path>
<path d="M256 205.5c-38.4 0-69.5 31.1-69.5 69.5s31.1 69.5 69.5 69.5 69.5-31.1
69.5-69.5-31.1-69.5-69.5-69.5zm0 101.5c-17.7 0-32-14.3-32-32s14.3-32 32-32 32
14.3 32 32-14.3 32-32 32z"></path>
</svg>
</div>
</div>
</div>
@if ( (app()->environment()) ==='production' )
<script src="{{ secure_asset('js/3rd-party/jquery.min-v3.4.1.js').'?v='.\time() }}"></script>
<script src="{{ secure_asset('js/3rd-party/bootstrap-min-5.3.2.js').'?v='.\time() }}"></script>
<script src="{{ secure_asset('js/3rd-party/sweetalert2.all.min-v9.5.4.js').'?v='.\time() }}"></script>
<script src="{{ secure_asset('js/3rd-party/wheel-zoom.min.js').'?v='.\time() }}"></script>
@else
<script src="{{ e(asset('js/3rd-party/jquery.min-v3.4.1.js')).'?v='.\time() }}"></script>
<script src="{{ e(asset('js/3rd-party/bootstrap-min-5.3.2.js')).'?v='.\time() }}"></script>
<script src="{{ e(asset('js/3rd-party/sweetalert2.all.min-v9.5.4.js')).'?v='.\time() }}"></script>
<script src="{{ e(asset('js/3rd-party/wheel-zoom.min.js')).'?v='.\time() }}"></script>
@endif
<script type="application/javascript">
$(document).ready(() => {
const imageElement = document.getElementById('photo-container').querySelector('img');
function init() {
const rangeElement = document.querySelector('[data-zoom-range]');
const wzoom = WZoom.create('#photo-container', {
type: 'html',
width: imageElement.naturalWidth,
height: imageElement.naturalHeight,
onGrab: function () {
document.getElementById('viewport').style.cursor = 'grabbing';
},
onDrop: function () {
document.getElementById('viewport').style.cursor = 'grab';
},
prepare: function (instance) {
rangeElement.defaultValue = 0;
rangeElement.max = Math.round(Math.log(instance.content.maxScale / instance.content.minScale) / Math.log(instance.options.speed));
},
rescale: function (instance) {
rangeElement.value = Math.round(Math.log(instance.content.currentScale / instance.content.minScale) / Math.log(instance.options.speed));
}
});
document.querySelector('[data-zoom-up]').addEventListener('click', function () {
wzoom.zoomUp();
});
document.querySelector('[data-zoom-down]').addEventListener('click', function () {
wzoom.zoomDown();
});
window.addEventListener('resize', function () {
wzoom.prepare();
});
rangeElement.addEventListener('input', function () {
const newZoom = Number(rangeElement.value);
if (newZoom === 0) {
wzoom.maxZoomDown();
} else if (newZoom === rangeElement.max) {
wzoom.maxZoomUp();
} else {
let oldZoom = Math.round(Math.log(wzoom.content.currentScale / wzoom.content.minScale) / Math.log(wzoom.options.speed));
if (newZoom > oldZoom) {
wzoom.zoomUp();
} else {
wzoom.zoomDown();
}
}
});
}
//addFileHandler
(() => {
const svg_camera = $('#camera');
const fileInput = $('#fileInput');
const preview = $('#preview');
svg_camera.on('click', () => {
$('#fileInput').click();
});
// Handle file selection
fileInput.on('change', (event) => {
// Check if a file was selected
if (event.target.files && event.target.files[0]) {
const reader = new FileReader();
reader.onload = (e) => {
// Set the preview image source
preview.attr('src', e.target.result);
if (imageElement.complete) {
init();
} else {
imageElement.onload = init;
}
};
// Read the selected file as a data URL
reader.readAsDataURL(event.target.files[0]);
preview.show();
svg_camera.hide();
}
});
})();
$('.btn-delete-customer').on('click', (evt) => {
evt.preventDefault();
evt.stopImmediatePropagation();
let form = $(evt.target).parent();
swal.fire({
title: '<strong>Atenção!</strong>',
icon: 'warning',
html: 'Deseja realmente deletar este cliente? <br> Essa ação não poderá ser desfeita',
showCloseButton: true,
showCancelButton: true,
focusConfirm: false,
confirmButtonText: 'Deletar',
cancelButtonText: 'Cancelar',
confirmButtonColor: '#d33',
cancelButtonColor: '#3085d6',
}).then(
(result) => {
if (result.value) {
form.submit();
}
});
});
$('.btn-add-new-attendance').on('click', (evt) => {
evt.preventDefault();
evt.stopImmediatePropagation();
let customer_id = $(evt.target).data('customer-id');
let modal = $('.modal-add-photo-to-attendance');
modal.show();
console.log(customer_id);
})
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment