Created
July 23, 2019 13:48
-
-
Save ixsiid/605618e3988ba68945debaaf9adc0ec9 to your computer and use it in GitHub Desktop.
レンチキュラーディスプレイ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<style> | |
* { | |
margin: 0; | |
padding: 0; | |
} | |
table { | |
border: none; | |
border-collapse: collapse; | |
font-weight: bold; | |
text-align: center; | |
vertical-align: middle; | |
table-layout: fixed; | |
} | |
table td.button button { | |
width: 100px; | |
height: 100px; | |
margin: 20px; | |
font-size: 40px; | |
} | |
button { | |
width: 300px; | |
height: 40px; | |
margin: 20px; | |
} | |
.parameter{ | |
margin: 20px; | |
font-size: 50px; | |
} | |
</style> | |
<script> | |
// 画面レイアウトパラメータ | |
const header_height = 140 * 3 + 80; | |
const footer_height = 75 * 3; | |
// 環境によって調整するパラメータ | |
const width = 1080; | |
const height = 1920; | |
const view_count = 32; | |
// キャリブレーションパラメータ | |
const parameter = { | |
dpl: Math.floor((440.0 / 60.0) * view_count) / view_count, | |
x: 0.0, | |
angle: 90.0, | |
}; | |
const range = { | |
dpl: [4, 8], | |
x: [-5, 5], | |
angle: [60, 120], | |
}; | |
Object.defineProperty(parameter, 'canvas', { | |
writable: true, | |
value: null, | |
}); | |
const h = height - header_height - footer_height; | |
window.addEventListener('load', () => { | |
const canvas = document.getElementById('canvas'); | |
canvas.setAttribute('width', width); | |
canvas.setAttribute('height', h); | |
parameter.canvas = canvas; | |
stripe(); | |
}, false); | |
// 縞模様生成処理 | |
const stripe = () => { | |
parameter.dpl = Math.floor(parameter.dpl * view_count) / view_count; | |
document.getElementById('dpl_value').innerText = `DPL: ${parameter.dpl.toFixed(3)}`; | |
document.getElementById('offset_value').innerText = `Offset: ${parameter.x.toFixed(3)}`; | |
document.getElementById('angle_value').innerText = `Angle: ${parameter.angle}`; | |
const context = parameter.canvas.getContext('2d'); | |
context.clearRect(-1, -1, width + 2, h + 2); | |
context.beginPath(); | |
context.fillStyle = 'black'; | |
context.fillRect(-1, -1, width + 2, h + 2); | |
const cx = width / 2 + parameter.x; | |
const cy = height / 2 - header_height; | |
for (let i = 0; i < width; i += parameter.dpl) { | |
const dx = h * Math.tan((parameter.angle - 90.0) / 180.0 * Math.PI); | |
context.beginPath(); | |
context.strokeStyle = 'white'; | |
context.moveTo(cx - i, 0); | |
context.lineTo(cx - i - dx, h); | |
context.stroke(); | |
if (i == 0) continue; | |
context.beginPath(); | |
context.strokeStyle = 'white'; | |
context.moveTo(cx + i, 0); | |
context.lineTo(cx + i - dx, h); | |
context.stroke(); | |
} | |
}; | |
// HTML上の画像をPNGとして保存 | |
function download(kind) { | |
const p = {}; | |
if (kind == 'image') { | |
p.href = document.getElementById('canvas').toDataURL(); | |
p.download = `vertical_stripe_(${parameter.dpl},${parameter.x},${parameter.angle}).png`; | |
} else if (kind == 'json') { | |
p.href = 'data:application/json;charset=utf-8;,' + JSON.stringify(parameter); | |
p.download = `calibration_${Date.now()}.json`; | |
} | |
const canvas = document.getElementById('canvas'); | |
const a = document.createElement('a'); | |
Object.keys(p).map(x => a.setAttribute(x, p[x])); | |
document.body.appendChild(a); | |
a.click(); | |
document.body.removeChild(a); | |
} | |
function add(diff) { | |
Object.keys(diff).map(x => { | |
parameter[x] += diff[x]; | |
}); | |
Object.keys(range).map(x => { | |
if (parameter[x] < range[x][0]) parameter[x] = range[x][0]; | |
if (parameter[x] > range[x][1]) parameter[x] = range[x][1]; | |
}); | |
stripe(); | |
} | |
</script> | |
</head> | |
<body> | |
<table> | |
<tbody> | |
<tr> | |
<td class="button"><button onclick="add({angle: -1});">-1</button></td> | |
<td class="button"><button onclick="add({angle: -0.1});">-0.1</button></td> | |
<td class="button"><button onclick="add({angle: -0.01});">-0.01</button></td> | |
<td>Rotation</td> | |
<td class="button"><button onclick="add({angle: +0.01});">+0.01</button></td> | |
<td class="button"><button onclick="add({angle: +0.1});">+0.1</button></td> | |
<td class="button"><button onclick="add({angle: +1});">+1</button></td> | |
</tr> | |
<tr> | |
<td class="button"><button onclick="add({x: -1});">-1</button></td> | |
<td class="button"><button onclick="add({x: -0.1});">-0.1</button></td> | |
<td class="button"><button onclick="add({x: -0.01});">-0.01</button></td> | |
<td>Offset</td> | |
<td class="button"><button onclick="add({x: +0.01});">+0.01</button></td> | |
<td class="button"><button onclick="add({x: +0.1});">+0.1</button></td> | |
<td class="button"><button onclick="add({x: +1});">+1</button></td> | |
</tr> | |
<tr> | |
<td class="button"><button onclick="add({dpl: 1 / view_count * -16});">-16</button></td> | |
<td class="button"><button onclick="add({dpl: 1 / view_count * -4});">-4</button></td> | |
<td class="button"><button onclick="add({dpl: 1 / view_count * -1});">-1</button></td> | |
<td>Frequency</td> | |
<td class="button"><button onclick="add({dpl: 1 / view_count * +1});">+1</button></td> | |
<td class="button"><button onclick="add({dpl: 1 / view_count * +4});">+4</button></td> | |
<td class="button"><button onclick="add({dpl: 1 / view_count * +16});">+16</button></td> | |
</tr> | |
<tr> | |
<td colspan="3"><button onclick="download('image');">Image</button></td> | |
<td>Download</td> | |
<td colspan="3"><button onclick="download('json');">JSON</button></td> | |
</tr> | |
<tr> | |
<td colspan="7"><canvas id="canvas"></canvas></td> | |
</tr> | |
<tr> | |
<td colspan="7" class="parameter" id="dpl_value"></td> | |
</tr> | |
<tr> | |
<td colspan="7" class="parameter" id="angle_value"></td> | |
</tr> | |
<tr> | |
<td colspan="7" class="parameter" id="offset_value"></td> | |
</tr> | |
</tbody> | |
</table> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment