Procházet zdrojové kódy

WIP but this does work, needs cleanup

Kirk Trombley před 5 roky
rodič
revize
83e14d44c6

+ 117 - 10
client/src/components/screens/RoundSummary/RoundSummary.jsx

@@ -1,9 +1,11 @@
-import React, { useRef } from "react";
+import React, { useRef, useEffect } from "react";
 import styled from "styled-components";
 import useMap from "../../../hooks/useMap";
-import useMarkedPoints from "./useMarkedPoints";
-import RoundInfoPane from "./RoundInfoPane";
 import { useLastRound } from "../../../domain/gameStore";
+import flag from "../../../assets/checkered-flag.svg";
+import usePlayerScores from "../../../hooks/usePlayerScores";
+/* global google */
+
 
 const Container = styled.div`
   flex: 1;
@@ -26,20 +28,125 @@ const MapDiv = styled.div`
   }
 `
 
+const flagIcon = {
+  url: flag,
+  scaledSize: new google.maps.Size(32, 32),
+  origin: new google.maps.Point(0, 0),
+  anchor: new google.maps.Point(4, 36),
+};
+
+const questionSymbol = color => ({
+  path: "M29.898 26.5722l-4.3921 0c-0.0118,-0.635 -0.0177,-1.0172 -0.0177,-1.1583 0,-1.4229 0.2352,-2.5929 0.7056,-3.5102 0.4704,-0.9231 1.417,-1.952 2.8281,-3.1044 1.4111,-1.1465 2.2578,-1.8991 2.5282,-2.2578 0.4292,-0.5585 0.6409,-1.1818 0.6409,-1.8579 0,-0.9408 -0.3763,-1.7463 -1.1289,-2.4224 -0.7526,-0.6703 -1.7639,-1.0054 -3.0397,-1.0054 -1.2289,0 -2.2578,0.3527 -3.0868,1.0524 -0.8232,0.6997 -1.3935,1.7698 -1.7051,3.2044l-4.4391 -0.5527c0.1234,-2.0578 0.9995,-3.8041 2.6223,-5.2387 1.6286,-1.4346 3.757,-2.152 6.4029,-2.152 2.7752,0 4.9859,0.7291 6.6322,2.1814 1.6404,1.4522 2.4635,3.1397 2.4635,5.0741 0,1.0642 -0.3057,2.0755 -0.9054,3.028 -0.6056,0.9525 -1.8933,2.2519 -3.8688,3.8923 -1.0231,0.8525 -1.6581,1.5346 -1.905,2.052 -0.2469,0.5174 -0.3587,1.4405 -0.3351,2.7752zm-4.3921 6.5087l0 -4.8389 4.8389 0 0 4.8389 -4.8389 0z",
+  fillOpacity: 1.0,
+  fillColor: color,
+  scale: 1,
+  anchor: new google.maps.Point(24, 36),
+})
+
+const lineSettings = color => ({
+  strokeColor: color,
+  strokeOpacity: 0,
+  icons: [{
+    icon: {
+      path: 'M 0,-1 0,1',
+      strokeOpacity: 1,
+      scale: 4
+    },
+    offset: '0',
+    repeat: '20px'
+  }],
+});
+
+const makeMarker = (map, position, title, icon) => {
+  const marker = new google.maps.Marker({
+    clickable: true,
+    map,
+    position,
+    title,
+    icon,
+  });
+
+  const { lat, lng } = position;
+  marker.addListener("click", () => {
+    window.open(`https://www.google.com/maps?hl=en&q=+${lat},+${lng}`, "_blank");
+  });
+
+  return marker;
+}
+
+const goldenRatioConj = 0.618033988749895;
+let h = 0;
+const nextColor = () => {
+  h += goldenRatioConj;
+  h %= 1;
+  const s = 0.5;
+  const v = 0.9;
+  const h_i = Math.floor(h*6)
+  const f = h*6 - h_i
+  const p = v * (1 - s)
+  const q = v * (1 - f*s)
+  const t = v * (1 - (1 - f) * s)
+  return "#" + ([
+    [v, t, p],
+    [q, v, p],
+    [p, v, t],
+    [p, q, v],
+    [t, p, v],
+    [v, p, q],
+  ])[h_i].map(component => {
+    const converted = Math.floor(component * 256).toString(16);
+    if (converted.length === 1) {
+      return "0" + converted;
+    }
+    return converted;
+  }).reduce((x, y) => x + y);
+}
+
+const playerColors = {};
+
 export default () => {
-  const {
-    selectedPoint,
-    targetPoint,
-  } = useLastRound();
-  const mapDivRef = useRef(null);
+  // get the info about the last round
+  const { roundNum, targetPoint } = useLastRound();
+
+  // draw the map
   // TODO dynamically determine this zoom level?
+  const mapDivRef = useRef(null);
   const mapRef = useMap(mapDivRef, targetPoint.lat, targetPoint.lng, 4);
-  useMarkedPoints(mapRef, selectedPoint, targetPoint);
 
+  // set up the flag at the target point
+  useEffect(() => {
+    const targetMarker = makeMarker(mapRef.current, targetPoint, "Goal", flagIcon);
+    return () => targetMarker.setMap(null);
+  }, [mapRef, targetPoint]);
+
+  // live update the player scores
+  const players = usePlayerScores()
+    ?.filter(({ guesses }) => guesses[roundNum] && guesses[roundNum].score);
+  useEffect(() => {
+    if (!players) return;
+    const drawings = [];
+    players.forEach(({ name, guesses }) => {
+      const { lat, lng, score } = guesses[roundNum]
+      const color = playerColors[name] ?? nextColor();
+      playerColors[name] = color;
+      const selectedPoint = { lat, lng };
+
+      const marker = makeMarker(mapRef.current, selectedPoint, `${name} - ${score} Points`, questionSymbol(color))
+      drawings.push(marker);
+
+      const line = new google.maps.Polyline({
+        path: [ selectedPoint, targetPoint ],
+        map: mapRef.current,
+        ...lineSettings(color),
+      });
+      drawings.push(line);
+    });
+    return () => drawings.forEach((drawing) => drawing.setMap(null));
+  }, [players, mapRef, targetPoint, roundNum]);
+  
   return (
     <Container>
       <MapDiv ref={mapDivRef} />
-      <RoundInfoPane/>
     </Container>
   );
 };

