<!DOCTYPE HTML>
<HTML LANG="ja">
<HEAD>
<META CHARSET="Shift_JIS">
<TITLE>スタイルシート ルーレット</TITLE>
<STYLE TYPE="text/css">
<!--
/* 等速回転 */
@keyframes rotate {
from {
--theta1:0;
}
to {
--theta1:360;
}
}
/* 等速回転リセット */
@keyframes reset {
to {
--rotate:none;
}
}
/* 減速時間ランダム化 */
@keyframes decel {
from {
--decel:0;
}
to {
--decel:4;
}
}
/* 減速中 入力ディスエーブル */
@keyframes disable2 {
to {
--disable1-color:gray;
--disable1-pointer:none;
--disable2-color:gray;
--disable2-pointer:none;
}
}
/* 確定 */
@keyframes decided {
from, 25%, 50%, 75%, to {
--dec-vis:visible;
}
12.5%, 37.5%, 62.5%, 87.5% {
--dec-vis:hidden;
}
}
@property --theta1 {
syntax:'<number>';
inherits:true;
initial-value:0;
}
@property --theta2 {
syntax:'<number>';
inherits:true;
initial-value:0;
}
@property --decel {
syntax:'<integer>';
inherits:true;
initial-value:0;
}
@property --round {
syntax:'<integer>';
inherits:true;
initial-value:0;
}
body {
background-color:#CCFFFF;
}
#title {
color:#CC0000;
font-size:large;
font-weight:bold;
text-align:center;
}
#start, .stop {
display:none;
}
.disable1 {
color:var(--disable1-color);
pointer-events:var(--disable1-pointer);
accent-color:var(--disable1-color); /* Google Chrome で有効 */
}
#base1 {
text-align:center;
--disable1-color:canvastext;
--disable1-pointer:auto;
--disable2-color:black;
--disable2-pointer:auto;
/* 減速時間ランダム化 */
/* 減速時間を直接アニメーションしてランダム化したいところだが,アニメーションした
カスタム プロパティを他のアニメーションのパラメータに使うことはできない.
代わりに,減速時間を 5種類に限定し,5個のストップ ボタンに対応させて,ストップ
ボタンをランダムに選ぶようにする. */
animation:decel 1s steps(5, jump-none) infinite;
}
#base2 {
display:inline-block;
text-align:start;
user-select:none;
--dec-vis:hidden;
}
/* 選択肢数,選択肢 扇形クリップ用 */
/* 三角関数は実装されていない */
#n-2:checked ~ #reset #board {
--n:2;
--sector-clip:none;
}
#n-3:checked ~ #reset #board {
--n:3;
--sector-clip:polygon(0 120px, 122px -91.31px, 122px 331.31px);
}
#n-4:checked ~ #reset #board {
--n:4;
--sector-clip:polygon(0 120px, 122px -2px, 122px 242px);
}
#n-5:checked ~ #reset #board {
--n:5;
--sector-clip:polygon(0 120px, 122px 31.36px, 122px 208.64px);
}
#n-6:checked ~ #reset #board {
--n:6;
--sector-clip:polygon(0 120px, 122px 49.56px, 122px 190.44px);
}
#n-7:checked ~ #reset #board {
--n:7;
--sector-clip:polygon(0 120px, 122px 61.25px, 122px 178.75px);
}
#n-8:checked ~ #reset #board {
--n:8;
--sector-clip:polygon(0 120px, 122px 69.47px, 122px 170.53px);
}
#reset {
--rotate:rotate 3s linear infinite;
}
#board {
position:relative;
margin-top:12px;
text-align:center;
--sector-angle:calc(360 / var(--n));
--theta2:0;
animation:rotate 3s linear infinite paused; /* 等速回転停止 */
}
#rim {
display:inline-block;
position:relative;
width:240px;
height:240px;
background-color:black;
border-radius:120px;
}
#back {
position:absolute;
left:0;
top:0;
width:240px;
height:240px;
background-color:white;
clip-path:circle(118.5px at 120px 120px);
transform-origin:120px 120px;
transform:rotate(calc((var(--theta1) + var(--theta2)) * 1deg));
}
/* 選択肢 */
.choice {
position:absolute;
left:120px;
top:0;
width:119px;
height:240px;
padding:0 0 0 0.5em;
border-style:none;
outline:none;
text-align:center;
clip-path:var(--sector-clip);
transform-origin:0 120px;
}
#choice1 {
background-color:#FF9999;
}
#choice2 {
background-color:#99FF99;
transform:rotate(calc(var(--sector-angle) * -1deg));
}
#choice3 {
background-color:#FFFF99;
transform:rotate(calc(var(--sector-angle) * -2deg));
z-index:clamp(-1, var(--n) - 3, 0);
}
#choice4 {
background-color:#9999FF;
transform:rotate(calc(var(--sector-angle) * -3deg));
z-index:clamp(-1, var(--n) - 4, 0);
}
#choice5 {
background-color:#FF99FF;
transform:rotate(calc(var(--sector-angle) * -4deg));
z-index:clamp(-1, var(--n) - 5, 0);
}
#choice6 {
background-color:#99FFFF;
transform:rotate(calc(var(--sector-angle) * -5deg));
z-index:clamp(-1, var(--n) - 6, 0);
}
#choice7 {
background-color:#FFCC99;
transform:rotate(calc(var(--sector-angle) * -6deg));
z-index:clamp(-1, var(--n) - 7, 0);
}
#choice8 {
background-color:#99CCFF;
transform:rotate(calc(var(--sector-angle) * -7deg));
z-index:clamp(-1, var(--n) - 8, 0);
}
/* 選択肢フォーカス */
/* 対象の選択肢を水平にする/隠れないように visibility を上書きする */
:is(#choice1, #choice2, #choice3, #choice4, #choice5, #choice6, #choice7, #choice8):focus {
transform:rotate(calc((var(--theta1) + var(--theta2)) * -1deg));
visibility:visible;
}
/* 対象以外の選択肢を隠す */
/* 対象の選択肢は隠さないように :where で詳細度を下げている */
:where(#back):focus-within .choice {
visibility:hidden;
}
#back:focus-within {
background-color:gray;
}
/* 確定表示を隠す */
#board:focus-within {
--dec-vis:hidden;
}
#pointer {
position:absolute;
left:234px;
top:114px;
width:16px;
height:12px;
background-color:red;
clip-path:polygon(0 6px, 16px 0, 16px 12px);
}
#button {
position:relative;
margin-top:24px;
text-align:center;
}
#start-l {
position:absolute;
left:50%;
top:0;
transform:translateX(-50%);
color:var(--disable2-color);
pointer-events:var(--disable2-pointer);
visibility:visible;
}
.stop-l {
position:absolute;
left:50%;
top:0;
transform:translateX(-50%);
color:black;
visibility:hidden;
}
#start-l, .stop-l {
background-color:gainsboro;
padding:4px 8px;
border-radius:3px;
}
:is(#start-l, .stop-l):hover {
background-color:lightgray;
}
#stop-1-l {
z-index:calc(0 - min(var(--decel), 1));
}
/* abs() は実装されていない */
#stop-2-l {
--w:calc(var(--decel) - 1);
z-index:calc(0 - min(var(--w) * var(--w), 1));
}
#stop-3-l {
--w:calc(var(--decel) - 2);
z-index:calc(0 - min(var(--w) * var(--w), 1));
}
#stop-4-l {
--w:calc(var(--decel) - 3);
z-index:calc(0 - min(var(--w) * var(--w), 1));
}
#stop-5-l {
z-index:calc(max(var(--decel) - 3, 0) - 1);
}
/* スタート */
#start:checked ~ #base1 {
--disable1-color:gray;
--disable1-pointer:none;
animation-play-state:paused; /* 減速時間ランダム化停止 */
}
#start:checked ~ #base1 #reset {
animation:reset 1ms step-start; /* 等速回転リセット */
}
#start:checked ~ #base1 #board {
animation:var(--rotate); /* 等速回転 */
}
#start:checked ~ #base1 .stop-l {
visibility:visible;
}
#start:checked ~ #base1 #start-l {
visibility:hidden;
}
/* ストップ */
.stop:checked ~ #base1 #board {
/* 減速 */
--theta2:calc(var(--decel-t) * 60);
transition:--theta2 calc(var(--decel-t) * 1s) cubic-bezier(0.3333333, 0.6666667, 0.6666667, 1);
}
.stop:checked ~ #base1 #base2 {
animation:disable2 calc(var(--decel-t) * 1s + 1s) step-start, /* 減速中 入力ディスエーブル */
decided 1s steps(8, jump-end) calc(var(--decel-t) * 1s) forwards; /* 確定表示 */
}
#stop-1:checked ~ #base1 #base2 {
--decel-t:16;
}
#stop-2:checked ~ #base1 #base2 {
--decel-t:18;
}
#stop-3:checked ~ #base1 #base2 {
--decel-t:20;
}
#stop-4:checked ~ #base1 #base2 {
--decel-t:22;
}
#stop-5:checked ~ #base1 #base2 {
--decel-t:24;
}
/* 確定表示 */
#dec1, #dec2 {
visibility:var(--dec-vis);
transform-origin:0 120px;
--round:calc((var(--theta1) + var(--theta2)) / var(--sector-angle)); /* 四捨五入 */
transform:rotate(calc((var(--theta1) + var(--theta2) - var(--round) * var(--sector-angle)) * 1deg));
}
#dec1 {
position:absolute;
left:120px;
top:0;
width:120px;
height:240px;
clip-path:var(--sector-clip);
}
#dec1-2 {
position:absolute;
left:0;
top:-2px;
width:122px;
height:244px;
background-color:red;
clip-path:circle(121.5px at 0 122px);
}
#dec2 {
position:absolute;
left:120px;
top:0;
width:120px;
height:240px;
pointer-events:none;
}
#dec2-2, #dec2-3 {
position:absolute;
left:0;
top:119px;
width:121px;
height:2px;
background-color:red;
transform-origin:0 1px;
}
#dec2-2 {
transform:rotate(calc(var(--sector-angle) / 2 * -1deg));
}
#dec2-3 {
transform:rotate(calc(var(--sector-angle) / 2 * 1deg));
}
-->
</STYLE>
</HEAD>
<BODY>
<BR>
<DIV ID="title">スタイルシート ルーレット</DIV>
<BR>
<INPUT TYPE=RADIO NAME="button-g" ID="start">
<INPUT TYPE=RADIO NAME="button-g" ID="stop-1" CLASS="stop">
<INPUT TYPE=RADIO NAME="button-g" ID="stop-2" CLASS="stop">
<INPUT TYPE=RADIO NAME="button-g" ID="stop-3" CLASS="stop">
<INPUT TYPE=RADIO NAME="button-g" ID="stop-4" CLASS="stop">
<INPUT TYPE=RADIO NAME="button-g" ID="stop-5" CLASS="stop">
<DIV ID="base1">
<DIV ID="base2">
選択肢数<BR>
<INPUT TYPE=RADIO NAME="choices-g" ID="n-2" TABINDEX="-1" CLASS="disable1" CHECKED><LABEL FOR="n-2" CLASS="disable1">2個</LABEL>
<INPUT TYPE=RADIO NAME="choices-g" ID="n-3" TABINDEX="-1" CLASS="disable1"><LABEL FOR="n-3" CLASS="disable1">3個</LABEL>
<INPUT TYPE=RADIO NAME="choices-g" ID="n-4" TABINDEX="-1" CLASS="disable1"><LABEL FOR="n-4" CLASS="disable1">4個</LABEL>
<INPUT TYPE=RADIO NAME="choices-g" ID="n-5" TABINDEX="-1" CLASS="disable1"><LABEL FOR="n-5" CLASS="disable1">5個</LABEL>
<BR>
<INPUT TYPE=RADIO NAME="choices-g" ID="n-6" TABINDEX="-1" CLASS="disable1"><LABEL FOR="n-6" CLASS="disable1">6個</LABEL>
<INPUT TYPE=RADIO NAME="choices-g" ID="n-7" TABINDEX="-1" CLASS="disable1"><LABEL FOR="n-7" CLASS="disable1">7個</LABEL>
<INPUT TYPE=RADIO NAME="choices-g" ID="n-8" TABINDEX="-1" CLASS="disable1"><LABEL FOR="n-8" CLASS="disable1">8個</LABEL>
<BR>
<DIV ID="reset">
<DIV ID="board" CLASS="disable1">
<DIV ID="rim">
<DIV ID="dec1">
<DIV ID="dec1-2"></DIV>
</DIV>
<DIV ID="back">
<INPUT TYPE=TEXT ID="choice1" TABINDEX="-1" PLACEHOLDER="選択肢を入力" CLASS="choice">
<INPUT TYPE=TEXT ID="choice2" TABINDEX="-1" PLACEHOLDER="選択肢を入力" CLASS="choice">
<INPUT TYPE=TEXT ID="choice3" TABINDEX="-1" PLACEHOLDER="選択肢を入力" CLASS="choice">
<INPUT TYPE=TEXT ID="choice4" TABINDEX="-1" PLACEHOLDER="選択肢を入力" CLASS="choice">
<INPUT TYPE=TEXT ID="choice5" TABINDEX="-1" PLACEHOLDER="選択肢を入力" CLASS="choice">
<INPUT TYPE=TEXT ID="choice6" TABINDEX="-1" PLACEHOLDER="選択肢を入力" CLASS="choice">
<INPUT TYPE=TEXT ID="choice7" TABINDEX="-1" PLACEHOLDER="選択肢を入力" CLASS="choice">
<INPUT TYPE=TEXT ID="choice8" TABINDEX="-1" PLACEHOLDER="選択肢を入力" CLASS="choice">
</DIV>
</DIV>
<DIV ID="dec2">
<DIV ID="dec2-2"></DIV>
<DIV ID="dec2-3"></DIV>
</DIV>
<DIV ID="pointer"></DIV>
</DIV>
</DIV>
<DIV ID="button">
<LABEL ID="start-l" FOR="start">スタート</LABEL>
<LABEL ID="stop-1-l" FOR="stop-1" CLASS="stop-l">ストップ</LABEL>
<LABEL ID="stop-2-l" FOR="stop-2" CLASS="stop-l">ストップ</LABEL>
<LABEL ID="stop-3-l" FOR="stop-3" CLASS="stop-l">ストップ</LABEL>
<LABEL ID="stop-4-l" FOR="stop-4" CLASS="stop-l">ストップ</LABEL>
<LABEL ID="stop-5-l" FOR="stop-5" CLASS="stop-l">ストップ</LABEL>
</DIV>
</DIV>
</DIV>
</BODY>
</HTML>
|