init commit
commit
07a12b3ef2
|
@ -0,0 +1,5 @@
|
||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="WEB_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/image_anotate.iml" filepath="$PROJECT_DIR$/.idea/image_anotate.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -0,0 +1,6 @@
|
||||||
|
@charset "UTF-8";
|
||||||
|
|
||||||
|
main > .container {
|
||||||
|
padding: 70px 10px 0px 10px;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,449 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" class="h-100">
|
||||||
|
<head>
|
||||||
|
<!-- set the encoding of your site -->
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
|
||||||
|
<title>Edit thumbnail | Variance</title>
|
||||||
|
<meta name="description" content="A demo showcasing useful tech.">
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Bootstrap 5 style css-->
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
|
||||||
|
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
|
||||||
|
crossorigin="anonymous">
|
||||||
|
|
||||||
|
<!-- Bootstrap 5 icons font-->
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.9.1/font/bootstrap-icons.css">
|
||||||
|
|
||||||
|
<!-- Custom styles for this template -->
|
||||||
|
<link href="/css/style.css" rel="stylesheet">
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body class="d-flex flex-column h-100">
|
||||||
|
|
||||||
|
<header id="pageHeader" class="position-absolute w-100 bg-white">
|
||||||
|
<!-- Navbar -->
|
||||||
|
<!-- Fixed navbar -->
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main class="flex-shrink-0">
|
||||||
|
<!-- Start Main content -->
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div>
|
||||||
|
<ol class="breadcrumb small">
|
||||||
|
<li class="breadcrumb-item"><a href="/">Home</a></li>
|
||||||
|
<li class="breadcrumb-item"><a href="/bo/listuploads">List of uploads</a></li>
|
||||||
|
<li class="breadcrumb-item" aria-current="page">Thhumbnail selection test</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-4 justify-content-center">
|
||||||
|
<div class="col-md-8">
|
||||||
|
<img id="full-image" src="https://variance-fl-media.s3.eu-west-3.amazonaws.com/taupiboxed.jpg" class="card-img-top" alt="Pi and Tau: one each" style="position:relative">
|
||||||
|
<canvas id="canvas" style="position:absolute; left: 0px; top: 0px; overflow:auto;"></canvas>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4 mt-3 mt-md-0">
|
||||||
|
<h2>Thumbnail selection (test)</h2>
|
||||||
|
<p>This demo page shows how the thumbnail's squared interactive selection works.</p>
|
||||||
|
<p>The square "follows" the image even when the image size changes (resize the browser's window to see the outcomes).</p>
|
||||||
|
|
||||||
|
<p>The coordinates of the selection change dynamically.</p>
|
||||||
|
<div class="mb-1 row">
|
||||||
|
<label for="thb_left" class="col-sm-4 col-form-label">Left</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input class="form-control" type="text" id="thb_left" name="thb_left" value="0" readonly>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mb-1 row">
|
||||||
|
<label for="thb_top" class="col-sm-4 col-form-label">Top</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input class="form-control" type="text" id="thb_top" name="thb_top" value="0" readonly>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mb-1 row">
|
||||||
|
<label for="thb_right" class="col-sm-4 col-form-label">Right</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input class="form-control" type="text" id="thb_right" name="thb_right" value="0" readonly>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3 row">
|
||||||
|
<label for="thb_bottom" class="col-sm-4 col-form-label">Bottom</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input class="form-control" type="text" id="thb_bottom" name="thb_bottom" value="0" readonly>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 text-center">
|
||||||
|
<a href="/bo/listuploads" class="btn btn-primary">Go to the list of uploads</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
var image = document.getElementById('full-image');
|
||||||
|
var canvas = document.getElementById('canvas')
|
||||||
|
|
||||||
|
//hidden or text inputs
|
||||||
|
var h_th_left = document.getElementById('thb_left')
|
||||||
|
var h_th_top = document.getElementById('thb_top')
|
||||||
|
var h_th_right = document.getElementById('thb_right')
|
||||||
|
var h_th_bottom = document.getElementById('thb_bottom')
|
||||||
|
|
||||||
|
var handleRadius = 10
|
||||||
|
|
||||||
|
var dragTL = dragBL = dragTR = dragBR = false;
|
||||||
|
var dragWholeRect = false;
|
||||||
|
|
||||||
|
var rect={}
|
||||||
|
var current_canvas_rect={}
|
||||||
|
|
||||||
|
var mouseX, mouseY
|
||||||
|
var startX, startY
|
||||||
|
|
||||||
|
var th_left = 150;
|
||||||
|
var th_top = 896;
|
||||||
|
var th_right = 2009;
|
||||||
|
var th_bottom = 2753;
|
||||||
|
|
||||||
|
var th_width = th_right - th_left;
|
||||||
|
var th_height = th_bottom - th_top;
|
||||||
|
|
||||||
|
var effective_image_width = 4032;
|
||||||
|
var effective_image_height = 3024;
|
||||||
|
|
||||||
|
//drawRectInCanvas() connected functions -- START
|
||||||
|
function updateHiddenInputs(){
|
||||||
|
|
||||||
|
var inverse_ratio_w = effective_image_width / canvas.width;
|
||||||
|
var inverse_ratio_h = effective_image_height / canvas.height ;
|
||||||
|
|
||||||
|
h_th_left.value = Math.round(rect.left * inverse_ratio_w)
|
||||||
|
h_th_top.value = Math.round(rect.top * inverse_ratio_h)
|
||||||
|
h_th_right.value = Math.round((rect.left + rect.width) * inverse_ratio_w)
|
||||||
|
h_th_bottom.value = Math.round((rect.top + rect.height) * inverse_ratio_h)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawCircle(x, y, radius) {
|
||||||
|
var ctx = canvas.getContext("2d");
|
||||||
|
|
||||||
|
ctx.fillStyle = "#c757e7";
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(x, y, radius, 0, 2 * Math.PI);
|
||||||
|
ctx.fill();
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawHandles() {
|
||||||
|
drawCircle(rect.left, rect.top, handleRadius);
|
||||||
|
drawCircle(rect.left + rect.width, rect.top, handleRadius);
|
||||||
|
drawCircle(rect.left + rect.width, rect.top + rect.height, handleRadius);
|
||||||
|
drawCircle(rect.left, rect.top + rect.height, handleRadius);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function drawRectInCanvas()
|
||||||
|
{
|
||||||
|
|
||||||
|
var ctx = canvas.getContext("2d");
|
||||||
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.lineWidth = "6";
|
||||||
|
ctx.fillStyle = "rgba(199, 87, 231, 0.2)";
|
||||||
|
ctx.strokeStyle = "#c757e7";
|
||||||
|
ctx.rect(rect.left, rect.top, rect.width, rect.height);
|
||||||
|
ctx.fill();
|
||||||
|
ctx.stroke();
|
||||||
|
|
||||||
|
|
||||||
|
drawHandles();
|
||||||
|
updateHiddenInputs()
|
||||||
|
|
||||||
|
}
|
||||||
|
//drawRectInCanvas() connected functions -- END
|
||||||
|
|
||||||
|
function mouseUp(e) {
|
||||||
|
console.log('MOUSE UP!');
|
||||||
|
dragTL = dragTR = dragBL = dragBR = false;
|
||||||
|
dragWholeRect = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//mousedown connected functions -- START
|
||||||
|
function checkInRect(x, y, r) {
|
||||||
|
console.log(x,y,r.left,r.right);
|
||||||
|
return (x>r.left && x<(r.width+r.left)) && (y>r.top && y<(r.top+r.height));
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkCloseEnough(p1, p2) {
|
||||||
|
return Math.abs(p1 - p2) < handleRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMousePos(canvas, evt) {
|
||||||
|
|
||||||
|
var clx, cly
|
||||||
|
if (evt.type == "touchstart" || evt.type == "touchmove") {
|
||||||
|
clx = evt.touches[0].clientX;
|
||||||
|
cly = evt.touches[0].clientY;
|
||||||
|
} else {
|
||||||
|
clx = evt.clientX;
|
||||||
|
cly = evt.clientY;
|
||||||
|
}
|
||||||
|
|
||||||
|
var boundingRect = canvas.getBoundingClientRect();
|
||||||
|
return {
|
||||||
|
x: clx - boundingRect.left,
|
||||||
|
y: cly - boundingRect.top
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function mouseDown(e) {
|
||||||
|
var pos = getMousePos(this,e);
|
||||||
|
|
||||||
|
//mouseX = e.pageX - this.offsetLeft;
|
||||||
|
mouseX = pos.x;
|
||||||
|
mouseY = pos.y;
|
||||||
|
//mouseY = e.pageY - this.offsetTop;
|
||||||
|
|
||||||
|
// 0. inside movable rectangle
|
||||||
|
if (checkInRect(mouseX, mouseY, rect)){
|
||||||
|
dragWholeRect=true;
|
||||||
|
startX = mouseX;
|
||||||
|
startY = mouseY;
|
||||||
|
console.log('dragWholeRect');
|
||||||
|
}
|
||||||
|
// 1. top left
|
||||||
|
else if (checkCloseEnough(mouseX, rect.left) && checkCloseEnough(mouseY, rect.top)) {
|
||||||
|
dragTL = true;
|
||||||
|
console.log('dragTL');
|
||||||
|
}
|
||||||
|
// 2. top right
|
||||||
|
else if (checkCloseEnough(mouseX, rect.left + rect.width) && checkCloseEnough(mouseY, rect.top)) {
|
||||||
|
dragTR = true;
|
||||||
|
console.log('dragTR');
|
||||||
|
}
|
||||||
|
// 3. bottom left
|
||||||
|
else if (checkCloseEnough(mouseX, rect.left) && checkCloseEnough(mouseY, rect.top + rect.height)) {
|
||||||
|
dragBL = true;
|
||||||
|
console.log('dragBL');
|
||||||
|
}
|
||||||
|
// 4. bottom right
|
||||||
|
else if (checkCloseEnough(mouseX, rect.left + rect.width) && checkCloseEnough(mouseY, rect.top + rect.height)) {
|
||||||
|
dragBR = true;
|
||||||
|
console.log('dragBR');
|
||||||
|
}
|
||||||
|
// (5.) none of them
|
||||||
|
else {
|
||||||
|
// handle not resizing
|
||||||
|
}
|
||||||
|
|
||||||
|
drawRectInCanvas();
|
||||||
|
|
||||||
|
}
|
||||||
|
//mousedown connected functions -- END
|
||||||
|
|
||||||
|
function mouseMove(e) {
|
||||||
|
|
||||||
|
var pos = getMousePos(this,e);
|
||||||
|
mouseX = pos.x;
|
||||||
|
mouseY = pos.y;
|
||||||
|
|
||||||
|
//console.log(mouseX, mouseY)
|
||||||
|
|
||||||
|
|
||||||
|
if (dragWholeRect) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
dx = mouseX - startX;
|
||||||
|
dy = mouseY - startY;
|
||||||
|
if ((rect.left+dx)>0 && (rect.left+dx+rect.width)<canvas.width){
|
||||||
|
rect.left += dx;
|
||||||
|
}
|
||||||
|
if ((rect.top+dy)>0 && (rect.top+dy+rect.height)<canvas.height){
|
||||||
|
rect.top += dy;
|
||||||
|
}
|
||||||
|
startX = mouseX;
|
||||||
|
startY = mouseY;
|
||||||
|
} else if (dragTL) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
var newSide = (Math.abs(rect.left+rect.width - mouseX)+Math.abs(rect.height + rect.top - mouseY))/2;
|
||||||
|
if (newSide>150){
|
||||||
|
rect.left = rect.left + rect.width - newSide;
|
||||||
|
rect.top = rect.height + rect.top - newSide;
|
||||||
|
rect.width = rect.height = newSide;
|
||||||
|
}
|
||||||
|
} else if (dragTR) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
var newSide = (Math.abs(mouseX-rect.left)+Math.abs(rect.height + rect.top - mouseY))/2;
|
||||||
|
if (newSide>150){
|
||||||
|
rect.top = rect.height + rect.top - newSide;
|
||||||
|
rect.width = rect.height = newSide;
|
||||||
|
}
|
||||||
|
} else if (dragBL) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
var newSide = (Math.abs(rect.left+rect.width - mouseX)+Math.abs(rect.top - mouseY))/2;
|
||||||
|
if (newSide>150)
|
||||||
|
{
|
||||||
|
rect.left = rect.left + rect.width - newSide;
|
||||||
|
rect.width = rect.height = newSide;
|
||||||
|
}
|
||||||
|
} else if (dragBR) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
var newSide = (Math.abs(rect.left - mouseX)+Math.abs(rect.top - mouseY))/2;
|
||||||
|
if (newSide>150)
|
||||||
|
{
|
||||||
|
rect.width = rect.height = newSide;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drawRectInCanvas();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateCurrentCanvasRect(){
|
||||||
|
current_canvas_rect.height = canvas.height
|
||||||
|
current_canvas_rect.width = canvas.width
|
||||||
|
current_canvas_rect.top = image.offsetTop
|
||||||
|
current_canvas_rect.left = image.offsetLeft
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function repositionCanvas(){
|
||||||
|
|
||||||
|
//make canvas same as image, which may have changed size and position
|
||||||
|
canvas.height = image.height;
|
||||||
|
canvas.width = image.width;
|
||||||
|
canvas.style.top = image.offsetTop + "px";;
|
||||||
|
canvas.style.left = image.offsetLeft + "px";
|
||||||
|
|
||||||
|
//compute ratio comparing the NEW canvas rect with the OLD (current)
|
||||||
|
var ratio_w = canvas.width / current_canvas_rect.width;
|
||||||
|
var ratio_h = canvas.height / current_canvas_rect.height;
|
||||||
|
|
||||||
|
//update rect coordinates
|
||||||
|
rect.top = rect.top * ratio_h;
|
||||||
|
rect.left = rect.left * ratio_w;
|
||||||
|
rect.height = rect.height * ratio_h;
|
||||||
|
rect.width = rect.width * ratio_w;
|
||||||
|
|
||||||
|
updateCurrentCanvasRect();
|
||||||
|
|
||||||
|
drawRectInCanvas();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function initCanvas(){
|
||||||
|
canvas.height = image.height;
|
||||||
|
canvas.width = image.width;
|
||||||
|
canvas.style.top = image.offsetTop + "px";;
|
||||||
|
canvas.style.left = image.offsetLeft + "px";
|
||||||
|
updateCurrentCanvasRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
function initRect(){
|
||||||
|
|
||||||
|
var ratio_w = canvas.width / effective_image_width;
|
||||||
|
var ratio_h = canvas.height / effective_image_height;
|
||||||
|
|
||||||
|
//BORDER OF SIZE 6!
|
||||||
|
rect.height = th_height*ratio_h-6
|
||||||
|
rect.width = th_width*ratio_w-6
|
||||||
|
rect.top = th_top*ratio_h+3
|
||||||
|
rect.left = th_left*ratio_w+3
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function init(){
|
||||||
|
canvas.addEventListener('mousedown', mouseDown, false);
|
||||||
|
canvas.addEventListener('mouseup', mouseUp, false);
|
||||||
|
canvas.addEventListener('mousemove', mouseMove, false);
|
||||||
|
|
||||||
|
canvas.addEventListener('touchstart', mouseDown);
|
||||||
|
canvas.addEventListener('touchmove', mouseMove);
|
||||||
|
canvas.addEventListener('touchend', mouseUp);
|
||||||
|
|
||||||
|
initCanvas();
|
||||||
|
initRect();
|
||||||
|
|
||||||
|
drawRectInCanvas();
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('load',init)
|
||||||
|
window.addEventListener('resize',repositionCanvas)
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- End Main content -->
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<!-- Bootstrap 5 JavaScript -->
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
|
||||||
|
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
|
||||||
|
crossorigin="anonymous"></script>
|
||||||
|
|
||||||
|
<!-- get custom JavaScript -->
|
||||||
|
<script src="/static/js/custom.js"></script>
|
||||||
|
|
||||||
|
<form method="post">
|
||||||
|
<div class="modal fade" id="cookieModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLongTitle" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-lg shadow" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<span style="font-weight: bold" class="modal-title">Cookie Settings</span>
|
||||||
|
</div>
|
||||||
|
<div data-nosnippet class="modal-body">
|
||||||
|
<div style="font-size: 80%">
|
||||||
|
<p id="cmText1"></p>
|
||||||
|
<p id="cmText2"></p>
|
||||||
|
</div>
|
||||||
|
<p class="d-flex justify-content-between">
|
||||||
|
<a href="/privacy-notice">Privacy Notice</a>
|
||||||
|
<a href="#alert-options" data-bs-toggle="collapse" role="button" aria-expanded="false" aria-controls="alert-options">My Settings</a>
|
||||||
|
</p>
|
||||||
|
<div id="alert-options" class="collapse">
|
||||||
|
<div data-name="necessary">
|
||||||
|
<div class="form-check mb-1">
|
||||||
|
<input type="checkbox" checked disabled class="form-check-input" id="checkboxNecessary">
|
||||||
|
<label class="form-check-label" for="checkboxNecessary"><b>Necessary</b></label>
|
||||||
|
</div>
|
||||||
|
<ul>
|
||||||
|
<li>Required to run the website</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<!--div data-name="personalization">
|
||||||
|
<div class="form-check mb-1">
|
||||||
|
<input type="checkbox" class="form-check-input" id="checkboxPersonalization" name="checkboxPersonalization"
|
||||||
|
|
||||||
|
>
|
||||||
|
<label class="form-check-label" for="checkboxPersonalization"><b>Personalization</b></label>
|
||||||
|
</div>
|
||||||
|
<ul>
|
||||||
|
<li>Storage of your preferences from previous visits</li>
|
||||||
|
<li>Collecting user feedback to improve our website</li>
|
||||||
|
<li>Recording of your interests in order to provide customised content and offers</li>
|
||||||
|
</ul>
|
||||||
|
</div-->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<!-- Modal -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,251 @@
|
||||||
|
var image = document.getElementById('full-image');
|
||||||
|
var canvas = document.getElementById('canvas')
|
||||||
|
|
||||||
|
//hidden or text inputs
|
||||||
|
var h_th_left = document.getElementById('thb_left')
|
||||||
|
var h_th_top = document.getElementById('thb_top')
|
||||||
|
var h_th_right = document.getElementById('thb_right')
|
||||||
|
var h_th_bottom = document.getElementById('thb_bottom')
|
||||||
|
|
||||||
|
var handleRadius = 10
|
||||||
|
|
||||||
|
var dragTL = dragBL = dragTR = dragBR = false;
|
||||||
|
var dragWholeRect = false;
|
||||||
|
|
||||||
|
var rect={}
|
||||||
|
var current_canvas_rect={}
|
||||||
|
|
||||||
|
var mouseX, mouseY
|
||||||
|
var startX, startY
|
||||||
|
|
||||||
|
var th_left = 504;
|
||||||
|
var th_top = 0;
|
||||||
|
var th_right = 3528;
|
||||||
|
var th_bottom = 3024;
|
||||||
|
|
||||||
|
var th_width = th_right - th_left;
|
||||||
|
var th_height = th_bottom - th_top;
|
||||||
|
|
||||||
|
var effective_image_width = 4032;
|
||||||
|
var effective_image_height = 3024;
|
||||||
|
|
||||||
|
//drawRectInCanvas() connected functions -- START
|
||||||
|
function updateHiddenInputs(){
|
||||||
|
var inverse_ratio_w = effective_image_width / canvas.width;
|
||||||
|
var inverse_ratio_h = effective_image_height / canvas.height ;
|
||||||
|
h_th_left.value = Math.round(rect.left * inverse_ratio_w)
|
||||||
|
h_th_top.value = Math.round(rect.top * inverse_ratio_h)
|
||||||
|
h_th_right.value = Math.round((rect.left + rect.width) * inverse_ratio_w)
|
||||||
|
h_th_bottom.value = Math.round((rect.top + rect.height) * inverse_ratio_h)
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawCircle(x, y, radius) {
|
||||||
|
var ctx = canvas.getContext("2d");
|
||||||
|
ctx.fillStyle = "#c757e7";
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(x, y, radius, 0, 2 * Math.PI);
|
||||||
|
ctx.fill();
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawHandles() {
|
||||||
|
drawCircle(rect.left, rect.top, handleRadius);
|
||||||
|
drawCircle(rect.left + rect.width, rect.top, handleRadius);
|
||||||
|
drawCircle(rect.left + rect.width, rect.top + rect.height, handleRadius);
|
||||||
|
drawCircle(rect.left, rect.top + rect.height, handleRadius);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function drawRectInCanvas()
|
||||||
|
{
|
||||||
|
var ctx = canvas.getContext("2d");
|
||||||
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.lineWidth = "6";
|
||||||
|
ctx.fillStyle = "rgba(199, 87, 231, 0.2)";
|
||||||
|
ctx.strokeStyle = "#c757e7";
|
||||||
|
ctx.rect(rect.left, rect.top, rect.width, rect.height);
|
||||||
|
ctx.fill();
|
||||||
|
ctx.stroke();
|
||||||
|
drawHandles();
|
||||||
|
updateHiddenInputs()
|
||||||
|
}
|
||||||
|
//drawRectInCanvas() connected functions -- END
|
||||||
|
|
||||||
|
function mouseUp(e) {
|
||||||
|
dragTL = dragTR = dragBL = dragBR = false;
|
||||||
|
dragWholeRect = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//mousedown connected functions -- START
|
||||||
|
function checkInRect(x, y, r) {
|
||||||
|
return (x>r.left && x<(r.width+r.left)) && (y>r.top && y<(r.top+r.height));
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkCloseEnough(p1, p2) {
|
||||||
|
return Math.abs(p1 - p2) < handleRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMousePos(canvas, evt) {
|
||||||
|
var clx, cly
|
||||||
|
if (evt.type == "touchstart" || evt.type == "touchmove") {
|
||||||
|
clx = evt.touches[0].clientX;
|
||||||
|
cly = evt.touches[0].clientY;
|
||||||
|
} else {
|
||||||
|
clx = evt.clientX;
|
||||||
|
cly = evt.clientY;
|
||||||
|
}
|
||||||
|
var boundingRect = canvas.getBoundingClientRect();
|
||||||
|
return {
|
||||||
|
x: clx - boundingRect.left,
|
||||||
|
y: cly - boundingRect.top
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function mouseDown(e) {
|
||||||
|
var pos = getMousePos(this,e);
|
||||||
|
mouseX = pos.x;
|
||||||
|
mouseY = pos.y;
|
||||||
|
// 0. inside movable rectangle
|
||||||
|
if (checkInRect(mouseX, mouseY, rect)){
|
||||||
|
dragWholeRect=true;
|
||||||
|
startX = mouseX;
|
||||||
|
startY = mouseY;
|
||||||
|
}
|
||||||
|
// 1. top left
|
||||||
|
else if (checkCloseEnough(mouseX, rect.left) && checkCloseEnough(mouseY, rect.top)) {
|
||||||
|
dragTL = true;
|
||||||
|
}
|
||||||
|
// 2. top right
|
||||||
|
else if (checkCloseEnough(mouseX, rect.left + rect.width) && checkCloseEnough(mouseY, rect.top)) {
|
||||||
|
dragTR = true;
|
||||||
|
}
|
||||||
|
// 3. bottom left
|
||||||
|
else if (checkCloseEnough(mouseX, rect.left) && checkCloseEnough(mouseY, rect.top + rect.height)) {
|
||||||
|
dragBL = true;
|
||||||
|
}
|
||||||
|
// 4. bottom right
|
||||||
|
else if (checkCloseEnough(mouseX, rect.left + rect.width) && checkCloseEnough(mouseY, rect.top + rect.height)) {
|
||||||
|
dragBR = true;
|
||||||
|
}
|
||||||
|
// (5.) none of them
|
||||||
|
else {
|
||||||
|
// handle not resizing
|
||||||
|
}
|
||||||
|
drawRectInCanvas();
|
||||||
|
}
|
||||||
|
//mousedown connected functions -- END
|
||||||
|
|
||||||
|
function mouseMove(e) {
|
||||||
|
var pos = getMousePos(this,e);
|
||||||
|
mouseX = pos.x;
|
||||||
|
mouseY = pos.y;
|
||||||
|
if (dragWholeRect) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
dx = mouseX - startX;
|
||||||
|
dy = mouseY - startY;
|
||||||
|
if ((rect.left+dx)>0 && (rect.left+dx+rect.width)<canvas.width){
|
||||||
|
rect.left += dx;
|
||||||
|
}
|
||||||
|
if ((rect.top+dy)>0 && (rect.top+dy+rect.height)<canvas.height){
|
||||||
|
rect.top += dy;
|
||||||
|
}
|
||||||
|
startX = mouseX;
|
||||||
|
startY = mouseY;
|
||||||
|
} else if (dragTL) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
var newSide = (Math.abs(rect.left+rect.width - mouseX)+Math.abs(rect.height + rect.top - mouseY))/2;
|
||||||
|
if (newSide>150){
|
||||||
|
rect.left = rect.left + rect.width - newSide;
|
||||||
|
rect.top = rect.height + rect.top - newSide;
|
||||||
|
rect.width = rect.height = newSide;
|
||||||
|
}
|
||||||
|
} else if (dragTR) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
var newSide = (Math.abs(mouseX-rect.left)+Math.abs(rect.height + rect.top - mouseY))/2;
|
||||||
|
if (newSide>150){
|
||||||
|
rect.top = rect.height + rect.top - newSide;
|
||||||
|
rect.width = rect.height = newSide;
|
||||||
|
}
|
||||||
|
} else if (dragBL) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
var newSide = (Math.abs(rect.left+rect.width - mouseX)+Math.abs(rect.top - mouseY))/2;
|
||||||
|
if (newSide>150)
|
||||||
|
{
|
||||||
|
rect.left = rect.left + rect.width - newSide;
|
||||||
|
rect.width = rect.height = newSide;
|
||||||
|
}
|
||||||
|
} else if (dragBR) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
var newSide = (Math.abs(rect.left - mouseX)+Math.abs(rect.top - mouseY))/2;
|
||||||
|
if (newSide>150)
|
||||||
|
{
|
||||||
|
rect.width = rect.height = newSide;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
drawRectInCanvas();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateCurrentCanvasRect(){
|
||||||
|
current_canvas_rect.height = canvas.height
|
||||||
|
current_canvas_rect.width = canvas.width
|
||||||
|
current_canvas_rect.top = image.offsetTop
|
||||||
|
current_canvas_rect.left = image.offsetLeft
|
||||||
|
}
|
||||||
|
|
||||||
|
function repositionCanvas(){
|
||||||
|
//make canvas same as image, which may have changed size and position
|
||||||
|
canvas.height = image.height;
|
||||||
|
canvas.width = image.width;
|
||||||
|
canvas.style.top = image.offsetTop + "px";;
|
||||||
|
canvas.style.left = image.offsetLeft + "px";
|
||||||
|
//compute ratio comparing the NEW canvas rect with the OLD (current)
|
||||||
|
var ratio_w = canvas.width / current_canvas_rect.width;
|
||||||
|
var ratio_h = canvas.height / current_canvas_rect.height;
|
||||||
|
//update rect coordinates
|
||||||
|
rect.top = rect.top * ratio_h;
|
||||||
|
rect.left = rect.left * ratio_w;
|
||||||
|
rect.height = rect.height * ratio_h;
|
||||||
|
rect.width = rect.width * ratio_w;
|
||||||
|
updateCurrentCanvasRect();
|
||||||
|
drawRectInCanvas();
|
||||||
|
}
|
||||||
|
|
||||||
|
function initCanvas(){
|
||||||
|
canvas.height = image.height;
|
||||||
|
canvas.width = image.width;
|
||||||
|
canvas.style.top = image.offsetTop + "px";;
|
||||||
|
canvas.style.left = image.offsetLeft + "px";
|
||||||
|
updateCurrentCanvasRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
function initRect(){
|
||||||
|
var ratio_w = canvas.width / effective_image_width;
|
||||||
|
var ratio_h = canvas.height / effective_image_height;
|
||||||
|
//BORDER OF SIZE 6!
|
||||||
|
rect.height = th_height*ratio_h-6
|
||||||
|
rect.width = th_width*ratio_w-6
|
||||||
|
rect.top = th_top*ratio_h+3
|
||||||
|
rect.left = th_left*ratio_w+3
|
||||||
|
}
|
||||||
|
|
||||||
|
function init(){
|
||||||
|
canvas.addEventListener('mousedown', mouseDown, false);
|
||||||
|
canvas.addEventListener('mouseup', mouseUp, false);
|
||||||
|
canvas.addEventListener('mousemove', mouseMove, false);
|
||||||
|
canvas.addEventListener('touchstart', mouseDown);
|
||||||
|
canvas.addEventListener('touchmove', mouseMove);
|
||||||
|
canvas.addEventListener('touchend', mouseUp);
|
||||||
|
initCanvas();
|
||||||
|
initRect();
|
||||||
|
drawRectInCanvas();
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('load',init)
|
||||||
|
window.addEventListener('resize',repositionCanvas)
|
||||||
|
|
||||||
|
//
|
Loading…
Reference in New Issue