<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ドット絵アプリ</title>
<style>
.container {
display: flex;
flex-direction: column;
align-items: center;
}
.canvas {
border: solid 1px black;
background-color: white;
margin: 20px;
}
.color-picker {
display: flex;
flex-wrap: wrap;
justify-content: center;
margin: 10px;
}
.color-choice {
width: 30px;
height: 30px;
cursor: pointer;
margin: 5px;
border: solid 1px black;
}
.message {
margin: 10px;
font-size: 18px;
font-weight: bold;
color: red;
display: none;
}
</style>
</head>
<body>
<div class="container">
<div class="canvas"></div>
<div class="color-picker">
<div class="color-choice" style="background-color: black;"></div>
<div class="color-choice" style="background-color: white;"></div>
<div class="color-choice" style="background-color: red;"></div>
<div class="color-choice" style="background-color: blue;"></div>
<div class="color-choice" style="background-color: green;"></div>
<div class="color-choice" style="background-color: yellow;"></div>
<div class="color-choice" style="background-color: orange;"></div>
<div class="color-choice" style="background-color: purple;"></div>
<div class="color-choice" style="background-color: pink;"></div>
<div class="color-choice" style="background-color: brown;"></div>
</div>
<button onclick="save()">保存</button>
<div class="message"></div>
</div>
<script>
// Canvasの要素
const canvas = document.querySelector('.canvas');
// Canvasのコンテキスト
const context = canvas.getContext('2d');
// ピクセルの一辺の長さ
const CELL_SIZE = 10;
// カラーの選択肢
const colors = [
'black',
'white',
'red',
'blue',
'green',
'yellow',
'orange',
'purple',
'pink',
'brown'
];
// 選択中のカラー
let selectedColor = colors[0];
// メッセージの要素
const message = document.querySelector('.message');
// Canvasを初期化する
function initCanvas(width, height) {
canvas.width = CELL_SIZE * width;
canvas.height = CELL_SIZE * height;
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
context.fillStyle = 'white';
context.fillRect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE);
context.strokeStyle = 'black';
context.strokeRect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE);
}
}
}
// カラーを選択する
function selectColor(color) {
selectedColor = color;
const colorChoices = document.querySelectorAll('.color-choice');
colorChoices.forEach(colorChoice => {
if (colorChoice.style.backgroundColor === color) {
colorChoice.classList.add('selected');
} else {
colorChoice.classList.remove('selected');
}
});
}
// Canvas内の位置を取得する
function getPosition(event) {
const rect = canvas.getBoundingClientRect();
const x = Math.floor((event.clientX - rect.left) / CELL_SIZE);
const y = Math.floor((event.clientY - rect.top) / CELL_SIZE);
return {x: x, y: y};
}
// マウスが押されたときの処理
function handleMouseDown(event) {
const pos = getPosition(event);
context.fillStyle = selectedColor;
context.fillRect(pos.x * CELL_SIZE, pos.y * CELL_SIZE, CELL_SIZE, CELL_SIZE);
}
// 保存する
function save() {
const image = canvas.toDataURL();
// ジョーク
// 保存している画像が本当にドット絵だった場合のみ保存する
if (image.indexOf('image/png') !== -1 && image.indexOf('base64,iVBORw0KGgoAAA') !== -1) {
window.location.href = image;
} else {
message.textContent = 'ドット絵ではありません。もう一度描いてください。';
message.style.display = 'block';
}
}
// 初期化する
function init() {
initCanvas(20, 20);
const colorChoices = document.querySelectorAll('.color-choice');
colorChoices.forEach(colorChoice => {
colorChoice.addEventListener('click', () => {
const color = colorChoice.style.backgroundColor;
selectColor(color);
});
});
canvas.addEventListener('mousedown', handleMouseDown);
}
init();
</script>
</body>
</html>