···
1
1
+
/.DS_Store
2
2
+
/.prettierrc
···
1
1
+
# Mandala
2
2
+
3
3
+
simple browser based vector mandala drawing tool, using [paper.js](http://paperjs.org/) and [bulma](https://bulma.io).
4
4
+
5
5
+
### TODO
6
6
+
7
7
+
- [ ] connect rotations slider to the actual rotation
8
8
+
- [x] save and load settings
9
9
+
10
10
+
- [ ] add zoom and pan on mobile
11
11
+
- [ ] add stuff for pwa
12
12
+
13
13
+
- [ ] add icon/favicon
14
14
+
15
15
+
- [ ] create file modal
16
16
+
- [ ] set background color
17
17
+
- [ ] clear current drawing
18
18
+
19
19
+
- [ ] save file
20
20
+
- [ ] load file
21
21
+
- [ ] export file as svg/png
···
1
1
+
<!DOCTYPE html>
2
2
+
<html>
3
3
+
<head>
4
4
+
<meta charset="utf-8" />
5
5
+
6
6
+
<meta name="apple-mobile-web-app-capable" content="yes" />
7
7
+
8
8
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
9
9
+
10
10
+
<link
11
11
+
rel="stylesheet"
12
12
+
href="https://cdn.jsdelivr.net/npm/@mdi/font@7.2.96/css/materialdesignicons.min.css"
13
13
+
/>
14
14
+
15
15
+
<link
16
16
+
rel="stylesheet"
17
17
+
href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css"
18
18
+
/>
19
19
+
<script
20
20
+
type="text/javascript"
21
21
+
src="https://cdnjs.cloudflare.com/ajax/libs/paper.js/0.12.17/paper-core.js"
22
22
+
></script>
23
23
+
<script type="text/javascript" src="./script.js"></script>
24
24
+
25
25
+
<link rel="stylesheet" type="text/css" href="./style.css" />
26
26
+
27
27
+
<meta name="theme-color" content="#AA0000" />
28
28
+
<title>vector mandalas</title>
29
29
+
</head>
30
30
+
<body>
31
31
+
<canvas id="myCanvas" resize></canvas>
32
32
+
<div id="controls">
33
33
+
<button
34
34
+
class="button is-danger is-large top-right-button"
35
35
+
id="file-button"
36
36
+
>
37
37
+
<span class="icon is-large">
38
38
+
<i class="mdi mdi-file mdi-36px"></i>
39
39
+
</span>
40
40
+
</button>
41
41
+
<button
42
42
+
class="button is-danger is-large bottom-right-button"
43
43
+
id="brush-button"
44
44
+
>
45
45
+
<span class="icon is-large">
46
46
+
<i class="mdi mdi-brush mdi-36px"></i>
47
47
+
</span>
48
48
+
</button>
49
49
+
<button
50
50
+
class="button is-danger is-large bottom-left-button"
51
51
+
id="undo-button"
52
52
+
>
53
53
+
<span class="icon is-large">
54
54
+
<i class="mdi mdi-undo mdi-36px"></i>
55
55
+
</span>
56
56
+
</button>
57
57
+
</div>
58
58
+
59
59
+
<div class="modal" id="brush-modal">
60
60
+
<div class="modal-background"></div>
61
61
+
62
62
+
<div class="modal-card">
63
63
+
<header class="modal-card-head">
64
64
+
<p class="modal-card-title">Brush settings</p>
65
65
+
<button class="delete" aria-label="close"></button>
66
66
+
</header>
67
67
+
<div class="modal-card-body">
68
68
+
<div class="block">
69
69
+
<div class="field">
70
70
+
<div class="control columns is-mobile is-vcentered">
71
71
+
<div class="column is-narrow">
72
72
+
<label class="label">Size</label>
73
73
+
</div>
74
74
+
<div class="column">
75
75
+
<progress
76
76
+
class="progress is-large is-danger"
77
77
+
id="brush-size-bar"
78
78
+
value="80"
79
79
+
max="100"
80
80
+
>
81
81
+
80%
82
82
+
</progress>
83
83
+
</div>
84
84
+
<div class="column is-3">
85
85
+
<div class="control">
86
86
+
<input
87
87
+
class="input"
88
88
+
type="text"
89
89
+
placeholder="0"
90
90
+
value="80"
91
91
+
id="brush-size-input"
92
92
+
/>
93
93
+
</div>
94
94
+
</div>
95
95
+
</div>
96
96
+
</div>
97
97
+
98
98
+
<div class="field">
99
99
+
<div class="control columns is-mobile is-vcentered">
100
100
+
<div class="column is-narrow">
101
101
+
<label class="label">Color</label>
102
102
+
</div>
103
103
+
<div class="column">
104
104
+
<div class="control">
105
105
+
<input
106
106
+
class="input"
107
107
+
type="color"
108
108
+
value="#ff0000"
109
109
+
id="brush-color-input"
110
110
+
style="width: 100px"
111
111
+
/>
112
112
+
</div>
113
113
+
</div>
114
114
+
</div>
115
115
+
</div>
116
116
+
</div>
117
117
+
118
118
+
<div class="block">
119
119
+
<div class="field">
120
120
+
<div class="columns is-mobile is-vcentered">
121
121
+
<div class="column is-narrow">
122
122
+
<label class="label">Rotations</label>
123
123
+
</div>
124
124
+
<div class="column">
125
125
+
<progress
126
126
+
class="progress is-large is-danger"
127
127
+
id="rotations-bar"
128
128
+
value="80"
129
129
+
max="100"
130
130
+
>
131
131
+
80%
132
132
+
</progress>
133
133
+
</div>
134
134
+
<div class="column is-3">
135
135
+
<div class="control">
136
136
+
<input
137
137
+
class="input"
138
138
+
type="text"
139
139
+
placeholder="0"
140
140
+
value="80"
141
141
+
id="rotations-input"
142
142
+
/>
143
143
+
</div>
144
144
+
</div>
145
145
+
</div>
146
146
+
</div>
147
147
+
148
148
+
<div class="field">
149
149
+
<div class="buttons">
150
150
+
<button class="button is-danger" id="mirror-button">
151
151
+
<span class="icon">
152
152
+
<i class="mdi mdi-mirror"></i>
153
153
+
</span>
154
154
+
<span>Mirror</span>
155
155
+
</button>
156
156
+
157
157
+
<button class="button is-danger" id="simplify-button">
158
158
+
<span class="icon">
159
159
+
<i class="mdi mdi-chart-bell-curve-cumulative"></i>
160
160
+
</span>
161
161
+
<span>Simplify</span>
162
162
+
</button>
163
163
+
</div>
164
164
+
</div>
165
165
+
</div>
166
166
+
</div>
167
167
+
</div>
168
168
+
</div>
169
169
+
</body>
170
170
+
</html>
···
1
1
+
paper.install(window);
2
2
+
3
3
+
window.onload = function () {
4
4
+
paper.setup("myCanvas");
5
5
+
6
6
+
let mandalaDrawer = new MandalaDrawer();
7
7
+
mandalaDrawer.loadCurrent();
8
8
+
9
9
+
view.translate(view.center);
10
10
+
11
11
+
document.addEventListener(
12
12
+
"wheel",
13
13
+
function (e) {
14
14
+
e.preventDefault();
15
15
+
if (e.ctrlKey) {
16
16
+
view.zoom -= e.deltaY * 0.005;
17
17
+
} else {
18
18
+
view.translate(-e.deltaX, -e.deltaY);
19
19
+
}
20
20
+
},
21
21
+
{ passive: false }
22
22
+
);
23
23
+
24
24
+
let undoButton = document.getElementById("undo-button");
25
25
+
undoButton.addEventListener("click", function (e) {
26
26
+
mandalaDrawer.undo();
27
27
+
});
28
28
+
29
29
+
let brushButton = document.getElementById("brush-button");
30
30
+
brushButton.addEventListener("click", openBrushModal);
31
31
+
32
32
+
let brushSizeInput = document.getElementById("brush-size-input");
33
33
+
let brushSizeBar = document.getElementById("brush-size-bar");
34
34
+
35
35
+
brushSizeBar.value = mandalaDrawer.brushSizePercentage * 100;
36
36
+
brushSizeInput.value = mandalaDrawer.brushSize;
37
37
+
38
38
+
brushSizeBar.addEventListener("click", function (e) {
39
39
+
let brushSize = e.offsetX / brushSizeBar.offsetWidth;
40
40
+
mandalaDrawer.setPercentageBrushSize(brushSize);
41
41
+
42
42
+
brushSizeBar.value = mandalaDrawer.brushSizePercentage * 100;
43
43
+
brushSizeInput.value = mandalaDrawer.brushSize;
44
44
+
});
45
45
+
46
46
+
let mouseDown = false;
47
47
+
brushSizeBar.addEventListener("pointerdown", function (e) {
48
48
+
mouseDown = true;
49
49
+
});
50
50
+
document.addEventListener("pointerup", function (e) {
51
51
+
mouseDown = false;
52
52
+
});
53
53
+
brushSizeBar.addEventListener("pointermove", function (e) {
54
54
+
if (mouseDown == false) return;
55
55
+
let brushSize = e.offsetX / brushSizeBar.offsetWidth;
56
56
+
mandalaDrawer.setPercentageBrushSize(brushSize);
57
57
+
58
58
+
brushSizeBar.value = mandalaDrawer.brushSizePercentage * 100;
59
59
+
brushSizeInput.value = mandalaDrawer.brushSize;
60
60
+
});
61
61
+
62
62
+
brushSizeInput.addEventListener("change", function (e) {
63
63
+
let brushSize = brushSizeInput.value;
64
64
+
mandalaDrawer.brushSize = brushSize;
65
65
+
66
66
+
brushSizeBar.value = mandalaDrawer.brushSizePercentage * 100;
67
67
+
brushSizeInput.value = mandalaDrawer.brushSize;
68
68
+
});
69
69
+
70
70
+
let mirrorButton = document.getElementById("mirror-button");
71
71
+
if (mandalaDrawer.mirror) {
72
72
+
mirrorButton.classList.remove("is-light");
73
73
+
} else {
74
74
+
mirrorButton.classList.add("is-light");
75
75
+
}
76
76
+
77
77
+
mirrorButton.addEventListener("click", function (e) {
78
78
+
mandalaDrawer.mirror = !mandalaDrawer.mirror;
79
79
+
if (mandalaDrawer.mirror) {
80
80
+
mirrorButton.classList.remove("is-light");
81
81
+
} else {
82
82
+
mirrorButton.classList.add("is-light");
83
83
+
}
84
84
+
});
85
85
+
86
86
+
let simplifyButton = document.getElementById("simplify-button");
87
87
+
if (mandalaDrawer.simplify) {
88
88
+
simplifyButton.classList.remove("is-light");
89
89
+
} else {
90
90
+
simplifyButton.classList.add("is-light");
91
91
+
}
92
92
+
93
93
+
simplifyButton.addEventListener("click", function (e) {
94
94
+
mandalaDrawer.simplify = !mandalaDrawer.simplify;
95
95
+
if (mandalaDrawer.simplify) {
96
96
+
simplifyButton.classList.remove("is-light");
97
97
+
} else {
98
98
+
simplifyButton.classList.add("is-light");
99
99
+
}
100
100
+
});
101
101
+
102
102
+
let brushColorInput = document.getElementById("brush-color-input");
103
103
+
brushColorInput.value = mandalaDrawer.brushColor;
104
104
+
105
105
+
brushColorInput.addEventListener("change", function (e) {
106
106
+
mandalaDrawer.brushColor = brushColorInput.value;
107
107
+
});
108
108
+
};
109
109
+
110
110
+
class MandalaDrawer {
111
111
+
constructor() {
112
112
+
this.tool = new Tool();
113
113
+
114
114
+
let json = localStorage.getItem("brush-settings");
115
115
+
let settings = json === null ? {} : JSON.parse(json);
116
116
+
117
117
+
this.path = undefined;
118
118
+
this.paths = undefined;
119
119
+
120
120
+
this._simplify = settings.simplify ?? true;
121
121
+
122
122
+
this._mirror = settings.mirror ?? true;
123
123
+
this._rotations = settings.rotations ?? 8;
124
124
+
125
125
+
this.maxBrushSize = 15;
126
126
+
this.minBrushSize = 0.2;
127
127
+
128
128
+
this._brushColor = settings.brushColor ?? "#FF0000";
129
129
+
130
130
+
this.brushSize = settings.brushSize ?? 1;
131
131
+
132
132
+
this.setupTool();
133
133
+
}
134
134
+
135
135
+
setPercentageBrushSize(percentage) {
136
136
+
if (isNaN(percentage)) percentage = 0;
137
137
+
138
138
+
percentage = Math.max(0, percentage);
139
139
+
percentage = Math.min(1, percentage);
140
140
+
141
141
+
this.brushSizePercentage = percentage;
142
142
+
143
143
+
this.brushSize =
144
144
+
this.minBrushSize + (this.maxBrushSize - this.minBrushSize) * percentage;
145
145
+
146
146
+
this.brushSize = Math.round(this.brushSize * 10) / 10;
147
147
+
}
148
148
+
149
149
+
set mirror(mirror) {
150
150
+
this._mirror = mirror;
151
151
+
this.saveSettings();
152
152
+
}
153
153
+
get mirror() {
154
154
+
return this._mirror;
155
155
+
}
156
156
+
set rotations(rotations) {
157
157
+
this._rotations = rotations;
158
158
+
this.saveSettings();
159
159
+
}
160
160
+
get rotations() {
161
161
+
return this._rotations;
162
162
+
}
163
163
+
set simplify(simplify) {
164
164
+
this._simplify = simplify;
165
165
+
this.saveSettings();
166
166
+
}
167
167
+
get simplify() {
168
168
+
return this._simplify;
169
169
+
}
170
170
+
set brushColor(color) {
171
171
+
this._brushColor = color;
172
172
+
this.saveSettings();
173
173
+
}
174
174
+
get brushColor() {
175
175
+
return this._brushColor;
176
176
+
}
177
177
+
178
178
+
set brushSize(size) {
179
179
+
this._brushSize = size;
180
180
+
let percentage = (size - this.minBrushSize) / this.maxBrushSize;
181
181
+
percentage = Math.max(0, percentage);
182
182
+
percentage = Math.min(1, percentage);
183
183
+
184
184
+
this.brushSizePercentage = percentage;
185
185
+
186
186
+
this.saveSettings();
187
187
+
}
188
188
+
get brushSize() {
189
189
+
return this._brushSize;
190
190
+
}
191
191
+
192
192
+
setupTool() {
193
193
+
this.tool.onMouseDown = (event) => {
194
194
+
if (event.modifiers.shift) {
195
195
+
return;
196
196
+
}
197
197
+
198
198
+
this.paths = [this.makePath()];
199
199
+
200
200
+
if (this.mirror) {
201
201
+
let mirrorPath = this.makePath();
202
202
+
this.paths.push(mirrorPath);
203
203
+
}
204
204
+
205
205
+
for (let i = 1; i <= this.rotations; i++) {
206
206
+
let p = this.makePath();
207
207
+
this.paths.push(p);
208
208
+
209
209
+
if (this.mirror) {
210
210
+
let mp = this.makePath();
211
211
+
this.paths.push(mp);
212
212
+
}
213
213
+
}
214
214
+
215
215
+
let group = new Group(this.paths);
216
216
+
217
217
+
this.addPoint(event.point);
218
218
+
};
219
219
+
220
220
+
this.tool.onMouseDrag = (event) => {
221
221
+
if (event.modifiers.shift) {
222
222
+
view.translate(event.delta);
223
223
+
return;
224
224
+
}
225
225
+
226
226
+
if (this.paths === undefined) {
227
227
+
return;
228
228
+
}
229
229
+
230
230
+
this.addPoint(event.point);
231
231
+
};
232
232
+
233
233
+
this.tool.onMouseUp = (event) => {
234
234
+
if (event.modifiers.shift || this.paths === undefined) {
235
235
+
return;
236
236
+
}
237
237
+
238
238
+
if (this.simplify) {
239
239
+
for (let p of this.paths) {
240
240
+
p.simplify(10);
241
241
+
}
242
242
+
}
243
243
+
244
244
+
this.paths = undefined;
245
245
+
246
246
+
// save project
247
247
+
this.saveCurrent();
248
248
+
};
249
249
+
250
250
+
this.tool.onKeyDown = (event) => {
251
251
+
if (event.key == "m") {
252
252
+
// Create a blob from the canvas...
253
253
+
view.element.toBlob((blob) => {
254
254
+
// ...and get it as a URL.
255
255
+
const url = URL.createObjectURL(blob);
256
256
+
// Open it in a new tab.
257
257
+
window.open(url, "_blank");
258
258
+
});
259
259
+
}
260
260
+
if (event.key == "+") {
261
261
+
view.zoom *= 1.1;
262
262
+
}
263
263
+
if (event.key == "-") {
264
264
+
view.zoom /= 1.1;
265
265
+
}
266
266
+
// move around
267
267
+
if (event.key == "up") {
268
268
+
view.translate(0, -10);
269
269
+
}
270
270
+
if (event.key == "down") {
271
271
+
view.translate(0, 10);
272
272
+
}
273
273
+
if (event.key == "left") {
274
274
+
view.translate(-10, 0);
275
275
+
}
276
276
+
if (event.key == "right") {
277
277
+
view.translate(10, 0);
278
278
+
}
279
279
+
};
280
280
+
}
281
281
+
282
282
+
makePath() {
283
283
+
let p = new Path();
284
284
+
p.strokeColor = this.brushColor;
285
285
+
p.strokeWidth = this.brushSize;
286
286
+
return p;
287
287
+
}
288
288
+
289
289
+
mirrorPoint(point) {
290
290
+
return new Point(point.x, -point.y);
291
291
+
}
292
292
+
293
293
+
addPoint(point) {
294
294
+
if (this.paths === undefined || this.paths.length < 1) return;
295
295
+
this.paths[0].add(point);
296
296
+
297
297
+
let index = 1;
298
298
+
if (this.mirror) {
299
299
+
this.paths[index].add(this.mirrorPoint(point));
300
300
+
index += 1;
301
301
+
}
302
302
+
303
303
+
for (let i = 1; i <= this.rotations; i++) {
304
304
+
let p = point.rotate((360 / this.rotations) * i);
305
305
+
this.paths[index].add(p);
306
306
+
index += 1;
307
307
+
308
308
+
if (this.mirror) {
309
309
+
this.paths[index].add(this.mirrorPoint(p));
310
310
+
index += 1;
311
311
+
}
312
312
+
}
313
313
+
}
314
314
+
315
315
+
saveCurrent() {
316
316
+
let json = paper.project.exportJSON();
317
317
+
localStorage.setItem("current-project", json);
318
318
+
}
319
319
+
320
320
+
loadCurrent() {
321
321
+
let json = localStorage.getItem("current-project");
322
322
+
paper.project.importJSON(json);
323
323
+
}
324
324
+
325
325
+
undo() {
326
326
+
let last = paper.project.activeLayer.lastChild;
327
327
+
if (last == undefined) return;
328
328
+
last.remove();
329
329
+
330
330
+
this.saveCurrent();
331
331
+
}
332
332
+
333
333
+
saveSettings() {
334
334
+
let settings = {};
335
335
+
settings.mirror = this.mirror;
336
336
+
settings.simplify = this.simplify;
337
337
+
settings.rotations = this.rotations;
338
338
+
settings.brushSize = this.brushSize;
339
339
+
settings.brushColor = this.brushColor;
340
340
+
341
341
+
localStorage.setItem("brush-settings", JSON.stringify(settings));
342
342
+
}
343
343
+
}
344
344
+
345
345
+
function openModal($el) {
346
346
+
$el.classList.add("is-active");
347
347
+
}
348
348
+
349
349
+
function openBrushModal() {
350
350
+
openModal(document.getElementById("brush-modal"));
351
351
+
}
352
352
+
353
353
+
function openFileModal() {
354
354
+
openModal(document.getElementById("file-modal"));
355
355
+
}
356
356
+
357
357
+
function closeModal($el) {
358
358
+
$el.classList.remove("is-active");
359
359
+
}
360
360
+
361
361
+
document.addEventListener("DOMContentLoaded", () => {
362
362
+
function closeAllModals() {
363
363
+
(document.querySelectorAll(".modal") || []).forEach(($modal) => {
364
364
+
closeModal($modal);
365
365
+
});
366
366
+
}
367
367
+
368
368
+
// Add a click event on buttons to open a specific modal
369
369
+
(document.querySelectorAll(".js-modal-trigger") || []).forEach(($trigger) => {
370
370
+
const modal = $trigger.dataset.target;
371
371
+
const $target = document.getElementById(modal);
372
372
+
373
373
+
$trigger.addEventListener("click", () => {
374
374
+
openModal($target);
375
375
+
});
376
376
+
});
377
377
+
378
378
+
// Add a click event on various child elements to close the parent modal
379
379
+
(
380
380
+
document.querySelectorAll(
381
381
+
".modal-background, .modal-close, .modal-card-head .delete, .modal-card-foot .button"
382
382
+
) || []
383
383
+
).forEach(($close) => {
384
384
+
const $target = $close.closest(".modal");
385
385
+
386
386
+
$close.addEventListener("click", () => {
387
387
+
closeModal($target);
388
388
+
});
389
389
+
});
390
390
+
391
391
+
// Add a keyboard event to close all modals
392
392
+
document.addEventListener("keydown", (event) => {
393
393
+
const e = event || window.event;
394
394
+
395
395
+
if (e.keyCode === 27) {
396
396
+
// Escape key
397
397
+
closeAllModals();
398
398
+
}
399
399
+
});
400
400
+
});
···
1
1
+
html, body {
2
2
+
height: 100%;
3
3
+
margin: 0;
4
4
+
overflow: hidden;
5
5
+
background-color: green;
6
6
+
}
7
7
+
8
8
+
canvas[resize] {
9
9
+
width: 100%;
10
10
+
height: 100%;
11
11
+
position: absolute;
12
12
+
background-color: black;
13
13
+
}
14
14
+
15
15
+
.top-right-button {
16
16
+
position: absolute;
17
17
+
top: 0;
18
18
+
right: 0;
19
19
+
z-index: 1;
20
20
+
}
21
21
+
22
22
+
.bottom-right-button {
23
23
+
position: absolute;
24
24
+
bottom: 0;
25
25
+
right: 0;
26
26
+
z-index: 1;
27
27
+
}
28
28
+
29
29
+
.bottom-left-button {
30
30
+
position: absolute;
31
31
+
bottom: 0;
32
32
+
left: 0;
33
33
+
z-index: 1;
34
34
+
}
35
35
+
36
36
+
.slidecontainer {
37
37
+
width: 100%; /* Width of the outside container */
38
38
+
}
39
39
+
40
40
+
/* The slider itself */
41
41
+
.slider {
42
42
+
-webkit-appearance: none; /* Override default CSS styles */
43
43
+
appearance: none;
44
44
+
width: 100%; /* Full-width */
45
45
+
height: 25px; /* Specified height */
46
46
+
background: #d3d3d3; /* Grey background */
47
47
+
outline: none; /* Remove outline */
48
48
+
opacity: 0.7; /* Set transparency (for mouse-over effects on hover) */
49
49
+
-webkit-transition: .2s; /* 0.2 seconds transition on hover */
50
50
+
transition: opacity .2s;
51
51
+
}
52
52
+
53
53
+
input[type="range"]::-webkit-slider-runnable-track {
54
54
+
background: #053a5f;
55
55
+
}
56
56
+
57
57
+
/******** Firefox ********/
58
58
+
input[type="range"]::-moz-range-track {
59
59
+
background: #053a5f;
60
60
+
}
61
61
+
62
62
+
/* Mouse-over effects */
63
63
+
.slider:hover {
64
64
+
opacity: 1; /* Fully shown on mouse-over */
65
65
+
}
66
66
+
67
67
+
/* The slider handle (use -webkit- (Chrome, Opera, Safari, Edge) and -moz- (Firefox) to override default look) */
68
68
+
.slider::-webkit-slider-thumb {
69
69
+
-webkit-appearance: none; /* Override default look */
70
70
+
appearance: none;
71
71
+
width: 25px; /* Set a specific slider handle width */
72
72
+
height: 25px; /* Slider handle height */
73
73
+
background: #04AA6D; /* Green background */
74
74
+
cursor: pointer; /* Cursor on hover */
75
75
+
}
76
76
+
77
77
+
.slider::-moz-range-thumb {
78
78
+
width: 25px; /* Set a specific slider handle width */
79
79
+
height: 25px; /* Slider handle height */
80
80
+
background: #04AA6D; /* Green background */
81
81
+
cursor: pointer; /* Cursor on hover */
82
82
+
}
83
83
+
84
84
+
85
85
+
/** FF*/
86
86
+
input[type="range"]::-moz-range-progress {
87
87
+
background-color: #43e5f7;
88
88
+
}
89
89
+
input[type="range"]::-moz-range-track {
90
90
+
background-color: #9a905d;
91
91
+
}
92
92
+
/* IE*/
93
93
+
input[type="range"]::-ms-fill-lower {
94
94
+
background-color: #43e5f7;
95
95
+
}
96
96
+
input[type="range"]::-ms-fill-upper {
97
97
+
background-color: #9a905d;
98
98
+
}