-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsketch.js
201 lines (178 loc) · 7.23 KB
/
sketch.js
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
// creates a square and returns it
function createSquare(side) {
let square = document.createElement('div');
square.classList.add('noncolored-square');
if (!currentGridBox) { square.classList.add('no-borders') }; // if grid box borders were disabled
square.style.width = `${side}px`;
square.style.height = `${side}px`;
return square;
}
// creates a row with specified row #
function createRow(num) {
let row = document.createElement('div');
row.classList.add(`row-${num}`, 'row');
return row;
}
// helper function to get rid of all previous nodes
function removeAllChildNodes(parent) {
while (parent.firstChild) {
parent.removeChild(parent.firstChild);
}
}
// creates a grid of user chosen size n, NxN
// also returns the grid object so it can be passed to other functions
function createGrid(userSize) {
let grid = document.querySelector('.grid-container');
removeAllChildNodes(grid);
for (let i = 0; i < userSize; i++) {
grid.appendChild(createRow(i));
let row = document.querySelector(`.row-${i}`);
for (let j = 0; j < userSize; j++) {
row.append(createSquare());
}
}
// updating/adding all current situations
updateGridNumber(userSize)
squareAddEventListeners(currentDrawingListener, currentDrawingOption); // adding current drawing option
}
// updates the display of the current grid size
function updateGridNumber(val) {
let displayedVal = document.querySelector('.size-preview');
displayedVal.textContent = val
}
// updates all values that result from slider being adjusted
function updateGridFromSlider() {
val = document.querySelector('.slider-preview');
createGrid(val.textContent);
}
// previews the size from slider
function updateSliderPreview() {
preview = document.querySelector('.slider-preview');
preview.textContent = this.value;
}
// adds functionality to grid sizing
function gridSliderSizing() {
let slider = document.querySelector('#grid-slider');
let sliderConfirm = document.querySelector('.grid-confirm');
slider.addEventListener('input', updateSliderPreview); // for when the slider is only being dragged
sliderConfirm.addEventListener('click', updateGridFromSlider); // for when the slider size is confirmed
}
// removes all event listener from all squares
function removeDrawingListenersFromAll() {
let grid = document.querySelectorAll('.noncolored-square');
grid.forEach((square) => { square.replaceWith(square.cloneNode(true)); })
}
// helper function that adds listeners with event type to squares w/o the class 'colored'
function squareAddEventListeners(mouseEvent, eventListener) {
let grid = document.querySelectorAll('.noncolored-square');
grid.forEach((square) => {
if (!square.classList.contains('colored')) {
square.addEventListener(mouseEvent, eventListener);
} else {
return;
}
})
}
// click-n-drag listeners to the squares
// so when the user 'clicks and drag', the boxes need to do as follows:
// when the user 'clicks', turns all the box listeners into 'hover' as the user
// has clicked down, also add the event listener of 'mouseup' signifying the user has
// released their mouse, thus turning all box listeners back into 'clicks'
function clicknDrag() {
color = document.querySelector('#Color');
this.style.backgroundColor = color.value;
this.style.borderColor = color.value;
this.classList.add('colored')
this.removeEventListener('mousedown', clicknDrag)
// then toggles on the hover
removeDrawingListenersFromAll();
squareAddEventListeners('mouseover', hoverDrawing);
// this is added to the document rather than the boxes because there's a case of the user's cursor might end up not on the boxes
document.onmouseup = documentDragUp;
}
function documentDragUp() {
removeDrawingListenersFromAll();
squareAddEventListeners('mousedown', clicknDrag);
}
// hover listeners to the squares (the default)
function hoverDrawing() {
color = document.querySelector('#Color');
// console.log(color);
this.style.backgroundColor = color.value;
this.style.borderColor = color.value;
this.classList.add('colored')
// console.log(this.classList)
this.removeEventListener('mouseover', hoverDrawing);
}
// adds the hover option functionality
function addHoverOption() {
hoverBtn = document.querySelector('.hover-option');
hoverBtn.addEventListener('click', () => {
currentDrawingOption = hoverDrawing;
currentDrawingListener = 'mouseover';
removeDrawingListenersFromAll(); // first removes all listeners
squareAddEventListeners('mouseover', hoverDrawing); // then adds hover listeners to all non-colored squares
});
}
// adds the click-n-drag option functionality
function addClicknDrag() {
dragBtn = document.querySelector('.click-option');
dragBtn.addEventListener('mousedown', () => {
currentDrawingOption = clicknDrag;
currentDrawingListener = 'mousedown';
removeDrawingListenersFromAll();
squareAddEventListeners('mousedown', clicknDrag);
});
}
function toggleGridBorder() {
currentGridBox = !currentGridBox
let grid = document.querySelectorAll('.noncolored-square');
grid.forEach((square) => { square.classList.toggle('no-borders') });
}
// adds grid-box functionality, user can toggle whether the borders of the box are visible or not
function addgridBoxToggle() {
let gridToggleBtn = document.querySelector('.grid-btn');
gridToggleBtn.addEventListener('click', toggleGridBorder);
}
// erases entire board
function addEraseBoard() {
let eraseBtn = document.querySelector('.eraser-btn');
eraseBtn.addEventListener('click', () => {
let currentSize = document.querySelector('.size-preview').textContent;
createGrid(currentSize);
})
}
// allows for manual size input
function addManualSize() {
let manualInput = document.querySelector('#grid-number');
manualInput.addEventListener('keypress', (e) => {
if (e.key == 'Enter') { // if user presses enter
val = manualInput.value;
if (2 <= val && val <= 100) { createGrid(val); } // if value is between [2, 100]
manualInput.value = NaN; // clears the field
}
})
}
// this updates the color background of the color input
function updateColorBackground(){
color = document.querySelector('#Color');
color.style.backgroundColor = color.value;
color.style.color = color.value;
}
// global variable (respectively) for current drawing option, drawing listener, and whether gridboxes are displayed or not
// by default, the drawing option is hover
let currentDrawingOption = hoverDrawing;
let currentDrawingListener = 'mouseover'
let currentGridBox = true; // if true, gridboxes should be displayed
function main() {
updateColorBackground();
document.querySelector('#Color').oninput = updateColorBackground;
createGrid(10);
gridSliderSizing(); // adds functionality of grid size slider
addManualSize(); // adds grid size manual input
addHoverOption(); // adds hover drawing option btn
addClicknDrag(); // adds click-n-drag drawing option btn
addgridBoxToggle(); // adds grid box border toggle btn
addEraseBoard(); // adds erasing board btn
}
main()