Farmbot-Web-App/frontend/farm_designer/map/layers/farmbot/bot_trail.tsx

76 lines
2.8 KiB
TypeScript
Raw Normal View History

2017-10-31 23:14:21 -06:00
import * as React from "react";
2018-10-25 18:02:54 -06:00
import { MapTransformProps } from "../../interfaces";
import { transformXY } from "../../util";
import { BotPosition } from "../../../../devices/interfaces";
import { Color } from "../../../../ui";
2019-02-04 07:32:26 -07:00
import { get, isNumber, takeRight, isEqual, round, first } from "lodash";
2017-10-31 23:14:21 -06:00
2018-03-19 21:26:09 -06:00
type TrailRecord = {
coord: Record<"x" | "y", number | undefined>,
water: number | undefined
} | undefined;
2017-10-31 23:14:21 -06:00
2017-11-01 10:54:28 -06:00
export enum VirtualTrail {
records = "virtualTrailRecords",
length = "virtualTrailLength"
}
2018-03-19 21:26:09 -06:00
function getNewTrailArray(update: TrailRecord, watering: boolean): TrailRecord[] {
2017-11-01 10:54:28 -06:00
const key = VirtualTrail.records; // sessionStorage location
2019-02-04 07:32:26 -07:00
const trailLength = get(sessionStorage, VirtualTrail.length, 100);
const arr: TrailRecord[] = JSON.parse(get(sessionStorage, key, "[]"));
2017-10-31 23:14:21 -06:00
if (arr.length > (trailLength - 1)) { arr.shift(); } // max length reached
2018-03-19 21:26:09 -06:00
const last = arr[arr.length - 1]; // most recent item in array
2020-01-03 13:04:45 -07:00
if (update?.coord &&
2019-02-04 07:32:26 -07:00
(!last || !isEqual(last.coord, update.coord))) { // coordinate comparison
2018-03-19 21:26:09 -06:00
arr.push(update); // unique addition
} else { // nothing new to add, increase water circle size if watering
2019-02-04 07:32:26 -07:00
if (watering && last && isNumber(last.water)) { last.water += 1; }
2018-03-19 21:26:09 -06:00
}
2017-10-31 23:14:21 -06:00
sessionStorage.setItem(key, JSON.stringify(arr)); // save array
2019-02-04 07:32:26 -07:00
return takeRight(arr, trailLength);
2017-10-31 23:14:21 -06:00
}
export interface BotTrailProps {
position: BotPosition;
mapTransformProps: MapTransformProps;
2018-03-19 21:26:09 -06:00
peripherals: { label: string, value: boolean }[];
2017-10-31 23:14:21 -06:00
}
export function BotTrail(props: BotTrailProps) {
2018-03-19 21:26:09 -06:00
const toQ = (ox: number, oy: number) =>
2018-04-11 20:05:08 -06:00
transformXY(ox, oy, props.mapTransformProps);
2018-03-19 21:26:09 -06:00
2017-10-31 23:14:21 -06:00
const { x, y } = props.position;
2019-02-04 07:32:26 -07:00
const watering = !!first(props.peripherals
2018-03-19 21:26:09 -06:00
.filter(p => p.label.toLowerCase().includes("water"))
.map(p => p.value));
const array = getNewTrailArray({ coord: { x, y }, water: 0 }, watering);
2018-04-28 00:54:52 -06:00
return <g className="virtual-bot-trail">
2017-10-31 23:14:21 -06:00
{array.map((cur: TrailRecord, i: number) => {
2018-03-19 21:26:09 -06:00
const prev = (array[i - 1] || { coord: undefined }).coord; // prev coord
2019-02-04 07:32:26 -07:00
const opacity = round(Math.max(0.25, i / (array.length - 1)), 2);
if (i > 0 && cur && prev && isNumber(prev.x) && isNumber(prev.y)
&& isNumber(cur.coord.x) && isNumber(cur.coord.y)
&& isNumber(cur.water)) {
2018-03-19 21:26:09 -06:00
const p1 = toQ(cur.coord.x, cur.coord.y);
const p2 = toQ(prev.x, prev.y);
return <g key={i}>
<line id={`trail-line-${i}`}
stroke="red" strokeOpacity={opacity} strokeWidth={1 + opacity * 2}
x1={p1.qx} y1={p1.qy} x2={p2.qx} y2={p2.qy} />
{cur.water &&
<circle id={`trail-water-${i}`}
fill={Color.blue} opacity={opacity / 2}
cx={p1.qx} cy={p1.qy} r={cur.water} />}
</g>;
2017-10-31 23:14:21 -06:00
}
})}
</g>;
}
2019-06-10 15:43:11 -06:00
export const resetVirtualTrail = () =>
sessionStorage.setItem(VirtualTrail.records, "[]");