aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMetroWind <chris.corsair@gmail.com>2025-08-31 22:08:18 -0700
committerMetroWind <chris.corsair@gmail.com>2025-08-31 22:08:18 -0700
commitbdbac00d7935a0c52a0f5198d56d00a4b033c8a2 (patch)
tree8e97f4478356bba75094c68cf782a8cb3198ced7
parent7854244c0318f590e0f198ec72dfd55afdd1bc91 (diff)
Fix asset drop clientx issue.
On Windows Firefox, the clientX property of the dragend event is unreliable. Use the drop event.
-rw-r--r--scripts/main.js33
1 files changed, 18 insertions, 15 deletions
diff --git a/scripts/main.js b/scripts/main.js
index 8f3bbee..d6b6787 100644
--- a/scripts/main.js
+++ b/scripts/main.js
@@ -4,15 +4,13 @@ const DEFAULT_APP_STATE = {
4 new Array(GRID_SIZE_X * GRID_SIZE_Y).fill(0)), 4 new Array(GRID_SIZE_X * GRID_SIZE_Y).fill(0)),
5 // mouse_state can be “normal”, or “dnd”. 5 // mouse_state can be “normal”, or “dnd”.
6 mouse_state: "normal", 6 mouse_state: "normal",
7 dragged_asset_index: null,
7 plan_code: "", 8 plan_code: "",
8}; 9};
9 10
10async function serializePlan(app_state) 11async function serializePlan(app_state)
11{ 12{
12 let rest = new Array(GRID_SIZE_X * GRID_SIZE_Y * (FLOOR_COUNT - 1)).fill(0); 13 return compressBytes(Uint8Array.from(app_state.plan.flat()));
13 let concated_plans =
14 app_state.plan.reduce((big, floor_plan) => big.concat(floor_plan), []);
15 return compressBytes(Uint8Array.from(concated_plans));
16} 14}
17 15
18function genGrid(x_count, y_count, cell_size) 16function genGrid(x_count, y_count, cell_size)
@@ -58,7 +56,7 @@ function AssetsView({on_drag_begin, on_drag_end})
58 return h("div", {}, views); 56 return h("div", {}, views);
59} 57}
60 58
61function PlanGridView({content, mouse_state}) 59function PlanGridView({content, mouse_state, on_drop_asset})
62{ 60{
63 const [mouse_coord, setMouseCoord] = preactHooks.useState(null); 61 const [mouse_coord, setMouseCoord] = preactHooks.useState(null);
64 62
@@ -109,6 +107,7 @@ ${cell_y * (CELL_SIZE + 1) + 1})`}, bg, TILES[idx].inner_svg);
109 let img_height = GRID_SIZE_Y * (CELL_SIZE + 1) + 1; 107 let img_height = GRID_SIZE_Y * (CELL_SIZE + 1) + 1;
110 return h("svg", {"width": img_width, "height": img_height, 108 return h("svg", {"width": img_width, "height": img_height,
111 "version": "1.1", "ondragover": onDragOver, 109 "version": "1.1", "ondragover": onDragOver,
110 "ondrop": on_drop_asset,
112 "id": "Grid", "ondragleave": onDragLeave,}, 111 "id": "Grid", "ondragleave": onDragLeave,},
113 h("rect", {x: 0, y: 0, width: img_width, height: img_height, 112 h("rect", {x: 0, y: 0, width: img_width, height: img_height,
114 fill: "#c0c0c0", "stroke-width": 0}), 113 fill: "#c0c0c0", "stroke-width": 0}),
@@ -116,11 +115,12 @@ ${cell_y * (CELL_SIZE + 1) + 1})`}, bg, TILES[idx].inner_svg);
116 hilight_box); 115 hilight_box);
117} 116}
118 117
119function PlanView({plan, mouse_state}) 118function PlanView({plan, mouse_state, on_drop_asset})
120{ 119{
121 return h("div", {"id": "PlanView"}, 120 return h("div", {"id": "PlanView"},
122 h("div", {"id": "EntryIndicator"}, "⬇️"), 121 h("div", {"id": "EntryIndicator"}, "⬇️"),
123 h(PlanGridView, {content: plan, mouse_state: mouse_state})); 122 h(PlanGridView, {content: plan, mouse_state: mouse_state,
123 on_drop_asset: on_drop_asset}));
124} 124}
125 125
126// on_floor_change takes one argument, which is the 0-based floor number. 126// on_floor_change takes one argument, which is the 0-based floor number.
@@ -137,28 +137,31 @@ function App({initial_state})
137{ 137{
138 const [state, setState] = preactHooks.useState(initial_state); 138 const [state, setState] = preactHooks.useState(initial_state);
139 139
140 // This event is targeted at the dragged asset.
140 function onDragAssetBegin(e) 141 function onDragAssetBegin(e)
141 { 142 {
142 let new_state = structuredClone(state); 143 let new_state = structuredClone(state);
143 new_state.mouse_state = "dnd"; 144 new_state.mouse_state = "dnd";
145 new_state.dragged_asset_index =
146 parseInt(e.target.getAttribute("data-asset-index"));
144 setState(new_state); 147 setState(new_state);
145 } 148 }
146 function onDragAssetEnd(e) 149
150 // This event is targeted at the grid.
151 function onDropAssetOnGrid(e)
147 { 152 {
148 if(e.dragEffect === "none") return; 153 if(e.dragEffect === "none") return;
149 let grid = document.getElementById("Grid"); 154 let grid = document.getElementById("Grid");
150 let b = grid.getBoundingClientRect(); 155 let b = grid.getBoundingClientRect();
151 let x = e.clientX - b.left; 156 let x = e.clientX - b.left;
152 let y = e.clientY - b.top; 157 let y = e.clientY - b.top;
153 if(x < 0 || y < 0 || x > b.width || y > b.height) return;
154 let cell_x = Math.floor(x / (CELL_SIZE + 1)); 158 let cell_x = Math.floor(x / (CELL_SIZE + 1));
155 let cell_y = Math.floor(y / (CELL_SIZE + 1)); 159 let cell_y = Math.floor(y / (CELL_SIZE + 1));
156 let cell_index = cell_y * GRID_SIZE_X + cell_x; 160 let cell_index = cell_y * GRID_SIZE_X + cell_x;
157 let asset_index = parseInt(e.target.getAttribute("data-asset-index"));
158
159 let new_state = structuredClone(state); 161 let new_state = structuredClone(state);
160 new_state.plan[new_state.floor][cell_index] = asset_index; 162 new_state.plan[new_state.floor][cell_index] = state.dragged_asset_index;
161 new_state.mouse_state = "normal"; 163 new_state.mouse_state = "normal";
164 new_state.dragged_asset_index = null;
162 serializePlan(new_state).then((s) => { 165 serializePlan(new_state).then((s) => {
163 new_state.plan_code = s; 166 new_state.plan_code = s;
164 setState(new_state); 167 setState(new_state);
@@ -206,10 +209,10 @@ function App({initial_state})
206 on_floor_change: onFloorChange}), 209 on_floor_change: onFloorChange}),
207 h("div", {"class": "LabeledPanel"}, 210 h("div", {"class": "LabeledPanel"},
208 h("h2", {}, "Rooms"), 211 h("h2", {}, "Rooms"),
209 h(AssetsView, {on_drag_begin: onDragAssetBegin, 212 h(AssetsView, {on_drag_begin: onDragAssetBegin,}))),
210 on_drag_end: onDragAssetEnd}))),
211 h(PlanView, {plan: state.plan[state.floor], 213 h(PlanView, {plan: state.plan[state.floor],
212 mouse_state: state.mouse_state})), 214 mouse_state: state.mouse_state,
215 on_drop_asset: onDropAssetOnGrid,})),
213 h("hr", {}), 216 h("hr", {}),
214 h("div", {}, 217 h("div", {},
215 h("textarea", {readonly: true}, state.plan_code)), 218 h("textarea", {readonly: true}, state.plan_code)),