Segelparade / www / symfonyproject / public / assets / js / cutout.js
cutout.js
Raw
document.addEventListener("DOMContentLoaded", function() {
    const lastIndex = imagePath.lastIndexOf(".");
    const cutImagePath = imagePath.slice(0, lastIndex) + ".png";
    const canvas = document.getElementById('canvas');
    const mainImage = document.getElementById('mainImage');
    const completeDrawingButton = document.getElementById('completeDrawing');
    const clearButton = document.getElementById('clearButton');
    const ctx = canvas.getContext('2d');
    const coordinates = [];

    function canvasScale(type) {
        // get the original image size
        let actualWidth = mainImage.clientWidth;
        let actualHeight = mainImage.clientHeight;
        if (type === "getScale") {
            // calculate the scale-factor to properly cut the image
            let naturalWidth = mainImage.naturalWidth;
            let scaleFactor = naturalWidth / actualWidth;
            return scaleFactor;
        } else if (type === "resize") {
            // adjust canvas to fit on the image
            canvas.width = actualWidth;
            canvas.height = actualHeight;
            canvas.style.top = mainImage.offsetTop + 'px';
            canvas.style.left = mainImage.offsetLeft + 'px';
            ctx.clearRect(0, 0, canvas.width, canvas.height);
        }       
    }

    // resize canvas on loaded window
    window.addEventListener("load", canvasScale("resize"));
    document.getElementById("cutoutContainer");
    cutoutContainer.style.display = "none";

    // left-click to add coordinates/ points
    canvas.addEventListener('click', function(event) {
        const rect = canvas.getBoundingClientRect();
        const scaleX = canvas.width / rect.width;
        const scaleY = canvas.height / rect.height;
        let x = (event.clientX - rect.left) * scaleX;
        let y = (event.clientY - rect.top) * scaleY;
        coordinates.push({x, y});
        drawCoordinates();
    })

    // right-click to remove existing coordinates
    canvas.addEventListener('contextmenu', function(event) {
        event.preventDefault();
        const rect = canvas.getBoundingClientRect();
        const scaleX = canvas.width / rect.width;
        const scaleY = canvas.height / rect.height;
        let x = (event.clientX - rect.left) * scaleX;
        let y = (event.clientY - rect.top) * scaleY;
        const index = coordinates.findIndex(coord => {
            return Math.abs(coord.x - x) < 5 && Math.abs(coord.y - y) < 5;
        });
        if (index !== -1) {
            coordinates.splice(index, 1);
            drawCoordinates();
        }
    });

    // completion of the drawing
    completeDrawingButton.addEventListener('click', function() {
        // start a loading animation
        loadingAnimation('start');
        // adjust coordinates to the original size of the image
        for (let i = 0; i < coordinates.length; i++) {
            coordinates[i].x *= canvasScale("getScale");
            coordinates[i].y *= canvasScale("getScale");
        }
        const xhr = new XMLHttpRequest();
        xhr.open('POST','/save_drawing', true);
        xhr.setRequestHeader('Content-Type', 'application/json');
        xhr.onreadystatechange = function() {
            if (xhr.readyState === 4 && xhr.status === 200) {
                // readyState 4 => request finished ; status 200 => worked correctly
                loadingAnimation('stop');
                finishedDrawing();
            }
        };
        // prepare object with coordinates, image path and cutImagePath to send to php
        var data = {
            coordinates: coordinates,
            imagePath: imagePath,
            cutImagePath: cutImagePath,
        }
        xhr.send(JSON.stringify(data));
        coordinates.length = 0;
        drawCoordinates();
    });

    // clearing the image
    clearButton.addEventListener('click', function() {
        coordinates.length = 0;
        drawCoordinates();
    })

    // draw new coordinates / refresh the drawing
    function drawCoordinates() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.fillStyle = 'blue';
        ctx.imageSmoothingEnabled = true;           // Enable anti-aliasing
        ctx.lineWidth = 2;                          // Adjust line width for smoother rendering
        ctx.lineCap = 'round';                      // Use rounded line caps
        ctx.lineJoin = 'round';                     // Use rounded line joins
        coordinates.forEach((coord, index) => {
            ctx.beginPath();
            ctx.arc(coord.x, coord.y, 3, 0, Math.PI * 2);
            ctx.fill();
            if (index > 0) {
                ctx.beginPath();
                ctx.moveTo(coordinates[index - 1].x, coordinates[index - 1].y);
                ctx.lineTo(coord.x, coord.y);
                ctx.strokeStyle = 'white';
                ctx.stroke();
            }
        });
    }
});


// start cutout
function startCutout() {
    // show the cutout interface
    cutoutContainer.style.display = "block";
    
    // remove the clicked button
    const cutoutStart = document.getElementById("cutoutStart");
    cutoutStart.style.display = "none";

    // remove wave animation
    toggleWave("remove");

    // change heading
    let uploadHeading = document.getElementById("uploadHeading");
    uploadHeading.innerText = "Durch Klicken umrahmen"
}


// finish drawing
function finishedDrawing() {
    // remove cutout interface
    cutoutContainer.style.display = "none";
    
    // change heading
    let uploadHeading = document.getElementById("uploadHeading");
    uploadHeading.innerText = "Danke für deine Hilfe!"

    // refresh image in wave-animation and show it
    toggleWave("show");
    refreshImage();
}


// loading animation
function loadingAnimation(type) {
    let loading = document.getElementById('loading');
    if (type == 'start') {
        loading.style.display = 'flex';
    } else if (type == 'stop') {
        loading.style.display = 'none';
    }
}

  

// toggle showing wave animation
function toggleWave(type) {
    let wave = document.getElementById("anim_container")
    if (type === "remove") {
      wave.style.display = "none";
    }
    else if(type === "show"){
        wave.style.display = "block";
    }
    else {
      wave.style.display = "block";
    }
}