-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprototype2.html
More file actions
202 lines (183 loc) · 7.58 KB
/
prototype2.html
File metadata and controls
202 lines (183 loc) · 7.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Bakeoff 2</title>
<style type="text/css">
body {
height: 100vh;
width: 100vw;
border: none;
margin: 0px;
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
svg {
border: 1px #ddd solid;
}
#custom-sliders {
margin-top: 20px;
}
input[type="range"] {
width: 400px;
}
</style>
<script src="https://cdn.jsdelivr.net/npm/@svgdotjs/svg.js@3.0/dist/svg.min.js"></script>
<script src="https://dhcs-s25-bakeoff2.glitch.me/framework.js"></script>
</head>
<body>
<div id="main"></div>
<div id="custom-sliders">
<div>
<label for="rotationSlider">Rotation: <span id="rotationValue">0</span>°</label>
<input type="range" id="rotationSlider" min="0" max="360" value="0">
</div>
<div>
<label for="sizeSlider">Size: <span id="sizeValue">40</span>px</label>
<input type="range" id="sizeSlider" min="4" max="300" value="40">
</div>
</div>
</body>
<script type="text/javascript">
const tasksLength = 10;
let svg = SVG().addTo('#main').size(canvasSize, canvasSize);
const judge = new Judge(tasksLength, svg, "teamName");
const startColor = "#6677ee";
const goalColor = "#000000";
let squareBeingClicked = false;
let isDraggingHandle = false; // tracks if handle is being dragged
let isDraggingSquare = false; // tracks if the squre is being dragged
let manipulator = svg.group(); // group for square manipulations
let goal = svg.group(); // group for the goal square
let currentSquare = null; // the square currently being manipulated
let rotationArm, handle; // handle for rotating the square
let currentRotation = 0; // initial rotation angle
let dragOffsetX = 0, dragOffsetY = 0; // offsets for dragging the square
// function to update the position of the handle
function updateHandlePosition() {
if (!currentSquare) return;
const cx = manipulator.cx();
const cy = manipulator.cy();
const squareSize = currentSquare.width() / 2;
const r = squareSize + 40;
const angleRad = (currentRotation * Math.PI) / 180;
const hx = cx + r * Math.cos(angleRad);
const hy = cy + r * Math.sin(angleRad);
if (handle) handle.center(hx, hy);
if (rotationArm) rotationArm.plot(cx, cy, hx, hy);
}
svg.on("mousemove", (e) => {
if (isDraggingHandle && currentSquare) {
const cx = currentSquare.cx();
const cy = currentSquare.cy();
const dx = e.offsetX - cx;
const dy = e.offsetY - cy;
const newAngle = (Math.atan2(dy, dx) * 180) / Math.PI;
const angleChange = newAngle - currentRotation;
currentRotation = newAngle;
currentSquare.rotate(angleChange, cx, cy); // rotate the square
// update rotation slider value
rotationSlider.value = Math.round(currentRotation);
rotationValueDisplay.textContent = Math.round(currentRotation);
updateHandlePosition();
}
if (isDraggingSquare && currentSquare) {
manipulator.center(e.offsetX, e.offsetY);
updateHandlePosition();
}
if (squareBeingClicked && manipulator.children().length > 0) {
manipulator.center(e.offsetX, e.offsetY);
updateHandlePosition();
}
});
svg.on("mouseup", () => {
isDraggingHandle = false;
isDraggingSquare = false;
});
svg.on("mousedown", () => {
squareBeingClicked = !squareBeingClicked;
});
judge.on("newTask", () => {
// clear previous goal and setup
goal.clear();
if (handle) {
handle.remove();
rotationArm.remove();
}
let task = judge.getCurrentTask();
task.start.square.fill(startColor);
task.goal.square.fill('none').stroke(goalColor);
manipulator.add(task.start.square);
goal.add(task.goal.square);
currentSquare = task.start.square;
currentRotation = task.start.rotation || 0;
rotationArm = svg.line(0, 0, 0, 0).stroke({ color: "black", width: 2 });
handle = svg.circle(10).fill("#f06").stroke({ color: "#000", width: 1 });
updateHandlePosition();
// Draw lines going across target square to align with rotation arm
const goalSquareCenter = task.goal.square.cx(), goalSquareCenterY = task.goal.square.cy();
const squareSize = task.goal.square.width();
const halfSize = squareSize / 2;
const line1 = svg.line(goalSquareCenter, goalSquareCenterY - halfSize - 20, goalSquareCenter, goalSquareCenterY + halfSize + 20)
.stroke({ color: 'black', width: 1 });
const line2 = svg.line(goalSquareCenter - halfSize - 20, goalSquareCenterY, goalSquareCenter + halfSize + 20, goalSquareCenterY)
.stroke({ color: 'black', width: 1 });
// Apply rotation to both lines to match the target square's rotation
line1.rotate(task.goal.rotation || 0, goalSquareCenter, goalSquareCenterY);
line2.rotate(task.goal.rotation || 0, goalSquareCenter, goalSquareCenterY);
goal.add(line1);
goal.add(line2);
// handle mouse down on the handle to start rotation
handle.on("mousedown", (e) => {
e.stopPropagation();
isDraggingHandle = true;
});
// handle mouse down on the square to start dragging
task.start.square.on("mousedown", (e) => {
isDraggingSquare = true;
dragOffsetX = e.offsetX - currentSquare.cx();
dragOffsetY = e.offsetY - currentSquare.cy();
});
});
judge.on("testOver", (data) => {
for (let i=1; i<data.scores.length; i++) { // starting on the second one, since the first one is the "learning" trial, which doesn't affect the score
let score = data.scores[i];
let summedScore = (8*score.distance) + (900*score.scaleFactor) + (4*score.rotationFactor); // using the weight values as listed on Canvas
console.log("Trial "+i+": "+summedScore);
}
});
judge.setup();
// ===== Slider Control Code =====
const rotationSlider = document.getElementById("rotationSlider");
const rotationValueDisplay = document.getElementById("rotationValue");
const sizeSlider = document.getElementById("sizeSlider");
const sizeValueDisplay = document.getElementById("sizeValue");
// Update rotation when the rotation slider moves.
rotationSlider.addEventListener("input", (e) => {
const newAngle = parseFloat(e.target.value);
const angleChange = newAngle - currentRotation;
currentRotation = newAngle;
rotationValueDisplay.textContent = newAngle;
if (currentSquare) {
currentSquare.rotate(angleChange, currentSquare.cx(), currentSquare.cy());
updateHandlePosition();
}
});
// Update size when the size slider moves.
sizeSlider.addEventListener("input", (e) => {
const newSize = parseFloat(e.target.value);
sizeValueDisplay.textContent = newSize;
if (currentSquare) {
const cx = currentSquare.cx();
const cy = currentSquare.cy();
// Resize the square.
currentSquare.size(newSize, newSize);
currentSquare.center(cx, cy);
updateHandlePosition();
}
});
</script>
</html>