Node-REDを使ってドット絵を表示する
動的にマトリクス表示するアプリケーションをNode-REDで作ろうと考えています。
DotGen.css – CSS Collectionというドット絵のCSSを生成してくれるサイトがありましたので、これでできるかためしてみます。
DotGen.cssの使い方
![DotGen.css - CSS Collection 2021-06-12 15-41-54.jpg DotGen css CSS Collection 2021 06 12 15 41 54](https://digital-light.jp/wp-content/uploads/2021/06/DotGen.css-CSS-Collection-2021-06-12-15-41-54.jpg)
まずは2×2ドットのマトリクスを表示しました。
![DotGen.css - CSS Collection 2021-06-12 15-46-17.jpg DotGen css CSS Collection 2021 06 12 15 46 17](https://digital-light.jp/wp-content/uploads/2021/06/DotGen.css-CSS-Collection-2021-06-12-15-46-17.jpg)
こちらの値で1ドットのサイズを設定できます。
最初の数字で縦横のマトリクス数が設定できます。
Outputにて下記のhtml+CSSが生成されます。
<div class="dot"></div> <style> .dot::before { content: ""; position: absolute; top: -60px; left: -60px; width: 60px; height: 60px; background: transparent; box-shadow:60px 60px 0 rgb(173, 173, 173), 120px 60px 0 transparent, 60px 120px 0 transparent, 120px 120px 0 transparent; } </style>
Node-REDでTemplateノードを使って表示
![Node-RED 2021-06-12 15-49-00.jpg Node RED 2021 06 12 15 49 00](https://digital-light.jp/wp-content/uploads/2021/06/Node-RED-2021-06-12-15-49-00.jpg)
http inノード、templateノード、http responseノードを使ってフローを作成。
![Node-RED 2021-06-12 15-50-13.jpg Node RED 2021 06 12 15 50 13](https://digital-light.jp/wp-content/uploads/2021/06/Node-RED-2021-06-12-15-50-13.jpg)
Templateノードには先程のOutputをそのまま貼り付け。
![Node-RED 2021-06-12 15-50-48.jpg Node RED 2021 06 12 15 50 48](https://digital-light.jp/wp-content/uploads/2021/06/Node-RED-2021-06-12-15-50-48.jpg)
http inノードには、MethodをGET、URLは”/hello”としました。
これで http://localhost:1880/hello にアクセスすると
![hello 2021-06-12 15-51-48.jpg Hello 2021 06 12 15 51 48](https://digital-light.jp/wp-content/uploads/2021/06/hello-2021-06-12-15-51-48.jpg)
このように表示されます。
マトリクス部分を動的に表示したい
![Node-RED 2021-06-12 15-52-57.jpg Node RED 2021 06 12 15 52 57](https://digital-light.jp/wp-content/uploads/2021/06/Node-RED-2021-06-12-15-52-57.jpg)
DotGen.cssから出力されるCSS部分をみてみると、ドットの状態によって変わらない部分と、変わる部分があります。
この変わる部分を動的に作ることができれば、ドット表示の操作ができそうです。
![Node-RED 2021-06-12 16-08-51.jpg Node RED 2021 06 12 16 08 51](https://digital-light.jp/wp-content/uploads/2021/06/Node-RED-2021-06-12-16-08-51.jpg)
このようにフローを作成。
![Node-RED 2021-06-12 16-09-46.jpg Node RED 2021 06 12 16 09 46](https://digital-light.jp/wp-content/uploads/2021/06/Node-RED-2021-06-12-16-09-46.jpg)
動的に生成するCSS部分をtemplateノードで作成。
![Node-RED 2021-06-12 16-10-39.jpg Node RED 2021 06 12 16 10 39](https://digital-light.jp/wp-content/uploads/2021/06/Node-RED-2021-06-12-16-10-39.jpg)
box-shadowの後にpayloadで差し込みました。
![hello 2021-06-12 16-11-41.jpg Hello 2021 06 12 16 11 41](https://digital-light.jp/wp-content/uploads/2021/06/hello-2021-06-12-16-11-41.jpg)
これで表示されました。
dot1とdot2で表示を切り替え
![Node-RED 2021-06-12 16-16-17.jpg Node RED 2021 06 12 16 16 17](https://digital-light.jp/wp-content/uploads/2021/06/Node-RED-2021-06-12-16-16-17.jpg)
このようにフローを作成。http://localhost:1880/dot1とhttp://localhost:1880/dot2でCSS-dynamicの内容を変更。
[{"id":"59ff2a1.fa600d4","type":"http in","z":"1354c47f.07097c","name":"","url":"/dot1","method":"get","upload":false,"swaggerDoc":"","x":140,"y":140,"wires":[["e12f95d3.5f6668"]]},{"id":"266c286f.d993d8","type":"http response","z":"1354c47f.07097c","name":"","x":670,"y":220,"wires":[]},{"id":"c1a860bb.f14d5","type":"template","z":"1354c47f.07097c","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"<html>\n <head></head>\n <body>\n<div class=\"dot\"></div>\n<style>\n.dot::before {\n content: \"\";\n position: absolute;\n top: -60px;\n left: -60px;\n\n width: 60px;\n height: 60px;\n background: transparent;\n\n box-shadow:{{payload}}\n}\n</style>","output":"str","x":500,"y":220,"wires":[["266c286f.d993d8"]]},{"id":"e12f95d3.5f6668","type":"template","z":"1354c47f.07097c","name":"CSS-dynamic","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"60px 60px 0 rgb(173, 173, 173),\n120px 60px 0 transparent,\n60px 120px 0 transparent,\n120px 120px 0 transparent;","output":"str","x":320,"y":180,"wires":[["c1a860bb.f14d5"]]},{"id":"b7ad4099.56333","type":"http in","z":"1354c47f.07097c","name":"","url":"/dot2","method":"get","upload":false,"swaggerDoc":"","x":140,"y":220,"wires":[["2261bf9.36d704"]]},{"id":"2261bf9.36d704","type":"template","z":"1354c47f.07097c","name":"CSS-dynamic","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"60px 60px 0 rgb(173, 173, 173),\n120px 60px 0 transparent,\n60px 120px 0 transparent,\n120px 120px 0 rgb(173, 173, 173);","output":"str","x":320,"y":240,"wires":[["c1a860bb.f14d5"]]}]
![dot2 2021-06-12 16-17-46.jpg Dot2 2021 06 12 16 17 46](https://digital-light.jp/wp-content/uploads/2021/06/dot2-2021-06-12-16-17-46.jpg)
無事に変更できました。
for文でマトリクス部分を作成
![Node-RED 2021-06-12 16-56-36.jpg Node RED 2021 06 12 16 56 36](https://digital-light.jp/wp-content/uploads/2021/06/Node-RED-2021-06-12-16-56-36.jpg)
マトリクス部分をfor文で生成するようにしました。
↓ フローはこちら
[{"id":"266c286f.d993d8","type":"http response","z":"1354c47f.07097c","name":"","x":490,"y":560,"wires":[]},{"id":"c1a860bb.f14d5","type":"template","z":"1354c47f.07097c","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"<html>\n <head></head>\n <body>\n<div class=\"dot\"></div>\n<style>\n.dot::before {\n content: \"\";\n position: absolute;\n top: -60px;\n left: -60px;\n\n width: 59px;\n height: 59px;\n background: transparent;\n\n box-shadow:{{payload}}\n}\n</style>","output":"str","x":420,"y":500,"wires":[["266c286f.d993d8"]]},{"id":"b7ad4099.56333","type":"http in","z":"1354c47f.07097c","name":"","url":"/dot1","method":"get","upload":false,"swaggerDoc":"","x":220,"y":380,"wires":[["88923119.bb9ad"]]},{"id":"88923119.bb9ad","type":"function","z":"1354c47f.07097c","name":"","func":"var x = 0;\nvar y = 0;\nvar pitch = 60;\nvar html= \"\";\n\nfor (i=0; i<2; i++){\n y=0;\n x = x+pitch;\n \n for ( o=0; o<2; o++){\n y = y+pitch;\n html = html+x+\"px \"+y+\"px 0 rgb(173, 173, 173),\";\n }\n}\n\nhtml = html.slice( 0, -1 ) ;\n\nmsg.payload = html;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":340,"y":440,"wires":[["c1a860bb.f14d5"]]}]
functionノードのJavascriptはこの様に。
var x = 0; var y = 0; var pitch = 60; var html= ""; for (i=0; i<2; i++){ y=0; x = x+pitch; for ( o=0; o<2; o++){ y = y+pitch; html = html+x+"px "+y+"px 0 rgb(173, 173, 173),"; } } html = html.slice( 0, -1 ) ; msg.payload = html; return msg;
![Node-RED 2021-06-12 17-03-25.jpg Node RED 2021 06 12 17 03 25](https://digital-light.jp/wp-content/uploads/2021/06/Node-RED-2021-06-12-17-03-25.jpg)
さらに、templateノードでwidthとheightを1減らすことで、仕切り線も表示できるようになりました。
マトリクスの大きさを変更
今までは2×2のマトリクスで表示していましたが、これを変更できるようにします。
![Node-RED 2021-06-12 17-08-52.jpg Node RED 2021 06 12 17 08 52](https://digital-light.jp/wp-content/uploads/2021/06/Node-RED-2021-06-12-17-08-52.jpg)
functionノードをこの様に変更。
![dot1 2021-06-12 17-09-45.jpg Dot1 2021 06 12 17 09 45](https://digital-light.jp/wp-content/uploads/2021/06/dot1-2021-06-12-17-09-45.jpg)
これで、20×10のマトリクスで表示されるようになりました。
濃淡を変数で表示
![Node-RED 2021-06-12 17-16-50.jpg Node RED 2021 06 12 17 16 50](https://digital-light.jp/wp-content/uploads/2021/06/Node-RED-2021-06-12-17-16-50.jpg)
これで、濃淡をdimとして変数で表示できるようになりました。
背景を黒に
![Node-RED 2021-06-12 17-21-39.jpg Node RED 2021 06 12 17 21 39](https://digital-light.jp/wp-content/uploads/2021/06/Node-RED-2021-06-12-17-21-39.jpg)
Templateノードを修正して、背景を黒にしました。
![dot1 2021-06-12 17-22-22.jpg Dot1 2021 06 12 17 22 22](https://digital-light.jp/wp-content/uploads/2021/06/dot1-2021-06-12-17-22-22.jpg)
濃淡をランダムに
getRandom(min,max)という関数をつくり、濃淡をランダムで設定するようにしました。
↓ 参考記事
【JavaScript入門】乱数の作り方(範囲指定/重複なし/ランダム文字列) | 侍エンジニアブログ
var x = 0; var y = 0; var xMax = 20; var yMax = 10; var pitch = 60; var html= ""; var dimlevel = 173; var dim = "rgb("+dimlevel+","+dimlevel+","+dimlevel+")"; for (i=0; i<xMax; i++){ y=0; x = x+pitch; for ( o=0; o<yMax; o++){ y = y+pitch; // dimlevelをランダム生成 dimlevel = getRandom(0,255); dim = "rgb("+dimlevel+","+dimlevel+","+dimlevel+")"; html = html+x+"px "+y+"px 0 "+dim+","; } } html = html.slice( 0, -1 ) ; msg.payload = html; return msg; // getRandom function getRandom( min, max ) { var random = Math.floor( Math.random() * (max + 1 - min) ) + min; return random; }
![dot1 2021-06-12 17-30-14.jpg Dot1 2021 06 12 17 30 14](https://digital-light.jp/wp-content/uploads/2021/06/dot1-2021-06-12-17-30-14.jpg)
この様に、濃淡が0〜255の範囲でマトリクスに反映されるようになりました。
ブラウザを2秒おきにリロード
![Node-RED 2021-06-12 17-33-29.jpg Node RED 2021 06 12 17 33 29](https://digital-light.jp/wp-content/uploads/2021/06/Node-RED-2021-06-12-17-33-29.jpg)
これで、ブラウザを2秒おきにリロードしました。
最終的なフローはこちら
[{"id":"266c286f.d993d8","type":"http response","z":"1354c47f.07097c","name":"","x":490,"y":560,"wires":[]},{"id":"c1a860bb.f14d5","type":"template","z":"1354c47f.07097c","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"<html>\n <head>\n <meta http-equiv=\"refresh\" content=\"2; URL=\">\n </head>\n <body>\n<div class=\"dot\"></div>\n<style>\nbody{\n background-color: black; \n}\n\n.dot::before {\n content: \"\";\n position: absolute;\n top: -60px;\n left: -60px;\n\n width: 59px;\n height: 59px;\n background: transparent;\n\n box-shadow:{{payload}}\n}\n</style>","output":"str","x":420,"y":500,"wires":[["266c286f.d993d8"]]},{"id":"b7ad4099.56333","type":"http in","z":"1354c47f.07097c","name":"","url":"/dot1","method":"get","upload":false,"swaggerDoc":"","x":220,"y":380,"wires":[["88923119.bb9ad"]]},{"id":"88923119.bb9ad","type":"function","z":"1354c47f.07097c","name":"","func":"var x = 0;\nvar y = 0;\nvar xMax = 20;\nvar yMax = 10;\nvar pitch = 60;\nvar html= \"\";\n\nvar dimlevel = 173;\nvar dim = \"rgb(\"+dimlevel+\",\"+dimlevel+\",\"+dimlevel+\")\";\n\nfor (i=0; i<xMax; i++){\n y=0;\n x = x+pitch;\n \n for ( o=0; o<yMax; o++){\n y = y+pitch;\n \n // dimlevelをランダム生成\n dimlevel = getRandom(0,255);\n dim = \"rgb(\"+dimlevel+\",\"+dimlevel+\",\"+dimlevel+\")\";\n \n html = html+x+\"px \"+y+\"px 0 \"+dim+\",\";\n }\n}\n\nhtml = html.slice( 0, -1 ) ;\n\nmsg.payload = html;\n\nreturn msg;\n\n// getRandom\n\nfunction getRandom( min, max ) {\n var random = Math.floor( Math.random() * (max + 1 - min) ) + min;\n \n return random;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":340,"y":440,"wires":[["c1a860bb.f14d5"]]}]
まとめ
Node-REDを使ってドットを表示させるフローを作成しました。
あとはこれをajaxにしたいですね。
Node-RED で(普通の)ウェブアプリケーションを作る : まだプログラマーですが何か?