
回転ルーレットを作る JavaScript + canvas
2019-01-1718 min read
目次
概要
JavaScriptとcanvasで回転するルーレットを作りました。
Runボタンを押すと回転開始。stopボタンを押すと減速を始め、数秒後に停止します。 ライブラリとかは使っていません。
デモ
まずはデモをみてください。
簡単な解説
ソースコード上のポイントを簡単に説明します。 サンプルソースが汚いのはご容赦ください。
扇型の描画
デモにもあるようにこの円盤は複数の扇型図形を並べて描画しています。 この扇型はCanvas API の CanvasRenderingContext2D.arc()で描画されています。
context.beginPath();
context.moveTo(150, 150)
context.fillStyle = "#f3f3f3";
context.arc(150, 150, 100, 0 * Math.PI / 180, 45 * Math.PI / 180, true);
context.fill();
ここでmoveToメソッドで始点を与えることで扇型を描画することができます。
サンプルソースはデモの座標と同じように(150, 150)を中心とし、半径が100で、0度から45度の扇型を描画します。
扇型の描画に関する解説はこちらにも掲載しています。
https://tech-blog.s-yoshiki.com/2019/01/1037/
減速
イベント開始と同時に setInterval関数を用いて、0.01秒ごとに円の角度をずらしながら繰り返し描画しています。
ストップボタンが押されたら回転速度が徐々に下がるようになっています。 減速のロジック自体はy = a / x のような簡単な反比例の式を使って実装しています。
ソース
const canvas = document.getElementById("canvas")
const context = canvas.getContext('2d');
var center = {
x: 150,
y: 150
}
var radius = 100
var data = [{
name: "label1",
color: '#FFCEBE',
weight: 1
},
{
name: "label2",
color: '#CEFFBE',
weight: 1
},
{
name: "label3",
color: '#CEBEFF',
weight: 1
},
{
name: "label4",
color: '#FDED9E',
weight: 1
}
]
var sum_weight = 0
var unit_weight = 0
var stopFlag = false;
var startFlag = false;
//
// メイン処理
//
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 count = 1; //終了までのカウント
var lastCell = "";
var deg_counter = 0 // 角度のカウント
var acceleration = 1
var timer = setInterval(function() {
deg_counter += acceleration
if (stopFlag) {
count++;
}
if (count < 1000) {
acceleration = 1000 / (count)
drawRoullet(deg_counter);
} else {
count = 0;
clearInterval(timer);
endEvent();
}
}, 10);
var endEvent = function() {
count++;
var id = setTimeout(endEvent, 115);
if (count > 9) {
clearTimeout(id);
startFlag = false;
stopFlag = false;
var current_deg = Math.ceil(deg_counter % 360)
var sum = 0
for (var i = 0; i < data.length; i++) {
if (unit_weight * sum < current_deg && current_deg < unit_weight * (sum + data[i].weight)) {
document.getElementById("debug").innerHTML = data[i].name
break
}
sum += data[i].weight
}
}
};
}
document.getElementById("run").addEventListener("click", function() {
// スタート連打を無効化
if (startFlag === false) {
runRoullet();
startFlag = true;
} else {
startFlag = false;
}
});
document.getElementById("stop").addEventListener("click", function() {
if (startFlag) {
stopFlag = true;
}
});
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.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();
}
Recommends
回転ルーレットを作る JavaScript + canvas
2019-01-17
async awaitで画像を読み込み canvasに描画 JavaScript
2019-06-23
JavaScriptで画像のヒストグラムの正規化
2019-06-10
【JavaScript】凸包(グラハムスキャン)を可視化・アニメーション【Canvas】
2018-06-21
【JavaScript】凸包(ギフト包装法)を可視化・アニメーション【Canvas】
2018-06-16
【JavaScript】K-meansをアニメーション・可視化したら蜘蛛みたいな動きをした...
2018-06-10
FileAPIで画像を読み込み canvasに描画
2018-01-22
Firebase + Nuxt で認証付きページを作るときに参考にしたいところ
2020-03-23
MonacoEditor + Vue を使ってエディタを実装
2019-06-23
画像のヒストグラムを表示する Chart.js JavaScript canvas
2019-05-26
画像のプーリング処理 canvas + JavaScript
2019-05-19
JSで画像をまとめて読み込む(プリロードする)
2019-05-06
画像の減色処理 サンプルコードとデモ JavaScript + canvas
2019-04-10
画像のHSV変換 JavaScript + canvas
2019-04-08
大津の二値化で画像を2値化 JavaScript + canvas 【画像処理】
2019-04-07
New Posts
Amazon S3 でライフサイクルポリシーを設定する
2022-06-19
AWS Certified Developer Associate に合格した
2022-01-01
Fisher-Yates shuffleで配列シャッフル [js/ts/php]
2022-06-19
JavaScriptでUTF-16コードを文字列に変換
2022-06-18
[JS]乱数でランダムな整数を生成する
2022-06-18
[JS]BigIntでMathが使えない件
2022-06-12
AWS SAPに合格しました
2022-06-11
[AWS]DataSync/Storage Gateway/Transfer Family...
2022-05-29
[AWS CDK]ECS FargateでNestJSで作成したRESTfull APIデ...
2022-05-24
[AWS CDK]S3 CloudFront OAI Route53 構成 で NextJ...
2022-05-23
[CDK]SNS+SQS+DynamoDBでBounceとComplaint情報を収集する...
2022-04-11
[AmazonSES] node.js と ejs を利用してEメールを送信する
2022-04-09
GatsbyからNext.jsへのサイト移行
2022-04-04
[AWS CDK] Lambda で S3 オブジェクトを読み書きするStackの構築
2022-03-18
[AWS CDK] S3 + CloudFrontの構築とOriginAccessIden...
2022-03-09
Hot posts!
Proxy環境下でcurlを実行する
2019-12-07
OpenCVのMatのタイプ一覧表
2018-11-25
Macでも利用できるDBクライアント MySQL PostgreSQL Oracle など
2019-12-21
TablePlusを使ってみる。シンプルでモダンなSQLクライアントツール
2018-09-30
DBクライアントツールはDBeaverをおすすめしたい
2021-03-08
AWS S3のアクセスキーIDとシークレットアクセスキーの取得 作業用ユーザを作成
2019-06-12
AtCoderで初めて色がつくまでの話(茶色) レートが中々上がらなかった原因
2018-11-25
CentOS8でEPELとPowerToolsリポジトリの有効化
2020-11-30
Macでターミナルからポートスキャンを行う方法。
2018-12-09
Python + OpenCVのfillConvexPolyで複雑なポリゴンを描画する
2018-11-27
Date
▶︎
2022 年 (31)
▶︎
2021 年 (40)
▶︎
2020 年 (30)
▶︎
2019 年 (90)
▶︎
2018 年 (89)
▶︎
2017 年 (1)
Tags
Author