Spaces:
Sleeping
Sleeping
import streamlit as st | |
import json | |
import random | |
# Initialize session state | |
if 'camera_offset' not in st.session_state: | |
st.session_state.camera_offset = {"x": 0, "y": 0} | |
if 'objects' not in st.session_state: | |
st.session_state.objects = [] | |
def update_canvas(direction=None, new_x=None, new_y=None, add_object=False, drag_x=0, drag_y=0): | |
if direction: | |
speed = 5 | |
if direction == "up": | |
st.session_state.camera_offset["y"] -= speed | |
elif direction == "down": | |
st.session_state.camera_offset["y"] += speed | |
elif direction == "left": | |
st.session_state.camera_offset["x"] -= speed | |
elif direction == "right": | |
st.session_state.camera_offset["x"] += speed | |
if new_x is not None and new_y is not None: | |
st.session_state.camera_offset["x"] = int(new_x) - 300 | |
st.session_state.camera_offset["y"] = int(new_y) - 200 | |
if add_object: | |
new_object = { | |
"x": st.session_state.camera_offset["x"] + 300, | |
"y": st.session_state.camera_offset["y"] + 200, | |
"size": 10, | |
"color": f"rgb({random.randint(0,255)},{random.randint(0,255)},{random.randint(0,255)})" | |
} | |
st.session_state.objects.append(new_object) | |
st.session_state.camera_offset["x"] += int(drag_x) | |
st.session_state.camera_offset["y"] += int(drag_y) | |
def render_canvas(): | |
state = json.dumps({ | |
"cameraOffset": st.session_state.camera_offset, | |
"objects": st.session_state.objects | |
}) | |
return f""" | |
<div id="canvasContainer"> | |
<canvas id="infiniteCanvas" width="600" height="400" style="border: 1px solid black; cursor: grab;"></canvas> | |
<p id="coordinates">Player coordinates: X: {300 + st.session_state.camera_offset['x']}, Y: {200 + st.session_state.camera_offset['y']}</p> | |
</div> | |
<script> | |
let cameraOffset = {st.session_state.camera_offset}; | |
let objects = {json.dumps(st.session_state.objects)}; | |
const playerSize = 20; | |
const gridSize = 50; | |
const canvas = document.getElementById('infiniteCanvas'); | |
const ctx = canvas.getContext('2d'); | |
const coordsDisplay = document.getElementById('coordinates'); | |
function drawGrid() {{ | |
ctx.strokeStyle = '#ddd'; | |
ctx.lineWidth = 0.5; | |
for (let x = -cameraOffset.x % gridSize; x < canvas.width; x += gridSize) {{ | |
ctx.beginPath(); | |
ctx.moveTo(x, 0); | |
ctx.lineTo(x, canvas.height); | |
ctx.stroke(); | |
}} | |
for (let y = -cameraOffset.y % gridSize; y < canvas.height; y += gridSize) {{ | |
ctx.beginPath(); | |
ctx.moveTo(0, y); | |
ctx.lineTo(canvas.width, y); | |
ctx.stroke(); | |
}} | |
}} | |
function drawPlayer() {{ | |
ctx.fillStyle = 'red'; | |
ctx.fillRect(canvas.width / 2 - playerSize / 2, canvas.height / 2 - playerSize / 2, playerSize, playerSize); | |
}} | |
function drawObjects() {{ | |
objects.forEach(obj => {{ | |
ctx.fillStyle = obj.color; | |
ctx.fillRect( | |
obj.x - cameraOffset.x, | |
obj.y - cameraOffset.y, | |
obj.size, | |
obj.size | |
); | |
}}); | |
}} | |
function draw() {{ | |
ctx.clearRect(0, 0, canvas.width, canvas.height); | |
drawGrid(); | |
drawObjects(); | |
drawPlayer(); | |
}} | |
draw(); | |
</script> | |
""" | |
st.title("Infinite Canvas") | |
# Render canvas | |
st.components.v1.html(render_canvas(), height=450) | |
# Control buttons | |
col1, col2, col3, col4 = st.columns(4) | |
with col1: | |
if st.button("β"): | |
update_canvas(direction="up") | |
with col2: | |
if st.button("β"): | |
update_canvas(direction="down") | |
with col3: | |
if st.button("β"): | |
update_canvas(direction="left") | |
with col4: | |
if st.button("β"): | |
update_canvas(direction="right") | |
# Go to coordinates | |
col1, col2, col3 = st.columns(3) | |
with col1: | |
new_x = st.number_input("X Coordinate", value=300 + st.session_state.camera_offset['x']) | |
with col2: | |
new_y = st.number_input("Y Coordinate", value=200 + st.session_state.camera_offset['y']) | |
with col3: | |
if st.button("Go to Coordinates"): | |
update_canvas(new_x=new_x, new_y=new_y) | |
# Add object button | |
if st.button("Add Object"): | |
update_canvas(add_object=True) | |
# Drag sliders | |
drag_x = st.slider("Drag X", -50, 50, 0) | |
drag_y = st.slider("Drag Y", -50, 50, 0) | |
if drag_x != 0 or drag_y != 0: | |
update_canvas(drag_x=drag_x, drag_y=drag_y) | |
st.experimental_rerun() | |
# Force rerun to update canvas | |
if st.button("Update Canvas"): | |
st.experimental_rerun() |