├── index.html ├── no_tutorial.html ├── style.css └── main.js /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 200色の白から見つけよう! - White 200 12 | 13 | 14 |
15 |
16 |

White 200

17 |
18 |
19 |

この白を探せ!
#xxxxxx

20 |
21 |
22 |
23 |

この色を、下の200色の白から選んでください!

24 |

お手つきすると、正解との差に応じてスコアが減ります。

25 |

外したマスには、正解色の斜線が付きます。

26 |

2回同じお手つきすると、はずれ表示の [ ]内の数で教えてくれます。

27 |
28 |
29 | 30 |
31 | 32 |
33 |

Time
00.00

34 |
35 |
36 |

Score:0

37 |

Try: 0

38 |
39 | 40 |
41 | 42 | 43 |
44 | 45 | 48 |
49 | 50 | スタート! 51 | Start! 52 |
53 | 83 |
84 |
85 |
86 |
87 |
88 | 89 | -------------------------------------------------------------------------------- /no_tutorial.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 200色の白から見つけよう! - White 200 12 | 13 | 14 |
15 |
16 |

White 200

17 |
18 |
19 |

この白を探せ!
#xxxxxx

20 |
21 |
22 |
23 |

この色を、下の200色の白から選んでください!

24 |

お手つきすると、正解との差に応じてスコアが減ります。

25 |

外したマスには、正解色の斜線が付きます。

26 |

2回同じお手つきすると、はずれ表示の [ ]内の数で教えてくれます。

27 |
28 |
29 | 30 |
31 | 32 |
33 |

Time
00.00

34 |
35 |
36 |

Score:0

37 |

Try: 0

