<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Advanced Drawing App</title>
<style>
canvas {
border: 2px solid #000;
cursor: crosshair;
}
#toolbar {
margin-bottom: 10px;
}
</style>
</head>
<body>
<div id="toolbar">
<label for="colorPicker">Color:</label>
<input type="color" id="colorPicker" value="#000">
<label for="thickness">Thickness:</label>
<input type="range" id="thickness" min="1" max="20" value="5">
<button id="pencil">Pencil</button>
<button id="line">Line</button>
<button id="rectangle">Rectangle</button>
<button id="circle">Circle</button>
<button id="undo">Undo</button>
<button id="redo">Redo</button>
<button id="clear">Clear</button>
</div>
<canvas id="drawingCanvas" width="800" height="600"></canvas>
<script>
const canvas = document.getElementById('drawingCanvas');
const context = canvas.getContext('2d');
let isDrawing = false;
let lastX = 0;
let lastY = 0;
let color = '#000';
let thickness = 5;
let isEraser = false;
let lines = [];
let currentLine = null;
function startDrawing(e) {
isDrawing = true;
[lastX, lastY] = [e.offsetX, e.offsetY];
currentLine = {
color,
thickness,
points: [{ x: lastX, y: lastY }]
};
}
function stopDrawing() {
isDrawing = false;
if (currentLine) {
lines.push(currentLine);
currentLine = null;
}
}
function draw(e) {
if (!isDrawing) return;
const x = e.offsetX;
const y = e.offsetY;
context.beginPath();
context.moveTo(lastX, lastY);
context.lineTo(x, y);
context.strokeStyle = isEraser ? '#fff' : color;
context.lineWidth = isEraser ? thickness * 2 : thickness;
context.lineCap = 'round';
context.stroke();
currentLine.points.push({ x, y });
[lastX, lastY] = [x, y];
}
function changeColor(e) {
color = e.target.value;
}
function changeThickness(e) {
thickness = e.target.value;
}
function toggleEraser() {
isEraser = !isEraser;
document.getElementById('pencil').textContent = isEraser ? 'Pencil' : 'Eraser';
}
function drawLine() {
isEraser = false;
document.getElementById('pencil').textContent = 'Pencil';
canvas.removeEventListener('mousedown', startDrawing);
canvas.removeEventListener('mousemove', draw);
canvas.removeEventListener('mouseup', stopDrawing);
canvas.removeEventListener('mouseout', stopDrawing);
canvas.addEventListener('mousedown', startDrawing);
canvas.addEventListener('mousemove', drawLinePreview);
canvas.addEventListener('mouseup', drawLineFinish);
canvas.addEventListener('mouseout', drawLineFinish);
}
function drawLinePreview(e) {
if (!isDrawing) return;
context.clearRect(0, 0, canvas.width, canvas.height);
context.beginPath();
context.moveTo(lastX, lastY);
context.lineTo(e.offsetX, e.offsetY);
context.strokeStyle = color;
context.lineWidth = thickness;
context.lineCap = 'round';
context.stroke();
}
function drawLineFinish(e) {
if (!isDrawing) return;
context.clearRect(0, 0, canvas.width, canvas.height);
draw(e);
canvas.removeEventListener('mousemove', drawLinePreview);
canvas.removeEventListener('mouseup', drawLineFinish);
canvas.removeEventListener('mouseout', drawLineFinish);
canvas.addEventListener('mousedown', startDrawing);
canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mouseup', stopDrawing);
canvas.addEventListener('mouseout', stopDrawing);
}
function drawRectangle() {
isEraser = false;
document.getElementById('pencil').textContent = 'Pencil';
canvas.removeEventListener('mousedown', startDrawing);
canvas.removeEventListener('mousemove', draw);
canvas.removeEventListener('mouseup', stopDrawing);
canvas.removeEventListener('mouseout', stopDrawing);
canvas.addEventListener('mousedown', startDrawing);
canvas.addEventListener('mousemove', drawRectanglePreview);
canvas.addEventListener('mouseup', drawRectangleFinish);
canvas.addEventListener('mouseout', drawRectangleFinish);
}
function drawRectanglePreview(e) {
if (!isDrawing) return;
context.clearRect(0, 0, canvas.width, canvas.height);
const width = e.offsetX - lastX;
const height = e.offsetY - lastY;
context.strokeRect(lastX, lastY, width, height);
}
function drawRectangleFinish(e) {
if (!isDrawing) return;
const width = e.offsetX - lastX;
const height = e.offsetY - lastY;
context.clearRect(0, 0, canvas.width, canvas.height);
context.strokeRect(lastX, lastY, width, height);
stopDrawing();
canvas.removeEventListener('mousemove', drawRectanglePreview);
canvas.removeEventListener('mouseup', drawRectangleFinish);
canvas.removeEventListener('mouseout', drawRectangleFinish);
canvas.addEventListener('mousedown', startDrawing);
canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mouseup', stopDrawing);
canvas.addEventListener('mouseout', stopDrawing);
}
function drawCircle() {
isEraser = false;
document.getElementById('pencil').textContent = 'Pencil';
canvas.removeEventListener('mousedown', startDrawing);
canvas.removeEventListener('mousemove', draw);
canvas.removeEventListener('mouseup', stopDrawing);
canvas.removeEventListener('mouseout', stopDrawing);
canvas.addEventListener('mousedown', startDrawing);
canvas.addEventListener('mousemove', drawCirclePreview);
canvas.addEventListener('mouseup', drawCircleFinish);
canvas.addEventListener('mouseout', drawCircleFinish);
}
function drawCirclePreview(e) {
if (!isDrawing) return;
context.clearRect(0, 0, canvas.width, canvas.height);
const radius = Math.sqrt(Math.pow(e.offsetX - lastX, 2) + Math.pow(e.offsetY - lastY, 2));
context.beginPath();
context.arc(lastX, lastY, radius, 0, Math.PI * 2);
context.stroke();
}
function drawCircleFinish(e) {
if (!isDrawing) return;
const radius = Math.sqrt(Math.pow(e.offsetX - lastX, 2) + Math.pow(e.offsetY - lastY, 2));
context.clearRect(0, 0, canvas.width, canvas.height);
context.beginPath();
context.arc(lastX, lastY, radius, 0, Math.PI * 2);
context.stroke();
stopDrawing();
canvas.removeEventListener('mousemove', drawCirclePreview);
canvas.removeEventListener('mouseup', drawCircleFinish);
canvas.removeEventListener('mouseout', drawCircleFinish);
canvas.addEventListener('mousedown', startDrawing);
canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mouseup', stopDrawing);
canvas.addEventListener('mouseout', stopDrawing);
}
function undo() {
lines.pop();
redraw();
}
function redo() {
// 未実装
}
function clearCanvas() {
context.clearRect(0, 0, canvas.width, canvas.height);
lines = [];
}
function redraw() {
clearCanvas();
lines.forEach(line => {
context.strokeStyle = line.color;
context.lineWidth = line.thickness;
context.beginPath();
context.moveTo(line.points[0].x, line.points[0].y);
line.points.forEach(point => context.lineTo(point.x, point.y));
context.stroke();
});
}
canvas.addEventListener('mousedown', startDrawing);
canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mouseup', stopDrawing);
canvas.addEventListener('mouseout', stopDrawing);
document.getElementById('colorPicker').addEventListener('change', changeColor);
document.getElementById('thickness').addEventListener('input', changeThickness);
document.getElementById('pencil').addEventListener('click', toggleEraser);
document.getElementById('line').addEventListener('click', drawLine);
document.getElementById('rectangle').addEventListener('click', drawRectangle);
document.getElementById('circle').addEventListener('click', drawCircle);
document.getElementById('undo').addEventListener('click', undo);
document.getElementById('redo').addEventListener('click', redo);
document.getElementById('clear').addEventListener('click', clearCanvas);
</script>
</body>
</html>