585 lines
21 KiB
Plaintext
585 lines
21 KiB
Plaintext
---
|
|
import Layout from '../../layouts/Layout.astro';
|
|
---
|
|
<Layout title='Drawing Game'>
|
|
<main>
|
|
<div>
|
|
</div>
|
|
<script is:inline src="/assets/js/phaser_3.60.0.js"></script>
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
|
|
</main>
|
|
</Layout>
|
|
<script is:inline>
|
|
const isMobile = window.innerWidth <= 768; // Define your mobile breakpoint as needed
|
|
const drawingZone = {
|
|
x: isMobile ? 0 : window.innerWidth / 4, // Set x to 0 on mobile, else 1/4 of screen width
|
|
y: window.innerHeight / 4,
|
|
width: isMobile ? window.innerWidth : window.innerWidth / 2, // Full width on mobile, else 1/2 of screen width
|
|
height: window.innerHeight / 2,
|
|
};
|
|
var assetsList = {}
|
|
const params = new URLSearchParams(window.location.search);
|
|
const paramsID = params.get('id');
|
|
const data = fetch(`https://management.beanstalkedu.com/items/game_drawing/${encodeURIComponent(paramsID)}`)
|
|
.then(response => response.json())
|
|
.then(({data}) => {
|
|
const {image} = data;
|
|
assetsList.image = "https://management.beanstalkedu.com/assets/" + image; // + "?width=450";
|
|
const config = {
|
|
type: Phaser.AUTO,
|
|
width: window.innerWidth,
|
|
height: window.innerHeight,
|
|
backgroundColor: '#ffffff',
|
|
scale: {
|
|
mode: Phaser.Scale.FIT,
|
|
autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
|
|
},
|
|
scene: {
|
|
preload: preload,
|
|
create: create,
|
|
update: update,
|
|
},
|
|
};
|
|
const game = new Phaser.Game(config);
|
|
|
|
})
|
|
.catch(error => {
|
|
|
|
console.error('Error fetching initial data:', error);
|
|
});
|
|
const displayW = window.innerWidth;
|
|
const displayH = window.innerHeight;
|
|
|
|
let graphics;
|
|
let isDrawing = false;
|
|
let selectedColor = '#f00f0f'; // Default color
|
|
let brushSize = 10; // Default brush size
|
|
let customCursor;
|
|
const cursorSizeMultiplier = 1;
|
|
let isErasing = false;
|
|
|
|
function preload() {
|
|
this.load.image('outline', assetsList.image);
|
|
}
|
|
|
|
function create() {
|
|
const params = new URLSearchParams(window.location.search);
|
|
const paramsID = params.get('id');
|
|
fetch(`https://management.beanstalkedu.com/items/game_drawing/${encodeURIComponent(paramsID)}`)
|
|
.then(response => response.json())
|
|
.then(({ data }) => {
|
|
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2;
|
|
const baseFontSize = 40;
|
|
const responsiveFontSize = (window.innerWidth / 950) * baseFontSize;
|
|
const descrptText = this.add.text(screenCenterX, 50, data.description, {
|
|
font: `${responsiveFontSize}px quicksand`,
|
|
fill: '#7c4c23',
|
|
}).setOrigin(0.5);
|
|
|
|
})
|
|
.catch(error => {
|
|
console.error('Error fetching initial data:', error);
|
|
});
|
|
const outlineImage = this.add.image(displayW / 2, displayH / 2, 'outline').setScale(0.5);
|
|
outlineImage.setDepth(1);
|
|
graphics = this.add.graphics();
|
|
|
|
const colorContainer = document.createElement('div');
|
|
colorContainer.style.position = 'absolute';
|
|
colorContainer.style.top = '10%';
|
|
colorContainer.style.left = '20px';
|
|
colorContainer.style.display = 'flex'; // Display color picker and buttons horizontally
|
|
// Create the color picker
|
|
const colorPicker = document.createElement('input');
|
|
colorPicker.type = 'color';
|
|
colorPicker.value = selectedColor;
|
|
colorPicker.className = 'color-picker';
|
|
colorPicker.style.marginTop = '-0px';
|
|
colorPicker.style.marginRight = '15px';
|
|
colorPicker.style.padding = '1px 1px';
|
|
colorPicker.style.outline = 'none';
|
|
colorPicker.style.width = '46px';
|
|
colorPicker.style.height = '46px';
|
|
colorPicker.style.border = '3px solid #05b3a4';
|
|
colorPicker.style.backgroundColor = '#05b3a4';
|
|
colorPicker.style.borderRadius = '50%';
|
|
colorPicker.style.boxShadow = '5px 10px 30px #7c4c2390';
|
|
|
|
|
|
colorPicker.addEventListener('input', (event) => {
|
|
if (!isErasing) {
|
|
selectedColor = event.target.value; // Update selectedColor if not erasing
|
|
}
|
|
});
|
|
|
|
// Append the color picker to the color container
|
|
colorContainer.appendChild(colorPicker);
|
|
|
|
const colors = ['#ff0000', '#00ff00', '#0000ff', '#ffff00', '#ff00ff', '#00ffff'];
|
|
const buttonSize = 50;
|
|
const buttonSpacing = 15;
|
|
|
|
// Create a container div for the color buttons
|
|
const colorButtonsContainer = document.createElement('div');
|
|
colorButtonsContainer.style.display = 'flex'; // Display color buttons horizontally
|
|
|
|
// Align the color buttons to the left of the viewport
|
|
const buttonX = 30; // Adjusted position (e.g., 10px from the left)
|
|
const colorPaletteY = drawingZone.y - 20; // Position it at the top of the drawing zone
|
|
|
|
// Keep track of the selected color
|
|
let selectedButton = null;
|
|
|
|
colors.forEach((color, index) => {
|
|
const x = buttonX + index * (buttonSize + buttonSpacing);
|
|
const button = document.createElement('button');
|
|
button.style.backgroundColor = color;
|
|
button.style.width = `${buttonSize}px`;
|
|
button.style.height = `${buttonSize}px`;
|
|
button.style.border = '3px solid #05b3a4';
|
|
button.style.boxShadow = '5px 10px 30px #7c4c2390';
|
|
button.style.borderRadius = '50%'
|
|
button.style.marginRight = `${buttonSpacing}px`;
|
|
|
|
button.addEventListener('click', () => {
|
|
// Remove the mark from the previously selected button, if any
|
|
if (selectedButton) {
|
|
// Remove the border
|
|
}
|
|
// Set the new selected color
|
|
selectedColor = color;
|
|
|
|
// Add a border or tick mark to indicate the selected color
|
|
button.style.border = '3px solid #000'; // Add a black border (you can customize this)
|
|
// Update the selectedButton variable to the current button
|
|
selectedButton = button;
|
|
});
|
|
|
|
// Append the color button to the color buttons container
|
|
colorButtonsContainer.appendChild(button);
|
|
});
|
|
|
|
// Append the color buttons container to the color container
|
|
colorContainer.appendChild(colorButtonsContainer);
|
|
|
|
// Append the color container to the document body
|
|
document.body.appendChild(colorContainer);
|
|
|
|
// Create a container div for both buttons
|
|
const buttonsContainer = document.createElement('div');
|
|
buttonsContainer.style.position = 'absolute';
|
|
buttonsContainer.style.left = '20px';
|
|
buttonsContainer.style.top = '17%';
|
|
// buttonsContainer.style.left = `${window.innerWidth * 0.03}px`; // Position 5% from the left edge
|
|
document.body.appendChild(buttonsContainer);
|
|
|
|
// Create the Clear button
|
|
const clearButton = document.createElement('button');
|
|
clearButton.innerHTML ='<i class="fa fa-remove" style="font-size:30px"></i>';
|
|
clearButton.style.border = '3px solid blue';
|
|
// clearButton.textContent = 'Clear';
|
|
clearButton.style.color = 'blue';
|
|
// clearButton.style.color = 'white';
|
|
clearButton.style.marginRight = '10px';
|
|
clearButton.style.padding = '5px 10px';
|
|
clearButton.style.fontSize = '16px';
|
|
clearButton.style.fontWeight = 'bold';
|
|
clearButton.style.borderRadius = '50%';
|
|
clearButton.style.boxShadow = '5px 10px 30px #7c4c2390';
|
|
clearButton.addEventListener('click', () => {
|
|
clearDrawing();
|
|
});
|
|
|
|
// Create the Eraser button
|
|
const eraserButton = document.createElement('button');
|
|
// eraserButton.textContent = 'Eraser';
|
|
eraserButton.innerHTML = '<i class="fa fa-eraser" style="font-size:30px"></i>';
|
|
eraserButton.style.color = '#7c4c23';
|
|
eraserButton.style.border = '3px solid #7c4c23';
|
|
// eraserButton.style.color = 'white';
|
|
eraserButton.style.marginRight = '15px';
|
|
eraserButton.style.padding = '5px 5px';
|
|
eraserButton.style.fontSize = '16px';
|
|
eraserButton.style.fontWeight = 'bold';
|
|
eraserButton.style.borderRadius = '50%';
|
|
eraserButton.style.boxShadow = '5px 10px 15px #7c4c2390';
|
|
eraserButton.addEventListener('click', () => {
|
|
isErasing = !isErasing;
|
|
if (isErasing) {
|
|
// eraserButton.style.backgroundColor = 'red'; // Update eraser button color to indicate erasing mode
|
|
eraserButton.style.color = 'red';
|
|
} else {
|
|
// Return to drawing mode
|
|
// eraserButton.style.backgroundColor = 'green'; // Restore eraser button color
|
|
eraserButton.style.color = '#7c4c23';
|
|
}
|
|
});
|
|
|
|
// Add the Clear and Eraser buttons to the container
|
|
buttonsContainer.appendChild(clearButton);
|
|
buttonsContainer.appendChild(eraserButton);
|
|
|
|
const sliderContainer = document.createElement('div');
|
|
sliderContainer.className = 'slider-container';
|
|
sliderContainer.style.position = 'absolute';
|
|
sliderContainer.style.top = '25%';
|
|
sliderContainer.style.left = '100%';
|
|
|
|
// Create the slider
|
|
const slider = document.createElement('input');
|
|
slider.type = 'range';
|
|
slider.min = '2';
|
|
slider.max = '80';
|
|
slider.value = brushSize.toString();
|
|
slider.className = 'slider';
|
|
// slider.style.width = `${window.innerWidth / 2}px`;
|
|
|
|
slider.addEventListener('input', (event) => {
|
|
brushSize = parseInt(event.target.value);
|
|
slider.style.backgroundSize = `calc(${(brushSize - 2) * 100 / 18}% + 20px) 100%`;
|
|
});
|
|
|
|
sliderContainer.appendChild(slider);
|
|
buttonsContainer.appendChild(sliderContainer);
|
|
|
|
this.input.on('pointerdown', () => {
|
|
isDrawing = true;
|
|
startDrawing(this.input.x, this.input.y);
|
|
});
|
|
|
|
this.input.on('pointermove', () => {
|
|
if (isDrawing) {
|
|
continueDrawing(this.input.x, this.input.y);
|
|
}
|
|
});
|
|
this.input.on('pointerup', () => {
|
|
if (isDrawing) {
|
|
finishDrawing();
|
|
}
|
|
isDrawing = false;
|
|
});
|
|
customCursor = this.add.graphics();
|
|
|
|
// Disable the default cursor
|
|
this.input.setDefaultCursor('none');
|
|
|
|
|
|
const borderThickness = 2;
|
|
const borderColor = 0x000000; // Black color (you can customize this)
|
|
|
|
const borderGraphics = this.add.graphics();
|
|
borderGraphics.lineStyle(borderThickness, borderColor);
|
|
borderGraphics.strokeRect(drawingZone.x, drawingZone.y, drawingZone.width, drawingZone.height);
|
|
function continueDrawing(x, y) {
|
|
// Check if the pointer coordinates are within the drawing zone
|
|
if (
|
|
x >= drawingZone.x &&
|
|
x <= drawingZone.x + drawingZone.width &&
|
|
y >= drawingZone.y &&
|
|
y <= drawingZone.y + drawingZone.height
|
|
) {
|
|
// The pointer is within the drawing zone, so continue drawing
|
|
graphics.lineTo(x, y);
|
|
graphics.strokePath();
|
|
}
|
|
};
|
|
}
|
|
|
|
function startDrawing(x, y) {
|
|
if (!isErasing) {
|
|
graphics.lineStyle(brushSize * 2, Phaser.Display.Color.HexStringToColor(selectedColor).color);
|
|
} else {
|
|
graphics.lineStyle(brushSize * 2, 0xffffff, 1); // Set a white color to clear lines (full opacity)
|
|
}
|
|
graphics.beginPath();
|
|
graphics.moveTo(x, y);
|
|
|
|
}
|
|
|
|
function continueDrawing(x, y) {
|
|
if (!isErasing) {
|
|
graphics.lineTo(x, y); // Drawing
|
|
} else {
|
|
graphics.lineTo(x, y); // Erasing by drawing with a white line
|
|
}
|
|
graphics.strokePath();
|
|
}
|
|
|
|
function finishDrawing() {
|
|
// No need for additional actions here
|
|
}
|
|
|
|
function clearDrawing() {
|
|
graphics.clear();
|
|
}
|
|
|
|
function update() {
|
|
const slider = document.querySelector('input[type="range"]');
|
|
if (slider && !isDrawing) {
|
|
const sliderValue = parseInt(slider.value);
|
|
const max = parseInt(slider.max);
|
|
const width = slider.offsetWidth;
|
|
const offsetX = (sliderValue - 2) / (max - 2) * width;
|
|
slider.style.background = `linear-gradient(to right, #000 0%, #000 ${offsetX}px, #fff ${offsetX}px, #fff 100%)`;
|
|
};
|
|
const cursorSize = brushSize * cursorSizeMultiplier;
|
|
customCursor.clear(); // Clear the previous frame
|
|
customCursor.lineStyle(3, 0x000000); // Set the line style (2 is the line thickness, 0x000000 is black color)
|
|
customCursor.strokeCircle(0, 0, cursorSize);
|
|
// Position the cursor at the current mouse pointer coordinates
|
|
customCursor.x = this.input.x;
|
|
customCursor.y = this.input.y;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// const config = {
|
|
// type: Phaser.AUTO,
|
|
// width: window.innerWidth,
|
|
// height: window.innerHeight,
|
|
// backgroundColor: '#05b3a4',
|
|
// scale: {
|
|
// mode: Phaser.Scale.FIT,
|
|
// autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
|
|
// },
|
|
// scene: {
|
|
// preload: preload,
|
|
// create: create,
|
|
// update: update,
|
|
// },
|
|
// };
|
|
|
|
// const game = new Phaser.Game(config);
|
|
// const displayW = window.innerWidth;
|
|
// const displayH = window.innerHeight;
|
|
|
|
// let graphics;
|
|
// let outlineImage;
|
|
// let isDrawing = false;
|
|
// let selectedColor = '#ff0000'; // Default color
|
|
// let brushSize = 5; // Default brush size
|
|
|
|
// function preload() {
|
|
// this.load.image('outline', '/assets/cow.png');
|
|
// }
|
|
|
|
// function create() {
|
|
// outlineImage = this.add.image(displayW / 2, displayH / 2, 'outline');
|
|
|
|
// graphics = this.add.graphics();
|
|
|
|
// // Create a color picker using HTML input type color
|
|
// const colorPicker = document.createElement('input');
|
|
// colorPicker.type = 'color';
|
|
// colorPicker.value = selectedColor;
|
|
// colorPicker.className = 'color-picker';
|
|
// colorPicker.addEventListener('input', (event) => {
|
|
// selectedColor = event.target.value;
|
|
// });
|
|
// document.body.appendChild(colorPicker);
|
|
|
|
// // Create a brush size slider using HTML input type range
|
|
// const sliderContainer = document.createElement('div');
|
|
// sliderContainer.className = 'slider-container';
|
|
// document.body.appendChild(sliderContainer);
|
|
|
|
// const slider = document.createElement('input');
|
|
// slider.type = 'range';
|
|
// slider.min = '2';
|
|
// slider.max = '20';
|
|
// slider.value = brushSize.toString(); // Set initial value to brushSize
|
|
// slider.className = 'slider';
|
|
// sliderContainer.appendChild(slider);
|
|
|
|
// slider.addEventListener('input', (event) => {
|
|
// brushSize = parseInt(event.target.value);
|
|
// slider.style.backgroundSize = `calc(${(brushSize - 2) * 100 / 18}% + 20px) 100%`;
|
|
// });
|
|
|
|
// const clearButton = document.createElement('button');
|
|
// clearButton.textContent = 'Clear';
|
|
// clearButton.className = 'clear-button';
|
|
// clearButton.addEventListener('click', () => {
|
|
// clearDrawing();
|
|
// });
|
|
// document.body.appendChild(clearButton);
|
|
// this.input.on('pointerdown', () => {
|
|
// isDrawing = true;
|
|
// startDrawing(this.input.x, this.input.y);
|
|
// });
|
|
|
|
// this.input.on('pointermove', () => {
|
|
// if (isDrawing) {
|
|
// continueDrawing(this.input.x, this.input.y);
|
|
// }
|
|
// });
|
|
|
|
// this.input.on('pointerup', () => {
|
|
// if (isDrawing) {
|
|
// finishDrawing();
|
|
// }
|
|
// isDrawing = false;
|
|
// });
|
|
// }
|
|
// function startDrawing(x, y) {
|
|
// graphics.lineStyle(brushSize * 2, Phaser.Display.Color.HexStringToColor(selectedColor).color);
|
|
// graphics.beginPath();
|
|
// graphics.moveTo(x, y);
|
|
// }
|
|
|
|
// function continueDrawing(x, y) {
|
|
// graphics.lineTo(x, y);
|
|
// graphics.strokePath();
|
|
// }
|
|
|
|
// function finishDrawing() {
|
|
// // No need for additional actions here
|
|
// }
|
|
|
|
// function clearDrawing() {
|
|
// graphics.clear();
|
|
// }
|
|
|
|
// function update() {
|
|
// // Update the slider position based on the pointer's movement
|
|
// const slider = document.querySelector('input[type="range"]');
|
|
// if (slider && !isDrawing) {
|
|
// const sliderValue = parseInt(slider.value);
|
|
// const max = parseInt(slider.max);
|
|
// const width = slider.offsetWidth;
|
|
// const offsetX = (sliderValue - 2) / (max - 2) * width;
|
|
// slider.style.background = `linear-gradient(to right, #000 0%, #000 ${offsetX}px, #fff ${offsetX}px, #fff 100%)`;
|
|
// }
|
|
// }
|
|
|
|
// const config = {
|
|
// type: Phaser.AUTO,
|
|
// width: window.innerWidth,
|
|
// height: window.innerHeight,
|
|
// backgroundColor: '#05b3a4',
|
|
// scale: {
|
|
// mode: Phaser.Scale.FIT,
|
|
// autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
|
|
// },
|
|
// scene: {
|
|
// preload: preload,
|
|
// create: create,
|
|
// update: update
|
|
// }
|
|
// };
|
|
|
|
// const game = new Phaser.Game(config);
|
|
// const displayW = window.innerWidth;
|
|
// const displayH = window.innerHeight;
|
|
|
|
// let graphics;
|
|
// let outlineImage;
|
|
// let isDrawing = false;
|
|
// let selectedColor = 0xff0000; // Default color
|
|
// let brushSize = 5; // Default brush size
|
|
|
|
// function preload() {
|
|
// this.load.image('outline', '/assets/cow.png');
|
|
// }
|
|
|
|
// function create() {
|
|
// outlineImage = this.add.image(displayW / 2, displayH / 2, 'outline');
|
|
|
|
// graphics = this.add.graphics();
|
|
|
|
// // Create color palette buttons
|
|
// const colorPalette = [0xff0000, 0x00ff00, 0x0000ff]; // Example colors
|
|
|
|
// colorPalette.forEach((color, index) => {
|
|
// const button = this.add.rectangle(50 + index * 70, 500, 50, 50, color);
|
|
// button.setInteractive();
|
|
// button.on('pointerdown', () => {
|
|
// selectedColor = color;
|
|
// });
|
|
// });
|
|
|
|
// // Create a brush size slider using HTML input type range
|
|
// const sliderContainer = document.createElement('div');
|
|
// sliderContainer.className = 'slider-container';
|
|
// document.body.appendChild(sliderContainer);
|
|
|
|
// const slider = document.createElement('input');
|
|
// slider.type = 'range';
|
|
// slider.min = '2';
|
|
// slider.max = '20';
|
|
// slider.value = brushSize.toString(); // Set initial value to brushSize
|
|
// slider.className = 'slider';
|
|
// sliderContainer.appendChild(slider);
|
|
|
|
// slider.addEventListener('input', (event) => {
|
|
// brushSize = parseInt(event.target.value);
|
|
// slider.style.backgroundSize = `calc(${(brushSize - 2) * 100 / 18}% + 20px) 100%`;
|
|
// });
|
|
|
|
// const clearButton = document.createElement('button');
|
|
// clearButton.textContent = 'Clear';
|
|
// clearButton.className = 'clear-button';
|
|
// clearButton.addEventListener('click', () => {
|
|
// clearDrawing();
|
|
// });
|
|
// document.body.appendChild(clearButton);
|
|
|
|
// this.input.on('pointerdown', () => {
|
|
// isDrawing = true;
|
|
// startDrawing(this.input.x, this.input.y);
|
|
// });
|
|
|
|
// this.input.on('pointermove', () => {
|
|
// if (isDrawing) {
|
|
// continueDrawing(this.input.x, this.input.y);
|
|
// }
|
|
// });
|
|
|
|
// this.input.on('pointerup', () => {
|
|
// if (isDrawing) {
|
|
// finishDrawing();
|
|
// }
|
|
// isDrawing = false;
|
|
// });
|
|
// }
|
|
|
|
// function startDrawing(x, y) {
|
|
// graphics.lineStyle(brushSize * 2, selectedColor);
|
|
// graphics.beginPath();
|
|
// graphics.moveTo(x, y);
|
|
// }
|
|
|
|
// function continueDrawing(x, y) {
|
|
// graphics.lineTo(x, y);
|
|
// graphics.strokePath();
|
|
// }
|
|
|
|
// function finishDrawing() {
|
|
// // No need for additional actions here
|
|
// }
|
|
|
|
// function clearDrawing() {
|
|
// graphics.clear();
|
|
// }
|
|
|
|
// function update() {
|
|
// // Update the slider position based on the pointer's movement
|
|
// const slider = document.querySelector('input[type="range"]');
|
|
// if (slider && !isDrawing) {
|
|
// const sliderValue = parseInt(slider.value);
|
|
// const max = parseInt(slider.max);
|
|
// const width = slider.offsetWidth;
|
|
// const offsetX = (sliderValue - 2) / (max - 2) * width;
|
|
// slider.style.background = `linear-gradient(to right, #000 0%, #000 ${offsetX}px, #fff ${offsetX}px, #fff 100%)`;
|
|
// }
|
|
// }
|
|
</script>
|
|
<style>
|
|
.clear-button {
|
|
background-color: blue;
|
|
}
|
|
</style>
|