mirror of
https://github.com/adanrsantos/ThePlaceHolders.git
synced 2024-12-16 12:20:37 -06:00
Compare commits
3 commits
51d48b69c3
...
bc1fffe07d
Author | SHA1 | Date | |
---|---|---|---|
bc1fffe07d | |||
1ae91a8b38 | |||
ac618b4ae4 |
34
pixel.go
Normal file
34
pixel.go
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PixelData struct {
|
||||||
|
X int `json:"x"`
|
||||||
|
Y int `json:"y"`
|
||||||
|
Color []int `json:"color"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var pixelStore []PixelData
|
||||||
|
|
||||||
|
func savePixelHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var pixel PixelData
|
||||||
|
|
||||||
|
if err := json.NewDecoder(r.Body).Decode(&pixel); err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
pixelStore = append(pixelStore, pixel)
|
||||||
|
log.Printf("Stored pixel: %+v", pixel)
|
||||||
|
|
||||||
|
log.Printf("Current stored pixels: %+v", pixelStore)
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
if err := json.NewEncoder(w).Encode(pixelStore); err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
}
|
25
server.go
25
server.go
|
@ -5,7 +5,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gorilla/sessions"
|
"github.com/gorilla/sessions"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -19,6 +18,25 @@ type Server struct {
|
||||||
Sessions *sessions.CookieStore
|
Sessions *sessions.CookieStore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enable CORS for specific routes
|
||||||
|
func enableCORS(next http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// Set the CORS headers to allow requests from your frontend
|
||||||
|
w.Header().Set("Access-Control-Allow-Origin", "http://127.0.0.1:8080") // Adjust if your frontend is on a different port
|
||||||
|
w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS")
|
||||||
|
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
|
||||||
|
|
||||||
|
// Handle preflight OPTIONS request
|
||||||
|
if r.Method == http.MethodOptions {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process the actual request
|
||||||
|
next.ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// Grab command line arguments
|
// Grab command line arguments
|
||||||
ipFlag := flag.String("ip", "127.0.0.1", "IP address to receive traffic from")
|
ipFlag := flag.String("ip", "127.0.0.1", "IP address to receive traffic from")
|
||||||
|
@ -26,6 +44,7 @@ func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
address := *ipFlag
|
address := *ipFlag
|
||||||
port := *portFlag
|
port := *portFlag
|
||||||
|
|
||||||
// Create server object
|
// Create server object
|
||||||
secret := []byte("super-secret-key")
|
secret := []byte("super-secret-key")
|
||||||
server := Server{
|
server := Server{
|
||||||
|
@ -48,6 +67,10 @@ func main() {
|
||||||
})
|
})
|
||||||
http.HandleFunc("/secret", server.secret)
|
http.HandleFunc("/secret", server.secret)
|
||||||
http.HandleFunc("/confirm-email", server.handle_confirmation)
|
http.HandleFunc("/confirm-email", server.handle_confirmation)
|
||||||
|
|
||||||
|
// Apply CORS middleware to /savePixel handler
|
||||||
|
http.Handle("/savePixel", enableCORS(http.HandlerFunc(savePixelHandler)))
|
||||||
|
|
||||||
// Start web server at 127.0.0.1:8080
|
// Start web server at 127.0.0.1:8080
|
||||||
fmt.Printf("Listening to %s on port %s...\n", address, port)
|
fmt.Printf("Listening to %s on port %s...\n", address, port)
|
||||||
err := http.ListenAndServe(address+":"+port, nil)
|
err := http.ListenAndServe(address+":"+port, nil)
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
|
|
||||||
html, body {
|
html, body {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.wrapper {
|
.wrapper {
|
||||||
|
@ -73,10 +75,11 @@ html, body {
|
||||||
|
|
||||||
.toolbar {
|
.toolbar {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-around;
|
flex-direction: row;
|
||||||
align-items: center;
|
justify-content: start;
|
||||||
|
align-items: start;
|
||||||
border-top: solid black 1px;
|
border-top: solid black 1px;
|
||||||
background-color: var(--utsa-blue);
|
background-color: gray;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: auto;
|
height: auto;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
@ -86,12 +89,12 @@ html, body {
|
||||||
.toolbarItems {
|
.toolbarItems {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: start;
|
||||||
font-weight: 900;
|
font-weight: 900;
|
||||||
color: white;
|
color: white;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
height: 100%;
|
height: 20px;
|
||||||
width: 100px;
|
width: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.strokePicker {
|
.strokePicker {
|
||||||
|
|
|
@ -37,6 +37,48 @@
|
||||||
<!--</div>-->
|
<!--</div>-->
|
||||||
<!--note to self: above IS the canvas-->
|
<!--note to self: above IS the canvas-->
|
||||||
</div>
|
</div>
|
||||||
|
<div id="toolbar" class="d-flex toolbar flex-wrap">
|
||||||
|
<div class="toolbarItems">
|
||||||
|
<button id="colorPicker" style="height:20px; width:20px; background-color:rgb(255, 255, 255);" type="button"></button>
|
||||||
|
</div>
|
||||||
|
<div class="toolbarItems">
|
||||||
|
<button id="colorPicker" style="height:20px; width:20px; background-color:rgb(0, 0, 0);" type="button"></button>
|
||||||
|
</div>
|
||||||
|
<div class="toolbarItems">
|
||||||
|
<button id="colorPicker" style="height:20px; width:20px; background-color:rgb(128,128,128);" type="button"></button>
|
||||||
|
</div>
|
||||||
|
<div class="toolbarItems">
|
||||||
|
<button id="colorPicker" style="height:20px; width:20px; background-color:rgb(128,0,0);" type="button"></button>
|
||||||
|
</div>
|
||||||
|
<div class="toolbarItems">
|
||||||
|
<button id="colorPicker" style="height:20px; width:20px; background-color:rgb(128,128,0);" type="button"></button>
|
||||||
|
</div>
|
||||||
|
<div class="toolbarItems">
|
||||||
|
<button id="colorPicker" style="height:20px; width:20px; background-color:rgb(0,128,0);" type="button"></button>
|
||||||
|
</div>
|
||||||
|
<div class="toolbarItems">
|
||||||
|
<button id="colorPicker" style="height:20px; width:20px; background-color:rgb(0,128,128);" type="button"></button>
|
||||||
|
</div>
|
||||||
|
<div class="toolbarItems">
|
||||||
|
<button id="colorPicker" style="height:20px; width:20px; background-color:rgb(0,0,128);" type="button"></button>
|
||||||
|
</div>
|
||||||
|
<div class="toolbarItems">
|
||||||
|
<button id="colorPicker" style="height:20px; width:20px; background-color:rgb(128,0,128);" type="button"></button>
|
||||||
|
</div>
|
||||||
|
<div class="toolbarItems">
|
||||||
|
<button id="colorPicker" style="height:20px; width:20px; background-color:rgb(128,128,64);" type="button"></button>
|
||||||
|
</div>
|
||||||
|
<div class="toolbarItems">
|
||||||
|
<button id="colorPicker" style="height:20px; width:20px; background-color:rgb(128,128,64);" type="button"></button>
|
||||||
|
</div>
|
||||||
|
<div class="toolbarItems">
|
||||||
|
<button id="colorPicker" style="height:20px; width:20px; background-color:rgb(128,128,64);" type="button"></button>
|
||||||
|
</div>
|
||||||
|
<!--<div class="toolbarItems">
|
||||||
|
<label for="stroke">Strokes</label>
|
||||||
|
<input id="stroke" name="stroke" type="color" class="strokePicker">
|
||||||
|
</div>-->
|
||||||
|
</div>
|
||||||
<script src="./canvas.js"></script>
|
<script src="./canvas.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -16,6 +16,63 @@ let image = new ImageData(DATA_SIZE, DATA_SIZE);
|
||||||
// Drawable image
|
// Drawable image
|
||||||
let bitmap = null;
|
let bitmap = null;
|
||||||
|
|
||||||
|
async function sendPixelData(x, y, color) {
|
||||||
|
try {
|
||||||
|
const response = await fetch("http://localhost:8080/savePixel", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ x: x, y: y, color: color })
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
const updatedPixels = await response.json();
|
||||||
|
// Refresh the canvas with updated pixel data
|
||||||
|
updateCanvasWithData(updatedPixels);
|
||||||
|
} else {
|
||||||
|
console.error("Failed to send pixel data:", response.statusText);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error sending pixel data:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateCanvasWithData(pixelDataArray) {
|
||||||
|
// Clear the canvas image data
|
||||||
|
for (let x = 0; x < DATA_SIZE * DATA_SIZE * 4; x++) {
|
||||||
|
image.data[x] = 255; // Reset to white
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set each pixel from the server data
|
||||||
|
pixelDataArray.forEach(pixel => {
|
||||||
|
setPixel(image.data, pixel.x, pixel.y, pixel.color);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Redraw and update canvas
|
||||||
|
redraw();
|
||||||
|
draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas.addEventListener("mouseup", async (e) => {
|
||||||
|
if (e.button == 0 && mouseClicked) {
|
||||||
|
mouseClicked = false;
|
||||||
|
let mouse = mousePosition(e);
|
||||||
|
let cx = mouse.x;
|
||||||
|
let cy = mouse.y;
|
||||||
|
|
||||||
|
if (cx < 0 || cx > CANVAS_SIZE || cy < 0 || cy > CANVAS_SIZE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const color = [0, 0, 255, 255];
|
||||||
|
setPixel(image.data, cx, cy, color);
|
||||||
|
|
||||||
|
// Send pixel data to the server
|
||||||
|
await sendPixelData(cx, cy, color);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
window.addEventListener("load", async (e) => {
|
window.addEventListener("load", async (e) => {
|
||||||
for (let x = 0; x < DATA_SIZE * DATA_SIZE * 4; x++) {
|
for (let x = 0; x < DATA_SIZE * DATA_SIZE * 4; x++) {
|
||||||
image.data[x] = 255;
|
image.data[x] = 255;
|
||||||
|
@ -29,7 +86,9 @@ window.addEventListener("load", async (e) => {
|
||||||
|
|
||||||
|
|
||||||
async function redraw() {
|
async function redraw() {
|
||||||
|
// Create a new ImageBitmap based on the updated image data
|
||||||
bitmap = await createImageBitmap(image);
|
bitmap = await createImageBitmap(image);
|
||||||
|
console.log("Redrawing canvas...");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Color is an array of four numbers 0-255 (RGB + transparency)
|
// Color is an array of four numbers 0-255 (RGB + transparency)
|
||||||
|
@ -104,7 +163,7 @@ canvas.addEventListener("mouseup", async (e) => {
|
||||||
if (cx < 0 || cx > CANVAS_SIZE || cy < 0 || cy > CANVAS_SIZE) {
|
if (cx < 0 || cx > CANVAS_SIZE || cy < 0 || cy > CANVAS_SIZE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setPixel(image.data, cx, cy, [255, 0, 0, 255]);
|
setPixel(image.data, cx, cy, [0, 0, 255, 255]);
|
||||||
await redraw();
|
await redraw();
|
||||||
draw();
|
draw();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue