イメージ
コーディング単価
1ページ: 5万円
コード
ディレクトリ構成
MySlotMachine
├ css
│ └ style.css
├ js
│ └ main.js
├ img
│ ├ inu.png
│ ├ neko.png
│ └ usagi.png
└ index.html
HTML(index.html)
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Slot Machine</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<main></main>
<div id="spin">SPIN</div>
<script src="js/main.js"></script>
</body>
</html>
CSS(style.css)
@charset "utf-8";
body {
background: #bdc3c7;
font-size: 16px;
font-weight: bold;
font-family: Arial, sans-serif;
}
main {
width: 300px;
background: #ecf0f1;
padding: 20px;
border: 4px solid #fff;
border-radius: 12px;
margin: 16px auto;
display: flex;
justify-content: space-between;
}
.panel img {
width: 90px;
height: 110px;
margin-bottom: 4px;
}
.stop {
cursor: pointer;
width: 90px;
height: 32px;
background: #ef454a;
box-shadow: 0 4px 0 #d1483e;
border-radius: 16px;
line-height: 32px;
text-align: center;
font-size: 14px;
color: #fff;
user-select: none;
}
#spin {
cursor: pointer;
width: 280px;
height: 36px;
background: #3498db;
box-shadow: 0 4px 0 #2880b9;
border-radius: 18px;
line-height: 36px;
text-align: center;
color: #fff;
user-select: none;
margin: 0 auto;
}
.unmatched {
opacity: 0.5;
}
.inactive {
opacity: 0.5;
}
JavaScript(main.js)
'use strict';
{
class Panel {
constructor () {
const section = document.createElement('section');
section.classList.add('panel');
this.img = document.createElement('img');
this.img.src = this.getRandomImage();
this.timeoutId = undefined;
this.stop = document.createElement('div');
this.stop.textContent = 'STOP';
this.stop.classList.add('stop', 'inactive');
this.stop.addEventListener('click', () => {
if (this.stop.classList.contains('inactive')) {
return;
}
this.stop.classList.add('inactive');
clearTimeout(this.timeoutId);
panelsLeft--;
if (panelsLeft === 0) {
spin.classList.remove('inactive');
panelsLeft = 3;
checkResult();
}
});
section.appendChild(this.img);
section.appendChild(this.stop);
const main = document.querySelector('main');
main.appendChild(section);
}
getRandomImage() {
const images = [
'myimg/usagi.png',
'myimg/neko.png',
'myimg/inu.png',
];
return images[Math.floor(Math.random() * images.length)];
}
spin() {
this.img.src = this.getRandomImage();
this.timeoutId = setTimeout(() => {
this.spin();
}, 50);
}
isUnmatched(p1, p2) {
return this.img.src !== p1.img.src && this.img.src !== p2.img.src;
}
unmatch() {
this.img.classList.add('unmatched');
}
activate() {
this.img.classList.remove('unmatched');
this.stop.classList.remove('inactive');
}
}
function checkResult() {
if (panels[0].isUnmatched(panels[1], panels[2])) {
panels[0].unmatch();
}
if (panels[1].isUnmatched(panels[0], panels[2])) {
panels[1].unmatch();
}
if (panels[2].isUnmatched(panels[0], panels[1])) {
panels[2].unmatch();
}
}
const panels = [
new Panel(),
new Panel(),
new Panel(),
];
let panelsLeft = 3;
const spin = document.getElementById('spin');
spin.addEventListener('click', () => {
if (spin.classList.contains('inactive')) {
return;
}
spin.classList.add('inactive');
panels.forEach(panel => {
panel.activate();
panel.spin();
});
});
}
コメント