+ 17 - 8
client/src/components/screens/RoundSummary/useMarkedPoints.jsx

@@ -10,15 +10,24 @@ const questionIcon = {
   anchor: new google.maps.Point(32, 48),
 };
 
+const questionSymbol = color => ({
+  path: "M29.898 26.5722l-4.3921 0c-0.0118,-0.635 -0.0177,-1.0172 -0.0177,-1.1583 0,-1.4229 0.2352,-2.5929 0.7056,-3.5102 0.4704,-0.9231 1.417,-1.952 2.8281,-3.1044 1.4111,-1.1465 2.2578,-1.8991 2.5282,-2.2578 0.4292,-0.5585 0.6409,-1.1818 0.6409,-1.8579 0,-0.9408 -0.3763,-1.7463 -1.1289,-2.4224 -0.7526,-0.6703 -1.7639,-1.0054 -3.0397,-1.0054 -1.2289,0 -2.2578,0.3527 -3.0868,1.0524 -0.8232,0.6997 -1.3935,1.7698 -1.7051,3.2044l-4.4391 -0.5527c0.1234,-2.0578 0.9995,-3.8041 2.6223,-5.2387 1.6286,-1.4346 3.757,-2.152 6.4029,-2.152 2.7752,0 4.9859,0.7291 6.6322,2.1814 1.6404,1.4522 2.4635,3.1397 2.4635,5.0741 0,1.0642 -0.3057,2.0755 -0.9054,3.028 -0.6056,0.9525 -1.8933,2.2519 -3.8688,3.8923 -1.0231,0.8525 -1.6581,1.5346 -1.905,2.052 -0.2469,0.5174 -0.3587,1.4405 -0.3351,2.7752zm-4.3921 6.5087l0 -4.8389 4.8389 0 0 4.8389 -4.8389 0z",
+  fillOpacity: 1.0,
+  fillColor: color,
+  scale: 1,
+  anchor: new google.maps.Point(24, 36),
+
+})
+
 const flagIcon = {
   url: flag,
   scaledSize: new google.maps.Size(32, 32),
   origin: new google.maps.Point(0, 0),
-  anchor: new google.maps.Point(4, 32),
+  anchor: new google.maps.Point(4, 36),
 };
 
-const lineSettings = {
-  strokeColor: "#333333",
+const lineSettings = color => ({
+  strokeColor: color,
   strokeOpacity: 0,
   icons: [{
     icon: {
@@ -29,7 +38,7 @@ const lineSettings = {
     offset: '0',
     repeat: '20px'
   }],
-};
+});
 
 const openMapInNewTab = ({ lat, lng }) => {
   window.open(`https://www.google.com/maps?hl=en&q=+${lat},+${lng}`, "_blank");
@@ -49,10 +58,10 @@ const makeMarker = (map, position, title, icon) => {
   return marker;
 }
 
-export default (mapRef, selectedPoint, targetPoint) => {
+export default (mapRef, selectedPoint, targetPoint, color = "#333333") => {
   useEffect(() => {
     const selectedMarker = selectedPoint
-      ? makeMarker(mapRef.current, selectedPoint, "Selected", questionIcon)
+      ? makeMarker(mapRef.current, selectedPoint, "Selected", questionSymbol(color))
       : null;
     const targetMarker = makeMarker(mapRef.current, targetPoint, "Goal", flagIcon);
 
@@ -60,7 +69,7 @@ export default (mapRef, selectedPoint, targetPoint) => {
       ? new google.maps.Polyline({
         path: [ selectedPoint, targetPoint ],
         map: mapRef.current,
-        ...lineSettings,
+        ...lineSettings(color),
       })
       : null;
 
@@ -73,5 +82,5 @@ export default (mapRef, selectedPoint, targetPoint) => {
         selectedMarker.setMap(null);
       }
     }
-  }, [mapRef, selectedPoint, targetPoint]);
+  }, [mapRef, selectedPoint, targetPoint, color]);
 }

+ 6 - 6
client/src/domain/gameStore.js

@@ -12,23 +12,23 @@ export const [
   },
   dispatch,
 ] = createStore({
-  gameId: null,
-  playerName: null,
+  gameId: "71925bd5-dc01-491a-8d94-9221cd222073",
+  playerName: "asdf",
   lastRound: {
-    roundNum: -1,
+    roundNum: 1,
     selectedPoint: {
-      lat: 0,
+      lat: -10,
       lng: 0,
     },
     targetPoint: {
       lat: 0,
-      lng: 0,
+      lng: -10,
     },
     score: -1,
     totalScore: -1,
   },
   gameJoined: false,
-  gameState: PRE_GAME,
+  gameState: POST_ROUND,
 }, {
   setPlayerName: ([set], playerName) => set({ playerName }),
   goToLobby: ([set, get], gameId) => set({