Skip to content

Instantly share code, notes, and snippets.

@motsu0
Created October 13, 2021 04:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save motsu0/a498740e080109abfd8207c81b499a4d to your computer and use it in GitHub Desktop.
Save motsu0/a498740e080109abfd8207c81b499a4d to your computer and use it in GitHub Desktop.
.input-row{
margin: 15px 0;
}
.input-data{
width: 80px;
margin: 0 5px;
}
.bt{
display: block;
margin: 0 auto 15px auto;
padding: 10px 20px;
cursor: pointer;
}
#canvas{
display: block;
max-width: 95%;
max-height: 500px;
margin: 15px auto;
border: 1px solid #333;
}
@media screen and (min-width:769px) {
#input-area{
display: flex;
flex-wrap: wrap;
text-align: center;
}
.input-row{
width: 50%;
}
}
<div id="input-area">
<div class="input-row">
w:<input type="number" min="100" max="4000" id="input-w" class="input-data" placeholder="300" value="300">(100-4000)
</div>
<div class="input-row">
h:<input type="number" min="100" max="4000" id="input-h" class="input-data" placeholder="300" value="300">(100-4000)
</div>
<div class="input-row">
粒度:<input type="number" min="1" max="4000" id="input-q" class="input-data" placeholder="10" value="10">(1-4000)
</div>
<div class="input-row">
色:<input type="color" id="input-c" class="input-data" value="#000000">
</div>
<div class="input-row">
背景色:<select name="sel-bg" id="sel-bg">
<option value="transparent">透明</option>
<option value="white">白色</option>
</select>
</div>
</div>
<button id="bt-submit" class="bt">再生成</button>
<div id="msg-box"></div>
<canvas id="canvas"></canvas>
<button id="bt-dl" class="bt">画像をダウンロード</button>
const input_w = document.getElementById('input-w');
const input_h = document.getElementById('input-h');
const input_q = document.getElementById('input-q');
const input_c = document.getElementById('input-c');
const input_data = document.getElementsByClassName('input-data');
const sel_bg = document.getElementById('sel-bg');
const bt_submit = document.getElementById('bt-submit');
const bt_dl = document.getElementById('bt-dl');
const msg_box = document.getElementById('msg-box');
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
//
[...input_data].forEach(el=>{
el.addEventListener('input',draw);
});
sel_bg.addEventListener('change',draw);
bt_submit.addEventListener('click',draw);
bt_dl.addEventListener('click',download);
//
draw();
function draw(){
//例外処理
for(let i=0;i<input_data.length;i++){
if(isNaN(Number(input_data[i].value))&&input_data[3]!=input_c){
msg('入力値に誤りがあります。');
return;
}
}
if(
Number(input_w.value)<100||
Number(input_w.value)>4000||
Number(input_h.value)<100||
Number(input_h.value)>4000||
Number(input_q.value)<1||
Number(input_q.value)>4000
){
msg('入力値が範囲外です。');
return;
}
//粒度限界
if(Number(input_q.value)/(Number(input_h.value)*Number(input_w.value))<1/100000){
msg('画像サイズに対して粒度が小さすぎます。');
return;
}
//初期処理
const unit = Number(input_q.value);
const row = Math.ceil(input_h.value/unit);
const col = Math.ceil(input_w.value/unit);
msg('');
//描画
canvas.width = input_w.value;
canvas.height = input_h.value;
ctx.clearRect(0, 0, canvas.width, canvas.height);
if(sel_bg.value=='white'){
ctx.fillStyle = '#FFFFFF';
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
for(let r=0;r<row;r++){
for(let c=0;c<col;c++){
ctx.globalAlpha = Math.random();
ctx.fillStyle = input_c.value;
ctx.fillRect(c*unit, r*unit, unit, unit);
}
}
//style
}
function msg(str){
msg_box.textContent = str;
canvas.width = 300;
canvas.height = 300;
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
function download(){
const file_name = `mosaic.png`;
const a = document.createElement('a');
a.download = file_name;
canvas.toBlob(blob=>{
a.href = window.URL.createObjectURL(blob);
a.click();
},'image/png');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment