こんにちは〜ららぽてすらです♪
今回は、ルーレットの作り方について詳しく解説していきます!
HTML部分:
html
<h2>ルーレット</h2>
<p><canvas id="canvas"></canvas></p>
<div id="labels"></div>
<p><button id="run">スタート</button> <button id="stop">ストップ</button></p>
この部分は、ページに表示されるHTMLのエレメントを定義しています。 <h2>でページのタイトル、<canvas>で描画するための領域を確保し、 <div>でルーレットの各部分を表すラベルを表示するための領域を確保しています。 <p>で2つのボタンを定義し、それぞれルーレットの開始と停止の動作を制御します。
JavaScript部分:
- const canvas = document.getElementById('canvas'); const context = canvas.getContext('2d');
ここで、canvas要素を取得し、2D描画コンテキストを取得しています。 - var center = { x: 150, y: 150 }; var radius = 100;
ここでは、円の中心座標と半径を定義しています。 - var data = [...]
ここで、ルーレットの各セグメントに対応するデータを定義します。それぞれの名前、色、そして"weight"(このセグメントがルーレットの全体のうち何割を占めるか)が設定されています。 - data.forEach(e => { sum_weight += e.weight; }); unit_weight = 360 / sum_weight;
ここで、全てのセグメントのweightの合計を計算し、それをもとに1単位のweightが何度分に相当するかを計算します。 - init(); showLabel(); drawRoullet(0);
ここで、描画の初期化、ラベルの表示、そしてルーレットの初期描画を行っています。 - function drawRoullet(offset) {...}
これはルーレットの描画を行う関数です。オフセットを引数として受け取り、それをもとにルーレットの各セグメントを描画します。 - function runRoullet() {...}
これはルーレットを動かす関数です。速度と加速度を使ってルーレットの動きをシミュレートしています。 - function endEvent(deg) {...}
これはルーレットが停止した時の動作を定義した関数です。ルーレットが指しているセグメントを計算し、その結果を表示します。 - function init() {...}
これは描画の初期化を行う関数です。 - function drawPie(cx, cy, start_deg, end_deg, radius, color) {...}
これは円の一部(セグメント)を描画する関数です。 - function showLabel() {...}
これはルーレットの各セグメントのラベルを表示する関数です。 - function showArrow() {...}
これはルーレットの矢印を表示する関数です。 - document.getElementById('run').addEventListener('click', function() {...});
ここで、スタートボタンがクリックされたときの動作を定義しています。 - document.getElementById('stop').addEventListener('click', function() {...});
ここで、ストップボタンがクリックされたときの動作を定義しています。 - init():
- canvasのサイズを設定し、白色で初期化する関数です。
- drawPie(cx, cy, start_deg, end_deg, radius, color):
- canvas上に色つきの円の一部(つまり「パイ」)を描画する関数です。中心の位置 (cx, cy)、開始角度と終了角度(start_degとend_deg)、半径(radius)、色(color)を指定します。
- showLabel():
- ルーレットの各セグメントのラベル(つまり、エメラルド、ルビー、ダイヤモンド、サファイア)をHTMLテーブルとして生成し、labelsというIDのdiv要素に挿入します。
- showArrow():
- ルーレットの上部に矢印を描画します。これは現在選択されているルーレットセクションを示します。
- document.getElementById('run').addEventListener('click', function() {...}):
- "run"というIDの要素(スタートボタン)がクリックされたときにrunRoullet()関数を実行します。しかし、これは既にルーレットが開始(startFlagがtrue)または停止(stopFlagがtrue)している場合は動作しません。
- document.getElementById('stop').addEventListener('click', function() {...}):
- "stop"というIDの要素(ストップボタン)がクリックされたときにルーレットの停止を開始します。しかし、これはルーレットが既に開始されていて(startFlagがtrue)、まだ停止していない(stopFlagがfalse)場合にのみ動作します。
- runRoullet():
- ルーレットを回転させるための関数です。加速度を使ってルーレットが回転する度数を計算します。もしstopFlagがtrueになった場合(つまり、ストップボタンがクリックされた場合)、ルーレットの速度を徐々に減速させます。速度が0になると、タイマーをクリアし、endEvent(deg)関数を呼び出します。
- endEvent(deg):
- ルーレットが停止したときに呼び出される関数です。ルーレットが指しているセグメントを計算し、その結果を表示します。また、startFlagとstopFlagをfalseにリセットします。
⭐️ルーレットソースコード⭐️
<p> </p>
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
background-color: #f4f4f4;
}
canvas {
border: 2px solid #333;
border-radius: 5px;
margin-top: 15px;
}
button {
margin-top: 15px;
padding: 10px 20px;
font-size: 16px;
border: none;
border-radius: 5px;
cursor: pointer;
}
#run {
background-color: #4CAF50;
color: white;
}
#stop {
background-color: #f44336;
color: white;
}
</style>
<h2>ジュエリーデザインルーレット</h2>
<p><canvas id="canvas"></canvas></p>
<div id="labels"></div>
<p><button id="run">スタート</button> <button id="stop">ストップ</button></p>
<p>
<script>
const canvas = document.getElementById('canvas');
const context = canvas.getContext('2d');
var center = {
x: 150,
y: 150,
};
var radius = 100;
var data = [{
name: 'エメラルド',
color: '#50C878',
weight: 1,
}, {
name: 'ルビー',
color: '#E0115F',
weight: 1,
}, {
name: 'ダイヤモンド',
color: '#B9F2FF',
weight: 1,
}, {
name: 'サファイア',
color: '#0F52BA',
weight: 1,
}];
var sum_weight = 0;
var unit_weight = 0;
var stopFlag = false;
var startFlag = false;
var timer;
data.forEach(e => {
sum_weight += e.weight;
});
unit_weight = 360 / sum_weight;
init();
showLabel();
drawRoullet(0);
function drawRoullet(offset) {
var uw_count = offset;
data.forEach(e => {
drawPie(
center.x,
center.y,
uw_count,
uw_count + unit_weight,
radius,
e.color
);
uw_count += unit_weight;
});
}
function runRoullet() {
var deg = 0;
var speed = 0;
var acceleration = 0.5;
timer = setInterval(function() {
speed += acceleration;
deg += speed;
if (deg > 360) {
deg = deg % 360;
}
if (stopFlag) {
acceleration = -0.1;
speed += acceleration;
if (speed <= 0) {
clearInterval(timer);
endEvent(deg);
}
}
context.clearRect(0, 0, canvas.width, canvas.height);
drawRoullet(deg);
}, 100);
}
function endEvent(deg) {
var res = '';
var c = deg % 360;
for (var i = 0; i < data.length; i++) {
if (unit_weight * i <= c && c < unit_weight * (i + 1)) {
res = data[i].name;
break;
}
}
startFlag = false;
stopFlag = false;
}
function init() {
canvas.width = 300;
canvas.height = 300;
var dst = context.createImageData(canvas.width, canvas.height);
for (var i = 0; i < dst.data.length; i++) {
dst.data[i] = 255;
}
context.putImageData(dst, 0, 0);
}
function drawPie(cx, cy, start_deg, end_deg, radius, color) {
var _start_deg = (360 - start_deg) * Math.PI / 180;
var _end_deg = (360 - end_deg) * Math.PI / 180;
context.beginPath();
context.moveTo(cx, cy);
context.fillStyle = color;
context.arc(cx, cy, radius, _start_deg, _end_deg, true);
context.closePath();
context.lineWidth = 2;
context.strokeStyle = '#000';
context.stroke();
context.fill();
showArrow();
}
function showLabel() {
var label_el = document.getElementById('labels');
var text = '<table>';
for (var i = 0; i < data.length; i++) {
text += `<tr>
<td style="width:20px;background-color:${data[i].color};"></td>
<td>${data[i].name}</td>
</tr>`;
}
text += '</table>';
label_el.innerHTML = text;
}
function showArrow() {
context.beginPath();
context.moveTo(center.x, center.y - radius);
context.lineTo(center.x + 10, center.y - radius - 10);
context.lineTo(center.x - 10, center.y - radius - 10);
context.closePath();
context.stroke();
context.fillStyle = 'rgba(40,40,40)';
context.fill();
}
document.getElementById('run').addEventListener('click', function() {
if (!startFlag && !stopFlag) {
runRoullet();
startFlag = true;
}
});
document.getElementById('stop').addEventListener('click', function() {
if (startFlag && !stopFlag) {
stopFlag = true;
}
});
</script>
</p>
⬇️実際にソース入れた際の表示と動き⬇️
ルーレット
有機 あずき美人茶 ペットボトル 500mL 12本セット【送料無料】【有機JAS認定】 価格:3,240円 |
《2000円クーポン配布中》 ヤ−マン アセチノ5Dデザイニングクリーム 35g ボディクリーム 美容クリーム スキンケア アセチノクリーム アセチノ美容クリーム 価格:3,980円 |