This commit is contained in:
赵鑫 2022-09-12 16:45:04 +08:00
parent 63730ac295
commit 923c42f2e0
10 changed files with 157 additions and 213 deletions

View File

@ -4,8 +4,8 @@
"description": "赵家小站", "description": "赵家小站",
"main": "server.js", "main": "server.js",
"scripts": { "scripts": {
"dev": "nodemon server", "start": "nodemon server",
"start": "PORT=8080 pm2 start server.js --name 'Zhao Server:8080' --watch", "install": "PORT=8080 pm2 start server.js --name 'Zhao Server:8080' --watch",
"test": "echo \"Error: no test specified\" && exit 1" "test": "echo \"Error: no test specified\" && exit 1"
}, },
"repository": { "repository": {

36
public/js/sensehat.js Normal file
View File

@ -0,0 +1,36 @@
/**
* Sense HAT 客户端
*/
const client = io.connect('ws://pi', { path: '/sensehat/socket.io' })
let current_color = [255, 255, 255]
client.on('action', ({ action, x, y, color, pixels }) => {
let leds = document.querySelectorAll('.led')
switch (action) {
case 'clear':
color = color || [0, 0, 0]
leds.forEach((led, i) => {
led.style.backgroundColor = `rgb(${String(color)})`
})
break
case 'setPixel':
leds[y * 8 + x].style.backgroundColor = `rgb(${String(color)})`
break
case 'setPixels':
leds.forEach((led, i) => {
led.style.backgroundColor = `rgb(${String(pixels[i])})`
})
break
default:
break
}
})
document.querySelectorAll('.led').forEach(led => {
led.addEventListener('click', (event) => {
const { x, y } = event.target.dataset
const color = current_color
client.emit('action', { action: 'setPixel', x, y, color })
})
})

View File

@ -1,131 +0,0 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/style/zhao.css">
<link rel="stylesheet" href="sensehat.css">
<title>Sense Hat</title>
</head>
<body>
<h1>Sense HAT 交互界面</h1>
<div style="width:300px; display:flex; flex-direction: column; align-items: center;">
<div id="matrix">
<div class="row">
<div class="led" data-y="0" data-x="0" onclick="setPixel(this)"></div>
<div class="led" data-y="0" data-x="1" onclick="setPixel(this)"></div>
<div class="led" data-y="0" data-x="2" onclick="setPixel(this)"></div>
<div class="led" data-y="0" data-x="3" onclick="setPixel(this)"></div>
<div class="led" data-y="0" data-x="4" onclick="setPixel(this)"></div>
<div class="led" data-y="0" data-x="5" onclick="setPixel(this)"></div>
<div class="led" data-y="0" data-x="6" onclick="setPixel(this)"></div>
<div class="led" data-y="0" data-x="7" onclick="setPixel(this)"></div>
</div>
<div class="row">
<div class="led" data-y="1" data-x="0" onclick="setPixel(this)"></div>
<div class="led" data-y="1" data-x="1" onclick="setPixel(this)"></div>
<div class="led" data-y="1" data-x="2" onclick="setPixel(this)"></div>
<div class="led" data-y="1" data-x="3" onclick="setPixel(this)"></div>
<div class="led" data-y="1" data-x="4" onclick="setPixel(this)"></div>
<div class="led" data-y="1" data-x="5" onclick="setPixel(this)"></div>
<div class="led" data-y="1" data-x="6" onclick="setPixel(this)"></div>
<div class="led" data-y="1" data-x="7" onclick="setPixel(this)"></div>
</div>
<div class="row">
<div class="led" data-y="2" data-x="0" onclick="setPixel(this)"></div>
<div class="led" data-y="2" data-x="1" onclick="setPixel(this)"></div>
<div class="led" data-y="2" data-x="2" onclick="setPixel(this)"></div>
<div class="led" data-y="2" data-x="3" onclick="setPixel(this)"></div>
<div class="led" data-y="2" data-x="4" onclick="setPixel(this)"></div>
<div class="led" data-y="2" data-x="5" onclick="setPixel(this)"></div>
<div class="led" data-y="2" data-x="6" onclick="setPixel(this)"></div>
<div class="led" data-y="2" data-x="7" onclick="setPixel(this)"></div>
</div>
<div class="row">
<div class="led" data-y="3" data-x="0" onclick="setPixel(this)"></div>
<div class="led" data-y="3" data-x="1" onclick="setPixel(this)"></div>
<div class="led" data-y="3" data-x="2" onclick="setPixel(this)"></div>
<div class="led" data-y="3" data-x="3" onclick="setPixel(this)"></div>
<div class="led" data-y="3" data-x="4" onclick="setPixel(this)"></div>
<div class="led" data-y="3" data-x="5" onclick="setPixel(this)"></div>
<div class="led" data-y="3" data-x="6" onclick="setPixel(this)"></div>
<div class="led" data-y="3" data-x="7" onclick="setPixel(this)"></div>
</div>
<div class="row">
<div class="led" data-y="4" data-x="0" onclick="setPixel(this)"></div>
<div class="led" data-y="4" data-x="1" onclick="setPixel(this)"></div>
<div class="led" data-y="4" data-x="2" onclick="setPixel(this)"></div>
<div class="led" data-y="4" data-x="3" onclick="setPixel(this)"></div>
<div class="led" data-y="4" data-x="4" onclick="setPixel(this)"></div>
<div class="led" data-y="4" data-x="5" onclick="setPixel(this)"></div>
<div class="led" data-y="4" data-x="6" onclick="setPixel(this)"></div>
<div class="led" data-y="4" data-x="7" onclick="setPixel(this)"></div>
</div>
<div class="row">
<div class="led" data-y="5" data-x="0" onclick="setPixel(this)"></div>
<div class="led" data-y="5" data-x="1" onclick="setPixel(this)"></div>
<div class="led" data-y="5" data-x="2" onclick="setPixel(this)"></div>
<div class="led" data-y="5" data-x="3" onclick="setPixel(this)"></div>
<div class="led" data-y="5" data-x="4" onclick="setPixel(this)"></div>
<div class="led" data-y="5" data-x="5" onclick="setPixel(this)"></div>
<div class="led" data-y="5" data-x="6" onclick="setPixel(this)"></div>
<div class="led" data-y="5" data-x="7" onclick="setPixel(this)"></div>
</div>
<div class="row">
<div class="led" data-y="6" data-x="0" onclick="setPixel(this)"></div>
<div class="led" data-y="6" data-x="1" onclick="setPixel(this)"></div>
<div class="led" data-y="6" data-x="2" onclick="setPixel(this)"></div>
<div class="led" data-y="6" data-x="3" onclick="setPixel(this)"></div>
<div class="led" data-y="6" data-x="4" onclick="setPixel(this)"></div>
<div class="led" data-y="6" data-x="5" onclick="setPixel(this)"></div>
<div class="led" data-y="6" data-x="6" onclick="setPixel(this)"></div>
<div class="led" data-y="6" data-x="7" onclick="setPixel(this)"></div>
</div>
<div class="row">
<div class="led" data-y="7" data-x="0" onclick="setPixel(this)"></div>
<div class="led" data-y="7" data-x="1" onclick="setPixel(this)"></div>
<div class="led" data-y="7" data-x="2" onclick="setPixel(this)"></div>
<div class="led" data-y="7" data-x="3" onclick="setPixel(this)"></div>
<div class="led" data-y="7" data-x="4" onclick="setPixel(this)"></div>
<div class="led" data-y="7" data-x="5" onclick="setPixel(this)"></div>
<div class="led" data-y="7" data-x="6" onclick="setPixel(this)"></div>
<div class="led" data-y="7" data-x="7" onclick="setPixel(this)"></div>
</div>
</div>
<p style="display:flex;gap:4px;">
<button onclick="client.emit('action', {action:'clear'})">清除</button>
<button onclick="client.emit('action', {action:'flash'})">闪光</button>
</p>
<p style="display:flex;gap:4px;">
<button onclick="client.emit('action', {action:'flipH'})">左右反转</button>
<button onclick="client.emit('action', {action:'flipV'})">上下反转</button>
</p>
<p style="display:flex;gap:4px;">
<button onclick="client.emit('action', {action:'loadImage', image:'heart'})">空心</button>
<button onclick="client.emit('action', {action:'loadImage', image:'heart_full'})">红心</button>
</p>
<!-- <button onclick="client.emit('action', {action:'turnLeft'})">turnLeft</button>
<button onclick="client.emit('action', {action:'turnRight'})">turnRight</button> -->
<!-- <button onclick="client.emit('action', {action:'showLetter', character:'A', color:[50,50,255]})">A</button>
<button
onclick="client.emit('action', {action:'showMessage', text:'Hello', color:[50,50,255], speed: 1})">Hello</button>
<button
onclick="client.emit('action', {action:'flashMessage', text:'Hello', color:[50,50,255], speed: 1})">Hello</button> -->
<div style="display:flex;">
<div>
<p><input type="range" name="red" id="red" min="0" , max="255" step="1" value="50"></p>
<p>绿 <input type="range" name="green" id="green" min="0" , max="255" step="1" value="50"></p>
<p><input type="range" name="blue" id="blue" min="0" , max="255" step="1" value="255"></p>
</div>
<div id="selected_color" style="width:100px;height:100px;border:1px solid black;margin:auto 1rem;"></div>
</div>
</div>
<script src="http://pi/sensehat/socket.io/socket.io.js"></script>
<script src="sensehat.js"></script>
</body>
</html>

View File

@ -1,30 +0,0 @@
#matrix {
display: flex;
flex-direction: column;
gap: 2px;
}
.row {
display: flex;
width: 254px;
gap: 2px;
}
.led {
width: 30px;
height: 30px;
border: 1px solid gray;
background-color: whitesmoke;
cursor: pointer;
border-radius: 2px;
}
.led.on {
background-color: blue;
}
button {
width: 100px;
margin-top: 1rem;
/* flex: 1 1 auto; */
}

View File

@ -1,43 +0,0 @@
const client = io.connect('ws://pi', { path: '/sensehat/socket.io', })
client.on('action', ({ action, x, y, color, pixels }) => {
var leds = document.querySelectorAll('.led')
if (color == undefined || color == [0, 0, 0]) color = [255, 255, 255]
var [r, g, b] = color
if (r == 0 && g == 0 && b == 0) [r, g, b] = [255, 255, 255]
switch (action) {
case 'clear':
for (let i = 0; i < 64; i++) {
leds[i].style.backgroundColor = `rgb(${r}, ${g}, ${b})`
}
break
case 'setPixel':
leds[y * 8 + x].style.backgroundColor = `rgb(${r}, ${g}, ${b})`
break
case 'setPixels':
for (let i = 0; i < 64; i++) {
var [r, g, b] = pixels[i]
if (r == 0 && g == 0 && b == 0) [r, g, b] = [255, 255, 255]
leds[i].style.backgroundColor = `rgb(${r}, ${g}, ${b})`
}
break
default:
break
}
})
function setPixel(led) {
const { x, y } = led.dataset
const r = Number(red.value)
const g = Number(green.value)
const b = Number(blue.value)
client.emit('action', { action: 'setPixel', x, y, color: [r, g, b] })
}
red.onchange = change_color
green.onchange = change_color
blue.onchange = change_color
function change_color() {
selected_color.style.backgroundColor = `rgb(${red.value},${green.value},${blue.value})`
}
change_color()

View File

@ -1,4 +1,5 @@
const router = require('express').Router() const router = require('express').Router()
router.get('/', (req, res) => res.render('home')) router.get('/', (req, res) => res.render('home'))
router.get('/poems', (req, res) => res.render('poems')) router.get('/poems', (req, res) => res.render('poems'))
router.get('/sensehat', (req, res) => res.render('sensehat'))
module.exports = router module.exports = router

View File

@ -16,7 +16,7 @@ const server = app.listen(PORT, () => console.log(`zhao server running at port $
const moment = require('moment') const moment = require('moment')
moment.locale('zh-cn') moment.locale('zh-cn')
const filesize = require('filesize').partial({base: 2, standard: "jedec"}) const filesize = require('filesize').partial({ base: 2, standard: "jedec" })
app.locals.moment = moment app.locals.moment = moment
app.locals.filesize = filesize app.locals.filesize = filesize

View File

@ -6,8 +6,7 @@ html(lang='zh')
meta(name='viewport', content='width=device-width, initial-scale=1.0') meta(name='viewport', content='width=device-width, initial-scale=1.0')
link(rel='stylesheet', href='/css/bootstrap.min.css') link(rel='stylesheet', href='/css/bootstrap.min.css')
link(rel='stylesheet', href='/css/zhao.css') link(rel='stylesheet', href='/css/zhao.css')
script(src='/socket.io/socket.io.min.js', defer) block styles
script(src='/js/bootstrap.bundle.min.js', defer)
title 赵家小站 title 赵家小站
body body
nav.navbar.navbar-expand-sm.navbar-light.bg-light nav.navbar.navbar-expand-sm.navbar-light.bg-light
@ -22,5 +21,5 @@ html(lang='zh')
include nav.pug include nav.pug
.container-md.py-3 .container-md.py-3
block main block main
script(src='/js/bootstrap.bundle.min.js', defer)
block scripts block scripts

View File

@ -1,7 +1,7 @@
li.nav-item li.nav-item
a.nav-link(href='/poems') 背诗词 a.nav-link(href='/poems') 背诗词
li.nav-item li.nav-item
a.nav-link(href='/sensehat/', target='_blank') SenseHAT a.nav-link(href='/sensehat') SenseHAT
li.nav-item li.nav-item
li.nav-item.dropdown li.nav-item.dropdown
a.nav-link.dropdown-toggle(data-bs-toggle='dropdown', href='#', role='button', aria-haspopup='true', aria-expanded='false') 数学 a.nav-link.dropdown-toggle(data-bs-toggle='dropdown', href='#', role='button', aria-haspopup='true', aria-expanded='false') 数学

View File

@ -1,5 +1,117 @@
extends layout extends layout.pug
block styles
style.
.led-matrix {
max-width: 384px;
min-width: 240px;
}
.led-row {}
.led {
margin: 1px;
aspect-ratio: 1;
cursor: pointer;
border-radius: 4px;
border: 1px solid gray;
background-color: #ddd;
}
block main block main
.container .container
h1 SenseHAT h1.h6.text-muted Sense HAT 交互界面
.container-fluid.bg-success
.led-matrix.w-auto.mx-auto.p-3
.led-row.row
.led.col(data-y='0' data-x='0')
.led.col(data-y='0' data-x='1')
.led.col(data-y='0' data-x='2')
.led.col(data-y='0' data-x='3')
.led.col(data-y='0' data-x='4')
.led.col(data-y='0' data-x='5')
.led.col(data-y='0' data-x='6')
.led.col(data-y='0' data-x='7')
.led-row.row
.led.col(data-y='1' data-x='0')
.led.col(data-y='1' data-x='1')
.led.col(data-y='1' data-x='2')
.led.col(data-y='1' data-x='3')
.led.col(data-y='1' data-x='4')
.led.col(data-y='1' data-x='5')
.led.col(data-y='1' data-x='6')
.led.col(data-y='1' data-x='7')
.led-row.row
.led.col(data-y='2' data-x='0')
.led.col(data-y='2' data-x='1')
.led.col(data-y='2' data-x='2')
.led.col(data-y='2' data-x='3')
.led.col(data-y='2' data-x='4')
.led.col(data-y='2' data-x='5')
.led.col(data-y='2' data-x='6')
.led.col(data-y='2' data-x='7')
.led-row.row
.led.col(data-y='3' data-x='0')
.led.col(data-y='3' data-x='1')
.led.col(data-y='3' data-x='2')
.led.col(data-y='3' data-x='3')
.led.col(data-y='3' data-x='4')
.led.col(data-y='3' data-x='5')
.led.col(data-y='3' data-x='6')
.led.col(data-y='3' data-x='7')
.led-row.row
.led.col(data-y='4' data-x='0')
.led.col(data-y='4' data-x='1')
.led.col(data-y='4' data-x='2')
.led.col(data-y='4' data-x='3')
.led.col(data-y='4' data-x='4')
.led.col(data-y='4' data-x='5')
.led.col(data-y='4' data-x='6')
.led.col(data-y='4' data-x='7')
.led-row.row
.led.col(data-y='5' data-x='0')
.led.col(data-y='5' data-x='1')
.led.col(data-y='5' data-x='2')
.led.col(data-y='5' data-x='3')
.led.col(data-y='5' data-x='4')
.led.col(data-y='5' data-x='5')
.led.col(data-y='5' data-x='6')
.led.col(data-y='5' data-x='7')
.led-row.row
.led.col(data-y='6' data-x='0')
.led.col(data-y='6' data-x='1')
.led.col(data-y='6' data-x='2')
.led.col(data-y='6' data-x='3')
.led.col(data-y='6' data-x='4')
.led.col(data-y='6' data-x='5')
.led.col(data-y='6' data-x='6')
.led.col(data-y='6' data-x='7')
.led-row.row
.led.col(data-y='7' data-x='0')
.led.col(data-y='7' data-x='1')
.led.col(data-y='7' data-x='2')
.led.col(data-y='7' data-x='3')
.led.col(data-y='7' data-x='4')
.led.col(data-y='7' data-x='5')
.led.col(data-y='7' data-x='6')
.led.col(data-y='7' data-x='7')
.container-fluid.p-3.bg-light
.row.gap-1.my-3
button.col.btn.btn-primary(onclick="client.emit('action', {action:'clear'});") 清空
button.col.btn.btn-primary(onclick="client.emit('action', {action:'flash', color:current_color});") 闪光
button.col.btn.btn-primary(onclick="client.emit('action', {action:'loadImage', image:'heart'});") 空心
button.col.btn.btn-primary(onclick="client.emit('action', {action:'loadImage', image:'heart_full'});") 红心
button.col.btn.btn-primary(onclick="client.emit('action', {action:'flipH'});") 左右镜像
button.col.btn.btn-primary(onclick="client.emit('action', {action:'flipV'});") 上下镜像
button.col.btn.btn-primary(onclick="client.emit('action', {action:'showMessage', text:'Hello'})") Hello
.row.gap-1.my-3
button.col.btn.btn-dark(onclick="current_color=[0,0,0];") 黑
button.col.btn.btn-white(onclick="current_color=[255,255,255];") 白
button.col.btn.btn-danger(onclick="current_color=[255,0,0];") 红
button.col.btn.btn-success(onclick="current_color=[0,255,0];") 绿
button.col.btn.btn-primary(onclick="current_color=[0,0,255];") 蓝
button.col.btn.btn-warning(onclick="current_color=[255,255,0];") 黄
block scripts
script(src="http://pi/sensehat/socket.io/socket.io.js")
script(src="/js/sensehat.js")