document.addEventListener('DOMContentLoaded', () => {
+ document.querySelectorAll('#search').forEach(p => {
+ let [input, button] = p.children;
+ button.onclick = e => {
+ if (input.value && input.offsetWidth > 50) {
+ return true; // bubble to submit
+ }
+ // make visible first
+ input.focus();
+ e.preventDefault();
+ return false;
+ };
+ });
+
document.querySelectorAll('.multiinput > input[id]').forEach(el => {
el.oninput = e => {
if (e.target.value == '') return;
let thumbpreview = document.getElementById('convertpreview');
if (thumbpreview && imgpreview) {
thumbpreview.onclick = e => {
+ thumbpreview.onclick = null; // setup once
const cropinput = document.getElementById('crop32');
- let border = { width: 600, height: 400 };
- let crop = new Croppie(thumbpreview, {
- boundary: { width: border.width * 1.3, height: border.height * 1.2 },
- viewport: border,
- update: e => {
- cropinput.value = e.points.map((pos, axis) => {
- Math.round(1000 * pos / (axis % 2 ? border.height : border.width))
- }).join(',');
- },
- });
- crop.bind({
- url: imgpreview.src,
- points: cropinput.value.split(/[^0-9]/).map((rel, axis) => {
- return rel * (axis % 2 ? border.height : border.width) / 1000
- }),
- });
- crop.elements.overlay.addEventListener('dblclick', e => {
- crop.destroy();
- });
+ const imgselect = thumbpreview.children[0];
+ const canvas = [thumbpreview.clientWidth, thumbpreview.clientHeight];
+ const border = [canvas[0], canvas[0] * imgpreview.height / imgpreview.width];
+ const minscale = Math.max(1, canvas[1] / border[1]); // 100% or fit width
+ let crop = cropinput.value.split(/[^0-9.]/).map(pos => pos / 1000);
+ let scale = 1 / (crop[2] - crop[0]) || minscale;
+ crop.push(0); // defined y dimension
+ crop.splice(2); // end coordinates applied to zoom
+ crop = crop.map((rel, axis) => rel * border[axis % 2] * scale);
+
+ let drag, pinch;
+ function applydrag(e) {
+ const touch = e.touches ? e.touches[0] : e;
+ let pos = [touch.pageX, touch.pageY];
+ if (e.type === 'touchmove' && e.touches.length > 1) {
+ // distance to second point
+ pos[0] -= e.touches[1].pageX;
+ pos[1] -= e.touches[1].pageY;
+ const span = Math.sqrt(pos[0]**2 + pos[1]**2);
+ if (pinch) {
+ cropzoom(.01 * (span - pinch));
+ }
+ pinch = span;
+ return;
+ }
+ if (drag) {
+ // apply drag delta to crop position
+ crop[0] += drag[0] - pos[0];
+ crop[1] += drag[1] - pos[1];
+ recrop();
+ }
+ drag = pos;
+ }
+
+ function recrop() {
+ [0, 1].forEach(axis => {
+ if (crop[axis] > border[axis] * scale - canvas[axis]) {
+ crop[axis] = border[axis] * scale - canvas[axis]; // max bound
+ }
+ if (crop[axis] < 0) {
+ crop[axis] = 0; // min bound
+ }
+ });
+ imgselect.style.left = -crop[0]+'px';
+ imgselect.style.top = -crop[1]+'px';
+ imgselect.style.width = (scale * 100)+'%';
+ cropinput.value = [
+ crop[0] / border[0],
+ crop[1] / border[1],
+ (crop[0] + canvas[0]) / border[0],
+ (crop[1] + canvas[1]) / border[1],
+ ].map(pos => Math.round(1000 * pos / scale));
+ }
+
+ function cropzoom(delta) {
+ if (scale + delta < minscale) {
+ delta = minscale - scale; // scale = 1
+ }
+ [0, 1].forEach(axis => {
+ // same area center at altered scale
+ crop[axis] += (crop[axis] + border[axis] / 2) / scale * delta;
+ });
+ scale += delta;
+ recrop();
+ }
+
+ imgselect.src = imgpreview.src;
+ imgselect.style.cursor = 'grab';
+ imgselect.style.position = 'absolute';
+ imgselect.style.maxWidth = 'none';
+ recrop();
+
+ imgselect.ontouchstart =
+ imgselect.onmousedown = e => {
+ e.preventDefault();
+ drag = pinch = false;
+ applydrag(e);
+ imgselect.style.cursor = 'grabbing';
+ window.ontouchmove =
+ window.onmousemove = e => {
+ e.preventDefault();
+ applydrag(e);
+ };
+ window.ontouchend =
+ window.onmouseup = e => {
+ e.preventDefault();
+ imgselect.style.cursor = 'grab';
+ window.ontouchmove = window.ontouchend =
+ window.onmousemove = window.onmouseup = null;
+ };
+ };
+
+ imgselect.onwheel = e => {
+ e.preventDefault();
+ let delta = (-e.deltaY || e.wheelDelta) * .001 * scale;
+ if (e.deltaMode == 1) { // DOM_DELTA_LINE
+ delta *= 18; // convert number of lines to pixels
+ }
+ cropzoom(delta);
+ };
};
}