Skip to content

Commit 9b0365f

Browse files
committed
[ui] Add an initial draft of a field to the UI
1 parent 8d5ae04 commit 9b0365f

File tree

2 files changed

+230
-0
lines changed

2 files changed

+230
-0
lines changed

ui/src/App.vue

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
<ControlGeneral/>
99
<ControlMatch class="match-controls"/>
1010
<Debug class="debug"/>
11+
<Field/>
1112
</div>
1213
</template>
1314

@@ -18,10 +19,12 @@
1819
import ControlTeam from "./components/control/ControlTeam";
1920
import Debug from "./components/Debug";
2021
import ControlMatch from "./components/control/ControlMatch";
22+
import Field from "./components/field/Field";
2123
2224
export default {
2325
name: 'app',
2426
components: {
27+
Field,
2528
ControlMatch,
2629
Debug,
2730
ControlTeam,

ui/src/components/field/Field.vue

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
<template>
2+
<svg class="field-canvas"
3+
:viewBox="viewBox">
4+
5+
<!-- rotate field -->
6+
<g :transform="getFieldTransformation">
7+
8+
<!-- draw field background -->
9+
<rect :x="-(fieldLength/2+boundaryWidth)"
10+
:y="-(fieldWidth/2+boundaryWidth)"
11+
:width="fieldLength+boundaryWidth*2"
12+
:height="fieldWidth+boundaryWidth*2"
13+
style="fill:green;fill-opacity:1;stroke:none"></rect>
14+
15+
<!-- draw field borders -->
16+
<line v-show="!useShapesFromGeometry"
17+
:x1="-fieldLength/2"
18+
:y1="-fieldWidth/2"
19+
:x2="-fieldLength/2"
20+
:y2="fieldWidth/2"
21+
style="stroke:white;stroke-width:10px"></line>
22+
<line v-show="!useShapesFromGeometry"
23+
:x1="-fieldLength/2"
24+
:y1="fieldWidth/2"
25+
:x2="fieldLength/2"
26+
:y2="fieldWidth/2"
27+
style="stroke:white;stroke-width:10px"></line>
28+
<line v-show="!useShapesFromGeometry"
29+
:x1="fieldLength/2"
30+
:y1="fieldWidth/2"
31+
:x2="fieldLength/2"
32+
:y2="-fieldWidth/2"
33+
style="stroke:white;stroke-width:10px"></line>
34+
<line v-show="!useShapesFromGeometry"
35+
:x1="fieldLength/2"
36+
:y1="-fieldWidth/2"
37+
:x2="-fieldLength/2"
38+
:y2="-fieldWidth/2"
39+
style="stroke:white;stroke-width:10px"></line>
40+
<line v-show="!useShapesFromGeometry"
41+
:x1="0"
42+
:y1="fieldWidth/2"
43+
:x2="0"
44+
:y2="-fieldWidth/2"
45+
style="stroke:white;stroke-width:10px"></line>
46+
<!-- center circle -->
47+
<circle v-show="!useShapesFromGeometry"
48+
:r="centerCircleRadius"
49+
style="stroke:white;stroke-width:10px;fill-opacity:0"></circle>
50+
<!-- penalty areas -->
51+
<rect v-show="!useShapesFromGeometry"
52+
:x="-(fieldLength)/2"
53+
:y="-(penAreaWidth)/2"
54+
:width="penAreaDepth"
55+
:height="penAreaWidth"
56+
style="stroke: white;stroke-width:10px; fill-opacity:0"></rect>
57+
<rect v-show="!useShapesFromGeometry"
58+
:x="(fieldLength/2)-penAreaDepth"
59+
:y="-penAreaWidth/2"
60+
:width="penAreaDepth"
61+
:height="penAreaWidth"
62+
style="stroke: white;stroke-width:10px; fill-opacity:0"></rect>
63+
64+
<!-- goals -->
65+
<line :x1="-fieldLength/2"
66+
:y1="-goalWidth/2"
67+
:x2="-fieldLength/2-goalDepth"
68+
:y2="-goalWidth/2"
69+
style="stroke:black;stroke-width:10px"></line>
70+
<line :x1="-fieldLength/2"
71+
:y1="goalWidth/2"
72+
:x2="-fieldLength/2-goalDepth"
73+
:y2="goalWidth/2"
74+
style="stroke:black;stroke-width:10px"></line>
75+
<line :x1="-fieldLength/2-goalDepth"
76+
:y1="-goalWidth/2"
77+
:x2="-fieldLength/2-goalDepth"
78+
:y2="goalWidth/2"
79+
style="stroke:black;stroke-width:10px"></line>
80+
81+
<line :x1="fieldLength/2"
82+
:y1="-goalWidth/2"
83+
:x2="fieldLength/2+goalDepth"
84+
:y2="-goalWidth/2"
85+
style="stroke:black;stroke-width:10px"></line>
86+
<line :x1="fieldLength/2"
87+
:y1="goalWidth/2"
88+
:x2="fieldLength/2+goalDepth"
89+
:y2="goalWidth/2"
90+
style="stroke:black;stroke-width:10px"></line>
91+
<line :x1="fieldLength/2+goalDepth"
92+
:y1="-goalWidth/2"
93+
:x2="fieldLength/2+goalDepth"
94+
:y2="goalWidth/2"
95+
style="stroke:black;stroke-width:10px"></line>
96+
97+
<!-- lines from geometry -->
98+
<line v-for="l of lines"
99+
v-bind:key="l"
100+
:x1="l.p1.x"
101+
:y1="l.p1.y"
102+
:x2="l.p2.x"
103+
:y2="l.p2.y"
104+
style="stroke:white;stroke-width:10px"></line>
105+
106+
<!-- arcs from geometry (only circles supported for now -->
107+
<circle v-for="a of arcs"
108+
v-bind:key="a"
109+
:cx="a.center.x"
110+
:cy="a.center.y"
111+
:r="a.radius"
112+
style="stroke:white;stroke-width:10px;fill-opacity:0"></circle>
113+
114+
<!-- robots -->
115+
<path v-for="r of getRobotsYellow"
116+
v-bind:key="r"
117+
:d="
118+
'M ' + r.x + r.botRightX() + ',' + r.y + r.botRightY() +
119+
'A ' + r.botRadius + ' ' + r.botRadius + ' 0 1 1 ' + r.x + r.botLeftX() + ',' + r.y + r.botLeftY() +
120+
'L ' + r.x + r.botRightX() + ','+ r.y + r.botRightY()"
121+
style="stroke:black;stroke-width:0.3em;fill: yellow; fill-opacity:1"></path>
122+
123+
<path v-for="r of getRobotsBlue"
124+
v-bind:key="r"
125+
:d="
126+
'M ' + r.x + r.botRightX() + ',' + r.y + r.botRightY() +
127+
'A ' + r.botRadius + ' ' + r.botRadius + ' 0 1 1 ' + r.x + r.botLeftX() + ',' + r.y + r.botLeftY() +
128+
'L ' + r.x + r.botRightX() + ','+ r.y + r.botRightY()"
129+
style="stroke:black;stroke-width:0.3em;fill: blue; fill-opacity:1"></path>
130+
131+
<!-- robot ids -->
132+
<text v-for="r of getRobotsYellow"
133+
v-bind:key="r"
134+
:x="r.x"
135+
:y="r.y"
136+
:dx="'-40'"
137+
:dy="'45'"
138+
:textLength="r.botRadius+20"
139+
:lengthAdjust="'spacingAndGlyphs'"
140+
class="bot-id"
141+
style="stroke-width:0;fill: black">
142+
{{r.id}}
143+
</text>
144+
145+
<text v-for="r of getRobotsBlue"
146+
v-bind:key="r"
147+
:x="r.x"
148+
:y="r.y"
149+
:dx="'-40'"
150+
:dy="'45'"
151+
:textLength="r.botRadius+20"
152+
:lengthAdjust="'spacingAndGlyphs'"
153+
class="bot-id"
154+
style="stroke-width:0;fill: white">
155+
{{r.id}}
156+
</text>
157+
158+
<!-- balls -->
159+
<circle v-for="r of balls"
160+
v-bind:key="r"
161+
:r="ballRadius"
162+
:cx="r.x"
163+
:cy="r.y"
164+
style="stroke:black;stroke-width:0.3em;fill: orangered; fill-opacity:1">
165+
</circle>
166+
<circle v-for="r of balls"
167+
v-bind:key="r"
168+
:r="300"
169+
:cx="r.x"
170+
:cy="r.y"
171+
style="stroke:red;stroke-width:0.5em; fill-opacity:0">
172+
</circle>
173+
</g>
174+
</svg>
175+
</template>
176+
177+
<script>
178+
179+
180+
export default {
181+
name: "Field",
182+
data: function () {
183+
return {
184+
rotateField: true,
185+
useShapesFromGeometry: false,
186+
fieldWidth: 2000,
187+
fieldLength: 3000,
188+
boundaryWidth: 300,
189+
penAreaWidth: 1000,
190+
penAreaDepth: 500,
191+
goalWidth: 600,
192+
goalDepth: 180,
193+
centerCircleRadius: 500,
194+
ballRadius: 21.5,
195+
lines: [{p1: {x: 100, y: 100}, p2: {x: 500, y: 1000}}],
196+
arcs: [],
197+
robotsYellow: {},
198+
robotsBlue: {},
199+
balls: []
200+
}
201+
},
202+
computed: {
203+
getRobotsYellow() {
204+
return this.robotsYellow.values;
205+
},
206+
getRobotsBlue() {
207+
return this.robotsBlue.values;
208+
},
209+
getFieldTransformation() {
210+
if (this.rotateField) {
211+
return 'rotate(90) scale(' + (this.fieldWidth / this.fieldLength) + ')';
212+
}
213+
return '';
214+
},
215+
viewBox() {
216+
return (-(this.fieldLength / 2 + this.boundaryWidth))
217+
+ ' ' + (-(this.fieldWidth / 2 + this.boundaryWidth))
218+
+ ' ' + (this.fieldLength + this.boundaryWidth * 2)
219+
+ ' ' + (this.fieldWidth + this.boundaryWidth * 2);
220+
}
221+
}
222+
}
223+
</script>
224+
225+
<style scoped>
226+
227+
</style>

0 commit comments

Comments
 (0)