about summary refs log blame commit diff stats
path: root/js/toadmode/toad.js
blob: 143c5f3482b885d38f01cc2c2b3be691a2bb1129 (plain) (tree)
1
2
3
4
5
6
7
8
9

                                          
                                               

                               
                                        
                    
 
                






                                      

                                    

                                    

                                         
                             
                                                         
                                      
                                                     

                                                             
                            
                                    


                                         

                                                              


                                                         








                                                                                                       


                                                             








                                                                                                       



                                                            
                            
     
                   



                                                         
                                            

                                                
                                    

                                                 

                                                                         

                                                     


















                                                                                             
                                           
                                    
                                                                                                    


                                       

                                    
                                             

                                                                  






                                                                                      

   

                                                                       
               
                                  
                                               

 
                        





                                                         


                                                                   
     
 

                                                                    
     





                                                







                                                     
                                                

                                                                  

                              
 
           
const viewportWidth = window.innerWidth;
const viewportHeight = window.innerHeight;
const canvas = document.getElementById('toad');
canvas.width = viewportWidth;
canvas.height = viewportHeight;
const context = canvas.getContext('2d');
const cellSize = 50;

let shapes = [];

const drawLine = (x1, y1, x2, y2) => {
    context.moveTo(x1, y1);
    context.lineTo(x2, y2);
    context.stroke();
};

const drawShape = (shape, x, y) => {
    context.beginPath();
    context.strokeStyle = '#2d2d2d';
    context.fillStyle = '#2d2d2d';
    const size = cellSize * 0.8;
    const offset = (cellSize - size) / 2;
    if (shape === 'square') {
        context.rect(x + offset, y + offset, size, size);
    } else if (shape === 'triangle') {
        context.moveTo(x + cellSize / 2, y + offset);
        context.lineTo(x + offset, y + size + offset);
        context.lineTo(x + size + offset, y + size + offset);
        context.closePath();
    } else if (shape === 'circle') {
        const radius = cellSize * 0.4;
        const centerX = x + cellSize / 2;
        const centerY = y + cellSize / 2;
        context.arc(centerX, centerY, radius, 0, 2 * Math.PI);
    } else if (shape === 'octagon') {
        const cellCenterX = x + cellSize / 2;
        const cellCenterY = y + cellSize / 2;
        const sideLength = cellSize / (2 + Math.sqrt(2));
        const angle = (2 * Math.PI) / 8;
        context.moveTo(cellCenterX + sideLength * Math.cos(0), cellCenterY + sideLength * Math.sin(0));
        [...Array(8).keys()].slice(1).forEach(i => {
            const newX = cellCenterX + sideLength * Math.cos(i * angle);
            const newY = cellCenterY + sideLength * Math.sin(i * angle);
            context.lineTo(newX, newY);
        });
        context.closePath();
    } else if (shape === 'pentagon') {
        const cellCenterX = x + cellSize / 2;
        const cellCenterY = y + cellSize / 2;
        const sideLength = cellSize / (1 + Math.sqrt(5 / 2));
        const angle = (2 * Math.PI) / 5;
        context.moveTo(cellCenterX + sideLength * Math.cos(0), cellCenterY + sideLength * Math.sin(0));
        [...Array(5).keys()].slice(1).forEach(i => {
            const newX = cellCenterX + sideLength * Math.cos(i * angle);
            const newY = cellCenterY + sideLength * Math.sin(i * angle);
            context.lineTo(newX, newY);
        });
        context.closePath();
    } else if (shape === 'diamond') {
        context.moveTo(x + cellSize / 2, y + offset);
        context.lineTo(x + offset, y + cellSize / 2);
        context.lineTo(x + cellSize / 2, y + size + offset);
        context.lineTo(x + size + offset, y + cellSize / 2);
        context.closePath();
    }
    context.fill();
    context.stroke();
    shapes.push({ type: shape, x, y, color: '#2d2d2d' });
};

const createContextMenuOption = (shape) => {
    const option = document.createElement('li');
    option.textContent = shape;
    option.style.cursor = 'pointer';
    option.addEventListener('click', (event) => {
        contextMenu.style.display = 'none';
        const cellX = Math.floor(lastRightClick.x / cellSize) * cellSize;
        const cellY = Math.floor(lastRightClick.y / cellSize) * cellSize;
        drawShape(shape.toLowerCase(), cellX, cellY);
    });
    if (shape === 'Nope') {
        option.style.color = 'lightcoral';
    }
    return option;
};

const contextMenu = document.createElement('ul');
contextMenu.id = 'context-menu';
contextMenu.style.display = 'none';
contextMenu.style.position = 'fixed';
contextMenu.style.listStyle = 'none';
contextMenu.style.lineHeight = '1.25';
contextMenu.style.padding = '10px';
contextMenu.style.fontSize = '18px';
contextMenu.style.backgroundColor = 'white';
contextMenu.style.border = '1px solid black';

['Square', 'Triangle', 'Circle', 'Octagon', 'Pentagon', 'Diamond', 'Nope'].forEach(shape => {
    const option = createContextMenuOption(shape);
    option.className = 'context-menu-item';
    contextMenu.appendChild(option);
}); // I mean, realistically shape should be label, but I got this far...so Nope is gonna be a shape

document.body.appendChild(contextMenu);

let lastRightClick = { x: 0, y: 0 };

canvas.addEventListener('click', (event) => {
    const cellX = Math.floor(event.clientX / cellSize) * cellSize;
    const cellY = Math.floor(event.clientY / cellSize) * cellSize;
    const clickedShape = shapes.find(shape => shape.x === cellX && shape.y === cellY);
    if (!clickedShape) {
        lastRightClick = { x: event.clientX, y: event.clientY };
        contextMenu.style.display = 'block';
        contextMenu.style.left = `${event.clientX}px`;
        contextMenu.style.top = `${event.clientY}px`;
    }
});

const removeShape = (x, y) => {
    shapes = shapes.filter(shape => !(shape.x === x && shape.y === y));
    drawGrid();
    context.fillStyle = '#f0f0f0';
    context.fillRect(x, y, cellSize, cellSize);
}

const drawGrid = () => {
    context.clearRect(0, 0, canvas.width, canvas.height);

    context.fillStyle = '#f0f0f0';
    context.fillRect(0, 0, canvas.width, canvas.height);

    context.strokeStyle = 'white';

    for (let x = 0; x < Math.ceil(viewportWidth / cellSize); x++) {
        drawLine(x * cellSize, 0, x * cellSize, viewportHeight);
    }

    for (let y = 0; y < Math.ceil(viewportHeight / cellSize); y++) {
        drawLine(0, y * cellSize, viewportWidth, y * cellSize);
    }

    shapes.forEach(shape => {
        drawShape(shape.type, shape.x, shape.y);
    });
}

let beatCounter = 0;
window.addEventListener('keydown', (event) => {
    if (event.key === ' ' || event.key === 'Enter') {
        beatCounter++;
        console.log(`Beat: ${beatCounter}`);
    }
});

canvas.addEventListener('dblclick', (event) => {
    const cellX = Math.floor(event.clientX / cellSize) * cellSize;
    const cellY = Math.floor(event.clientY / cellSize) * cellSize;
    removeShape(cellX, cellY);
});

drawGrid();