1---
2import HeadTags from "../components/HeadTags.astro";
3---
4
5<!DOCTYPE html>
6<html lang="en">
7 <head>
8 <title>nostr pixels</title>
9 <meta name="description" content="paint on a relay" />
10 <meta property="og:title" content="nostr pixels" />
11 <meta property="og:description" content="paint on a relay" />
12 <HeadTags />
13 </head>
14 <body>
15 <style>
16 body {
17 text-align: center;
18 }
19 </style>
20 <canvas id="canvas" width="640" height="480"></canvas>
21 <br />
22 <input type="color" id="pixel_color" />
23 <br />
24 <input id="secret_message" type="text" />
25 <script is:inline>
26 const canvas = document.getElementById("canvas");
27 const ctx = canvas.getContext("2d");
28 const pixelColor = document.getElementById("pixel_color");
29 const secretMessage = document.getElementById("secret_message");
30 const pixelSize = 5;
31 const params = new URLSearchParams(window.location.search);
32 const relay = params.get("relay");
33 const con = new WebSocket(relay || "wss://relay.damus.io");
34
35 let pixels = [];
36
37 ctx.fillStyle = "#FFFFFF";
38 ctx.fillRect(0, 0, canvas.width, canvas.height);
39
40 function place(x, y, color) {
41 const gridX = Math.floor(x / pixelSize) * pixelSize;
42 const gridY = Math.floor(y / pixelSize) * pixelSize;
43
44 pixels.push({ x: gridX, y: gridY, color: color });
45 ctx.fillStyle = color;
46 ctx.fillRect(gridX, gridY, pixelSize, pixelSize);
47 }
48
49 async function sendPixelEvent(x, y, color) {
50 if (window.nostr) {
51 try {
52 const event = await window.nostr.signEvent({
53 content: secretMessage.value,
54 created_at: Math.floor(Date.now() / 1000),
55 kind: 2763,
56 tags: [
57 ["x", x.toString()],
58 ["y", y.toString()],
59 ["color", color],
60 ],
61 });
62 const event2 = await window.nostr.signEvent({
63 content:
64 "pixel x: " +
65 x.toString() +
66 "\npixel y: " +
67 y.toString() +
68 "\npixel color: " +
69 color +
70 "\npixel message: " +
71 secretMessage.value,
72 created_at: Math.floor(Date.now() / 1000),
73 kind: 1,
74 tags: [["via", "nostr-pixels"]],
75 });
76 const send = con.send(JSON.stringify(["EVENT", event]));
77 const send2 = con.send(JSON.stringify(["EVENT", event2]));
78 if (send || send2) {
79 console.log("event sent to relay " + relay);
80 }
81 } catch (error) {
82 console.error(error);
83 }
84 }
85 }
86
87 con.onopen = async () => {
88 con.send(JSON.stringify(["REQ", "pixels", { kinds: [2763] }]));
89 };
90
91 con.onmessage = (msg) => {
92 const data = JSON.parse(msg.data);
93 if (data[0] === "EVENT") {
94 const event = data[2];
95 if (event.kind === 2763) {
96 const xTag = event.tags.find((t) => t[0] === "x");
97 const yTag = event.tags.find((t) => t[0] === "y");
98 const colorTag = event.tags.find(
99 (t) => t[0] === "color",
100 );
101 if (xTag && yTag && colorTag) {
102 const x = parseFloat(xTag[1]);
103 const y = parseFloat(yTag[1]);
104 const color = colorTag[1];
105 place(x, y, color);
106 }
107 }
108 }
109 };
110
111 canvas.addEventListener("click", (e) => {
112 const rect = canvas.getBoundingClientRect();
113 const x = e.clientX - rect.left;
114 const y = e.clientY - rect.top;
115 place(x, y, pixelColor.value);
116 sendPixelEvent(x, y, pixelColor.value);
117 });
118 </script>
119 </body>
120</html>