38 |
39 | 40 |
41 | 42 | 43 |
44 | 45 | 48 |
49 | 50 | スタート! 51 | Start! 52 |
53 | 83 |
84 |
85 |
86 |
87 |
88 | 89 | 90 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 50px; /* ヘッダーの後ろに要素が隠れないようにするため */ 3 | } 4 | 5 | header { 6 | width: 100%; /* 幅いっぱいを指定 */ 7 | height: 50px; /* 高さを50pxに指定 */ 8 | background: #fff; /* 背景色にwhiteを指定 */ 9 | padding: 8px 20px; /* ヘッダーに上下左右それぞれ余白を指定 */ 10 | box-sizing: border-box; /* padding分を含んで幅を100%にするため */ 11 | position: fixed; /* ウィンドウを基準に画面に固定 */ 12 | top: 0; /* 上下の固定位置を上から0pxにする */ 13 | left: 0; /* 左右の固定位置を左から0pxにする */ 14 | display: flex; /* 中の要素を横並びにする */ 15 | align-items: center; /* 中の要素を上下中央に並べる */ 16 | border-bottom: solid; 17 | border-width: 2px; 18 | border-color: #000000; 19 | box-shadow: 0 1px 5px 2px rgba(0,0,0,0.15); 20 | } 21 | main { 22 | /* height: 50vw; /*スクロールの演出を見れるようにmainに高さを指定 */ 23 | } 24 | 25 | .start_btn { 26 | width: 200px; 27 | height: 120px; 28 | float: left; 29 | font-size: 200%; 30 | margin: 2px; 31 | border: solid; 32 | border-color: #d3d2d2; 33 | border-radius: 8px; 34 | background-color: #eb6100; 35 | color: #fff; 36 | position: absolute; 37 | top: 50vh; 38 | left: 50%; 39 | transform: translate(-50%, -50%); 40 | -webkit-transform: translate(-50%, -50%); 41 | -ms-transform: translate(-50%, -50%); 42 | text-align:center; 43 | line-height:120px; 44 | -webkit-box-shadow: 0 3px 5px rgba(0, 0, 0, .3); 45 | box-shadow: 0 3px 5px rgba(0, 0, 0, .3); 46 | } 47 | .start_btn:hover { 48 | background: #f56500; 49 | } 50 | 51 | #problem_text { 52 | text-align:center; 53 | } 54 | 55 | #problem_color_box { 56 | height:40px; 57 | margin: 2px; 58 | border: solid; 59 | border-width: 1px; 60 | border-color: #aeaeaeae; 61 | border-radius: 8px; 62 | text-align:center; 63 | line-height:30px; 64 | 65 | position: relative; 66 | cursor: pointer; 67 | display: inline-block; 68 | } 69 | 70 | .alternatives{ 71 | width: min(70px, calc(16.66666% - 5px)); 72 | height: 50px; 73 | float: left; 74 | margin: 1.5px; 75 | border: solid; 76 | border-width: 1px; 77 | border-color: #aeaeaeae; 78 | border-radius: 8px; 79 | } 80 | 81 | .opened { 82 | background-image: linear-gradient(to left top, #ffffff00 49%, #ddd 50%, #ffffff00 51%); 83 | } 84 | 85 | .description_bottom { 86 | display: none; 87 | position: absolute; 88 | padding: 10px; 89 | font-size: 12px; 90 | line-height: 1.6em; 91 | color: #fff; 92 | border-radius: 5px; 93 | background: #000; 94 | width: 140px; 95 | text-align:left; 96 | } 97 | .description_bottom:before { 98 | content: ""; 99 | position: absolute; 100 | top: -24px; 101 | right: 60%; 102 | border: 15px solid transparent; 103 | border-top: 15px solid #000; 104 | margin-left: -15px; 105 | transform: rotateZ(180deg); 106 | } 107 | #problem_color_box:hover .description_bottom{ 108 | display: inline-block; 109 | top: 50px; 110 | left: 0px; 111 | } 112 | 113 | #modal_hazure{ 114 | width: 120px; 115 | height: 50px; 116 | position: absolute; 117 | background-color: #323232; 118 | top: -60%; 119 | left: max(270px, 50%); 120 | transform: translate(-50%, -50%); 121 | -webkit-transform: translate(-50%, -50%); 122 | -ms-transform: translate(-50%, -50%); 123 | border-radius: 8px; 124 | text-align:center; 125 | color: #ffffff; 126 | } 127 | 128 | #hazure_text{ 129 | margin: 3px; 130 | } 131 | 132 | .hazure_anim { 133 | animation: key1 4s ease alternate; 134 | animation-fill-mode: forwards; 135 | } 136 | 137 | .hazure_neutral { 138 | transform: translate(-50%, -60%); 139 | } 140 | 141 | @keyframes key1 { 142 | 0% { 143 | transform: translate(-50%, -60%); 144 | } 145 | 10% { 146 | transform: translate(-50%, 70%); 147 | } 148 | 90% { 149 | transform: translate(-50%, 70%); 150 | } 151 | 100% { 152 | transform: translate(-50%, -60%); 153 | } 154 | } 155 | 156 | .point_time_text{ 157 | margin: 2px; 158 | height: 45%; 159 | } 160 | 161 | 162 | #modal_ac { 163 | width: 400px; 164 | height: 500px; 165 | float: left; 166 | font-size: 200%; 167 | margin: 2px; 168 | border: solid; 169 | border-color: #d3d2d2; 170 | border-radius: 8px; 171 | background-color: #adadade8; 172 | color: #fff; 173 | position: absolute; 174 | top: 50vh; 175 | left: 50%; 176 | transform: translate(-50%, -50%); 177 | -webkit-transform: translate(-50%, -50%); 178 | -ms-transform: translate(-50%, -50%); 179 | text-align:center; 180 | line-height:120px; 181 | -webkit-box-shadow: 0 3px 5px rgba(0, 0, 0, .3); 182 | visibility: hidden; 183 | } 184 | 185 | .ac_text { 186 | font-size: 100%; 187 | line-height:100%; 188 | } 189 | .ac_ave_text { 190 | font-size: 75%; 191 | line-height:100%; 192 | } 193 | 194 | #tw_share { 195 | padding: 5px !important; 196 | font-size: 90%; 197 | font-weight: bold; 198 | padding: .8em 1.6em; 199 | margin: 0.4em; 200 | background-color: #00acee; 201 | color: #fff; 202 | text-decoration: none; 203 | border-style: none; 204 | border-radius: 5px; 205 | } 206 | 207 | #tw_share:hover { 208 | opacity: 0.6; 209 | transition: 1.0s ; 210 | color: #fff; 211 | } 212 | 213 | .fa-facebook-square { 214 | color: #1877f2; 215 | } 216 | 217 | @media screen and (max-width: 560px){ 218 | .none {display:none} 219 | header { 220 | padding: 8px 0px; 221 | } 222 | } 223 | 224 | .copy_right { 225 | height: 13px; 226 | font-size: 13px; 227 | line-height: 13px; 228 | text-align: right; 229 | margin-top: 70px; 230 | margin-right: 190px; 231 | position: absolute; 232 | top: 95%; 233 | margin: 0px 50px; 234 | } 235 | 236 | .lang_display_none { 237 | display: none; 238 | } 239 | -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | 2 | const shuffle = ([...array]) => { 3 | for (let i = array.length - 1; i > 0; i--) { 4 | const j = Math.floor(Math.random() * (i + 1)); 5 | [array[i], array[j]] = [array[j], array[i]]; 6 | } 7 | return array; 8 | } 9 | 10 | function ColorToHex(color) { 11 | var hexadecimal = color.toString(16); 12 | return hexadecimal.length == 1 ? "0" + hexadecimal : hexadecimal; 13 | } 14 | function ConvertRGBtoHex(col) { 15 | return ColorToHex(col[0]) + ColorToHex(col[1]) + ColorToHex(col[2]); 16 | } 17 | 18 | let ac_color = [-1, -1, -1]; 19 | let ac_color_hex = ""; 20 | let color_step = 0; 21 | let start_time; 22 | let try_num = 0; 23 | let score_num = 0; 24 | let enable_submit = 0; 25 | let score_history5 = ["---", "---", "---", "---", "---"]; 26 | let miss_cnt = {}; 27 | const isJapanese = ((navigator.browserLanguage || navigator.language || navigator.userLanguage).substr(0,2) === 'ja'); 28 | 29 | function update_score(){ 30 | const try_elem = document.getElementById('try'); 31 | try_elem.innerHTML = "Try: " + try_num; 32 | 33 | const score_elem = document.getElementById('score'); 34 | score_elem.innerHTML = "Score: " + score_num; 35 | } 36 | 37 | function submit(r, g, b) { 38 | if (!enable_submit) return; 39 | 40 | const col = [r, g, b]; 41 | const col_hex = ConvertRGBtoHex(col); 42 | try_num++; 43 | 44 | if (col_hex == ac_color_hex) { 45 | time = update_timer(); 46 | enable_submit = false; 47 | update_score(); 48 | document.getElementById('modal_ac').style.visibility ="visible"; 49 | 50 | const time_text = Math.floor(time/1000) + "." + ("00"+time%1000).slice(-3); 51 | document.getElementById('ac_scores').innerHTML = 52 | "Score: " + score_num + "
" + 53 | "Time: " + time_text + "
" + 54 | "Try: " + try_num; 55 | 56 | let comment = ""; 57 | let comment2 = ""; 58 | if (color_step != 1) { 59 | if (isJapanese) { 60 | comment = "| チュートリアルを完了しました!" 61 | comment2 = "チュートリアル終了!" 62 | } else { 63 | comment = "| Tutorial Completed!" 64 | comment2 = "Tutorial Completed!" 65 | } 66 | } else if(try_num == 1) { 67 | if (isJapanese) { 68 | comment = "| 一発で白を見つけられました!" 69 | comment2 = "一発で見つけられた!" 70 | } else { 71 | comment = "| Found white in once!" 72 | comment2 = "Found white in once!" 73 | } 74 | } else if(time <= 10000) { 75 | if (isJapanese) { 76 | comment = "| 素早く白を見つけられました!" 77 | comment2 = "素早く見つけられた!" 78 | } else { 79 | comment = "| Found white fast!" 80 | comment2 = "Found white fast!" 81 | } 82 | } else if(try_num <= 10) { 83 | if (isJapanese) { 84 | comment = "| 10回以内に白を見つけられました!" 85 | comment2 = "10回以内に見つけた!" 86 | } else { 87 | comment = "| Found white within 10 times!" 88 | comment2 = "Found white within 10!" 89 | } 90 | } 91 | 92 | let ave_message = ""; 93 | if (color_step == 1) { 94 | score_history5.shift(); 95 | score_history5.push(score_num); 96 | let ave = 0; 97 | for (const v of score_history5) { 98 | if (v == "---") { 99 | ave = "---"; 100 | break; 101 | } 102 | ave += v; 103 | } 104 | if (ave != "---") { 105 | ave /= 5; 106 | if (isJapanese) { 107 | comment = "| 最近5回の平均スコア: " + ave + " " + comment; 108 | } else { 109 | comment = "| Average score of the last 5: " + ave + " " + comment; 110 | } 111 | } 112 | if (isJapanese) { 113 | ave_message = "最近5回の平均スコア:" + ave + "
(" + score_history5.join(', ') + ")" 114 | } else { 115 | ave_message = "Average score of last 5:" + ave + "
(" + score_history5.join(', ') + ")" 116 | } 117 | } 118 | document.getElementById('ac_ave').innerHTML = ave_message; 119 | document.getElementById('tw_share').setAttribute('href', 120 | "http://twitter.com/share?url=" + encodeURI(location.href) + 121 | "&hashtags=white_200&related=TumoiYorozu" + 122 | (isJapanese 123 | ? "&text="+encodeURI("200色の白から見つけよう! White 200 "+comment+"\n得点:" + score_num + "、時間:" + time_text + "秒、クリック回数:" + try_num) 124 | : "&text="+encodeURI("Find WHITE among 200 colors of white! | White 200 "+comment+"\nScore:" + score_num + ", Time:" + time_text + "sec, Try:" + try_num) 125 | ) 126 | ); 127 | 128 | document.getElementById('ac_comment').innerHTML = comment2; 129 | 130 | } else { 131 | let miss_txt = " "; 132 | if (miss_cnt[col_hex] == null) { 133 | miss_cnt[col_hex] = 1; 134 | } else { 135 | miss_cnt[col_hex]++; 136 | miss_txt = " [" + miss_cnt[col_hex] + "]"; 137 | } 138 | 139 | const dif = ((ac_color[0]-r)**2 + (ac_color[1]-g)**2 + (ac_color[2]-b)**2) / color_step**2; 140 | score_num -= dif; 141 | update_score(); 142 | 143 | // document.getElementById('col_'+col_hex).classList.add("opened"); 144 | document.getElementById('col_'+col_hex).style.backgroundImage = "linear-gradient(to left top, #" + ac_color_hex + "00 45%, #" + ac_color_hex + " 46%, #" + ac_color_hex + " 54%, #" + ac_color_hex + "00 55%)"; 145 | 146 | const hazure = document.getElementById('modal_hazure'); 147 | hazure.classList.remove("hazure_anim") 148 | window.requestAnimationFrame(function(time) { 149 | window.requestAnimationFrame(function(time) { 150 | hazure.classList.add("hazure_anim") 151 | hazure.addEventListener('animationend', function() { 152 | hazure.classList.remove("hazure_anim") 153 | }); 154 | }); 155 | }); 156 | const hazure_text = document.getElementById('hazure_text'); 157 | hazure_text.innerHTML="#" + col_hex + miss_txt + "
はずれ (-" + dif + ")"; 158 | } 159 | } 160 | function update_timer(){ 161 | if (!enable_submit) return; 162 | 163 | let now_time = new Date(); 164 | let diff = now_time.getTime() - start_time.getTime(); 165 | 166 | const time_elem = document.getElementById('time'); 167 | time_elem.innerHTML = "Time
" + 168 | Math.floor(diff/1000) + "." + 169 | ("0"+Math.floor(diff/10)%100).slice(-2); 170 | setTimeout(update_timer, 30); 171 | return diff; 172 | } 173 | 174 | function make_problem(num, dif){ 175 | const start_btn = document.getElementById('start_btn'); 176 | if (start_btn != null) start_btn.remove(); 177 | 178 | color_step = dif; 179 | const alt = document.getElementById('list'); 180 | const target_col = [255, 255, 255]; 181 | alt.innerHTML=""; 182 | let list = []; 183 | for(let r = 0; r <= 5; ++r){ 184 | for(let g = 0; g <= 5; ++g){ 185 | for(let b = 0; b <= 5; ++b){ 186 | list.push([target_col[0]-r*dif, target_col[1]-g*dif, target_col[2]-b*dif]); 187 | } 188 | } 189 | } 190 | list = shuffle(list); 191 | let html = ""; 192 | for(let i = 0; i < num; ++i) { 193 | let col_hex = ConvertRGBtoHex(list[i]); 194 | html += '\n'; 200 | // '">#' + col_hex + '\n'; 201 | } 202 | alt.innerHTML=html; 203 | ac_color = list[Math.floor(Math.random() * num)]; 204 | ac_color_hex = ConvertRGBtoHex(ac_color); 205 | const problem_text = document.getElementById('problem_text'); 206 | problem_text.innerHTML = "この白を探せ!
#" + ac_color_hex; 207 | const problem_color_box = document.getElementById('problem_color_box'); 208 | problem_color_box.style.setProperty('background-color', "#" + ac_color_hex); 209 | 210 | 211 | document.getElementById('modal_ac').style.visibility ="hidden"; 212 | 213 | miss_cnt = {}; 214 | 215 | score_num = (dif == 1) ? 1000 : 100; 216 | try_num = 0; 217 | update_score(); 218 | 219 | start_time = new Date(); 220 | enable_submit = true; 221 | update_timer(); 222 | } 223 | 224 | function change_lang(){ 225 | if (isJapanese) { 226 | for(const elems of document.querySelectorAll(".en")) { 227 | elems.className = "lang_display_none"; 228 | } 229 | } else { 230 | for(const elems of document.querySelectorAll(".ja")) { 231 | elems.className = "lang_display_none"; 232 | } 233 | } 234 | } 235 | 236 | 237 | window.onload = function(){ 238 | change_lang(); 239 | 240 | // make_problem(200, 2); 241 | // make_problem(3, 2); 242 | } 243 | --------------------------------------------------------------------------------