Greasy Fork is available in English.

PixelPlace Image Placer

Place images on pixelplace.io

// ==UserScript==
// @name         PixelPlace Image Placer
// @namespace    http://tampermonkey.net/
// @version      v4
// @description  Place images on pixelplace.io
// @author       Ghost
// @match        https://pixelplace.io/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    let image = $('<img>');
    image.css({
        position: 'absolute',
        opacity: '0.5', // 50% transparent by default
    });
    let imageSize = 100; // Initial image size
    let imageUrl = ''; // URL for image
    let originalImageUrl = ''; // Original URL for image
    let locked = false; // Image lock state
    let lockImageUrl = 'https://i.imgur.com/RmYtAGW.jpg'; // URL for lock image
    let copyrightElement = $('#copyright');

    // Create buttons for resizing and uploading images
    let uploadButton = createButton('Upload Image', '150px', '10%', '-50%', 'translateY(-50%)');
    let biggerButton = createButton('Bigger', '150px', '25%', '-50%', 'translateY(-50%)');
    let smallerButton = createButton('Smaller', '150px', '40%', '-50%', 'translateY(-50%)');
    let lockButton = createButton('Lock Image', '150px', '55%', '-50%', 'translateY(-50%)');
    // Create opacity slider
    let opacitySlider = createSlider('Opacity', '150px', '70%', '-50%', 'translateY(-50%)');

    // Create menu button
    let menuButton = createButton('Menu', '80px', '5%', '-50%', 'translateY(-50%)');
    menuButton.css('display', ''); // Ensure menu button is visible initially

    // Function to create a button
    function createButton(text, width, top, topTranslation, transform) {
        let button = $('<button>').text(text).css({
            position: 'fixed',
            left: '50%',
            transform: 'translateX(-50%) ' + transform, // Center horizontally
            width: width,
            top: top,
            display: 'none', // Initially invisible
            outline: '3px solid transparent',
            outlineOffset: '-3px',
            animation: 'rainbow 2s infinite',
        });
        $('body').append(button);
        return button;
    }

    // Function to create a slider
    function createSlider(text, width, top, topTranslation, transform) {
        let label = $('<label>').text(text).css({
            position: 'fixed',
            left: '50%',
            transform: 'translateX(-50%) ' + transform, // Center horizontally
            width: width,
            top: top,
            display: 'none', // Initially invisible
        });

        let slider = $('<input>').attr({
            type: 'range',
            min: '0',
            max: '100',
            value: '50', // Starting at 50% opacity
        }).css({
            width: '100%',
            position: 'absolute',
            left: '0',
            top: '20px', // Position below the label
            outline: '1px solid blue', // Adding outline to the slider
            display: 'none', // Initially invisible
        });

        label.append(slider);
        $('body').append(label);

        return slider;
    }

    // Function to toggle the visibility of other buttons
    function toggleMenu() {
        let buttons = [uploadButton, biggerButton, smallerButton, lockButton, opacitySlider];
        for (let button of buttons) {
            button.css('display', button.css('display') === 'none' ? '' : 'none');
        }
        opacitySlider.parent().css('display', opacitySlider.parent().css('display') === 'none' ? '' : 'none');
    }

    // Event listener for menu button
    menuButton.click(toggleMenu);

    // Function to place the image at the clicked position
    function placeImage(event) {
        if (!locked && imageUrl) {
            const x = event.clientX + window.scrollX;
            const y = event.clientY + window.scrollY;
            image.attr('src', imageUrl).css({
                left: x + 'px',
                top: y + 'px',
                width: imageSize + 'px',
                outline: '3px solid transparent',
                outlineOffset: '-3px',
                boxShadow: '0 0 0 3px white inset', // Adding white inset outline
                animation: 'rainbow 2s infinite',
            });
            $('#painting-move').append(image);
        }
    }

    // Function to toggle image lock
    function toggleLock() {
        locked = !locked;
        if (!locked) {
            image.attr('src', originalImageUrl); // Restore original image when unlocked
        }
        updateOpacity(); // Update opacity only if the image is not locked
        updateCopyright();
    }

    // Function to update the opacity based on lock state and slider
    function updateOpacity() {
        if (!locked) {
            let opacityValue = opacitySlider.val();
            image.css('opacity', opacityValue / 100); // Convert to 0-1 range for CSS
        }
    }

    // Function to update the text in the copyright element
    function updateCopyright() {
        if (locked) {
            copyrightElement.text('Image Locked').css('color', 'red');
        } else {
            copyrightElement.text('Image Not Locked').css('color', 'green');
        }
    }

    // Event listener for mouse click to place the image
    $(document).click(placeImage);

    // Event listener for resizing the image bigger
    biggerButton.click(function() {
        imageSize += 10;
        image.css('width', imageSize + 'px');
    });

    // Event listener for resizing the image smaller
    smallerButton.click(function() {
        if (imageSize > 10) {
            imageSize -= 10;
            image.css('width', imageSize + 'px');
        }
    });

    // Event listener for uploading an image
    uploadButton.click(function() {
        const fileInput = $('<input>').attr({
            type: 'file',
            accept: 'image/*',
        }).change(function() {
            const file = fileInput[0].files[0];
            const reader = new FileReader();
            reader.onload = function(e) {
                imageUrl = e.target.result;
                originalImageUrl = imageUrl; // Store original image URL
                if (!locked && imageUrl) {
                    image.attr('src', imageUrl).css('width', imageSize + 'px');
                }
            };
            reader.readAsDataURL(file);
        });
        fileInput.click();
    });

    // Event listener for locking/unlocking the image
    lockButton.click(toggleLock);

    // Event listener for the opacity slider
    opacitySlider.on('input', function() {
        updateOpacity(); // Adjust opacity in real-time
    });

    // Event listener for keyboard controls
    $(document).keydown(function(event) {
        // Down arrow key: Toggle image lock
        if (event.key === 'ArrowDown') {
            toggleLock();
        }
    });

    // Prevent interactions with elements behind the image
    image.mousedown(function(event) {
        event.stopPropagation();
    });

    // Ensure mouse events pass through the image
    image.css('pointer-events', 'none');

    // Initialize the copyright text
    updateCopyright();
})();