circular-sliders-rails 1.1.0 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +0 -7
- data/README.md +5 -116
- data/circular-sliders-rails.gemspec +4 -4
- data/lib/circular/sliders/rails/version.rb +1 -1
- data/vendor/assets/javascripts/jquery.circular-sliders.js +307 -0
- metadata +19 -21
- data/vendor/assets/javascripts/circular-sliders.js +0 -234
- data/vendor/assets/javascripts/shapes.js +0 -46
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fd234f98547b315390249c7ef09874c4ea09c3d988fde25b5f185bb59fbb4525
|
4
|
+
data.tar.gz: 39535784adb7521b8be9c47d00d70d208ea3ad796bd61987e6fa193cef2bf13b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c8de5094ead6c0b5f4ab070d0b4da155e2616a1f10b9c7dfe0bbf70e3edce640380bf51e67c090f9165b413f8a9492e8b7a6f56de22507e36ff41ed4592933c2
|
7
|
+
data.tar.gz: 6db569d5174ebb882a3dbcf92ffbed92022d1e71e5ba6944ddfa1bf2eb17981b02165d2e9bfa33017e97112eb968338d0cfe205d8c0e084a6d5230587a2cfc79
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,6 @@
|
|
1
|
-
# Circular Sliders for Rails
|
1
|
+
# Jquery Circular Sliders for Rails
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
![Circular sliders](../assets/circular-sliders-rails.gif?raw=true)
|
3
|
+
Provides integration of [Jquery Circular Sliders](https://github.com/speterlin/jquery.circular-sliders) with Rails Asset Pipeline.
|
6
4
|
|
7
5
|
## Installation
|
8
6
|
|
@@ -24,118 +22,9 @@ Or install it yourself as:
|
|
24
22
|
|
25
23
|
Include in your application.js file:
|
26
24
|
|
27
|
-
//= require circular-sliders
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
<canvas id="sliders" width="1200" height="300" style="border:1px solid;"></canvas>
|
32
|
-
|
33
|
-
Use jQuery to add circular sliders to the canvas area. Pass slider settings as objects in an array. Create multiple sliders or just a single slider. With the settings below you should see something like the picture above.
|
34
|
-
|
35
|
-
<script>
|
36
|
-
$('#sliders').sliders([
|
37
|
-
{
|
38
|
-
name: "Age",
|
39
|
-
centerX: 175,
|
40
|
-
minValue: 18,
|
41
|
-
maxValue: 66,
|
42
|
-
step: 1,
|
43
|
-
units: "years",
|
44
|
-
color: "#FF7F50",
|
45
|
-
legendColor: "#FF7F50"
|
46
|
-
},
|
47
|
-
{
|
48
|
-
name: "Daily activity",
|
49
|
-
units: "miles",
|
50
|
-
minValue: 0,
|
51
|
-
maxValue: 25,
|
52
|
-
step: 1,
|
53
|
-
color: "#FF7F50",
|
54
|
-
legendColor: "#FF7F50"
|
55
|
-
},
|
56
|
-
{
|
57
|
-
name: "Height",
|
58
|
-
color: "#FFDEAD",
|
59
|
-
type: "Height",
|
60
|
-
centerX: 375,
|
61
|
-
minValue: 0,
|
62
|
-
maxValue: 250,
|
63
|
-
step: 2,
|
64
|
-
units: "cm",
|
65
|
-
radius: 100
|
66
|
-
},
|
67
|
-
{
|
68
|
-
name: "Weight",
|
69
|
-
color: "#A52A2A",
|
70
|
-
type: "Weight",
|
71
|
-
minValue: 0,
|
72
|
-
maxValue: 150,
|
73
|
-
radius: 100,
|
74
|
-
centerX: 600,
|
75
|
-
step: 5,
|
76
|
-
units: "kg",
|
77
|
-
lineWidth: 10,
|
78
|
-
gradientFill: false
|
79
|
-
},
|
80
|
-
{
|
81
|
-
name: "Waist size",
|
82
|
-
color: "#A0522D",
|
83
|
-
type: "Waist",
|
84
|
-
centerX: 825,
|
85
|
-
radius: 100,
|
86
|
-
minValue: 0,
|
87
|
-
maxValue: 50,
|
88
|
-
lineWidth: 10,
|
89
|
-
step: 2,
|
90
|
-
units: "cm",
|
91
|
-
ballColor: "#A0522D"
|
92
|
-
},
|
93
|
-
{
|
94
|
-
name: "Shoe size",
|
95
|
-
type: "Shoe",
|
96
|
-
centerX: 1050,
|
97
|
-
radius: 100,
|
98
|
-
lineWidth: 10,
|
99
|
-
minValue: 10,
|
100
|
-
maxValue: 60,
|
101
|
-
step: 1,
|
102
|
-
legendColor: "#0000FF"
|
103
|
-
},
|
104
|
-
{
|
105
|
-
name: "Desired price",
|
106
|
-
priceUnits: "£",
|
107
|
-
legendColor: "#0000FF",
|
108
|
-
step: 5
|
109
|
-
}
|
110
|
-
]);
|
111
|
-
</script>
|
112
|
-
|
113
|
-
Slider settings:
|
114
|
-
|
115
|
-
| Name | Type | Default | Description |
|
116
|
-
| --------------- | ------- | ----------------------------------- | ------------------------------------------------------ |
|
117
|
-
| name | String | Slider n | Name your slider |
|
118
|
-
| type | String | Plain | Pick between various types for interesting graphics at the center of the slider: 'Height', 'Weight', 'Shoe', 'Waist', and more to come |
|
119
|
-
| centerX | Float | Center of canvas or previous slider | Specify the x value for the center of the slider |
|
120
|
-
| centerY | Float | Center of canvas or previous slider | Specify the y value for the center of the slider |
|
121
|
-
| color | String | "#0000FF" | Specify the color of the arc fill |
|
122
|
-
| minValue | Float | 0 | The minimum value of your slider |
|
123
|
-
| maxValue | Float | 100 | The maximum value of your slider |
|
124
|
-
| step | Float | 10 | The amount the value is incremented |
|
125
|
-
| units | String | "" | The units your value is displayed in |
|
126
|
-
| priceUnits | String | "" | Adds price ('$', '€', '£' ...) before value |
|
127
|
-
| radius | Float | 40 or (previous slider radius + previous slider lineWidth + default slider lineWidth) | The radius of your slider |
|
128
|
-
| lineWidth | Float | 5 | The slider and arc width |
|
129
|
-
| strokeColor | String | "#D3D3D3" | The color of the dashes on the slider |
|
130
|
-
| ballColor | String | "#000000" | The color of the slider ball |
|
131
|
-
| gradientFill | Boolean | true | Specify whether you would like the image in the center (for specified type) of the slider to fill with the slider's color as you scale the slider |
|
132
|
-
| legend | Boolean | true | Specify whether you would like the slider name, value and units listed in the top left corner of the canvas |
|
133
|
-
| legendFont | Boolean | "12px Arial" | Specify the font for the slider legend |
|
134
|
-
| legendColor | String | "#000000" | The color of the slider legend |
|
135
|
-
|
136
|
-
Retrieve values of individual sliders by calling:
|
137
|
-
|
138
|
-
$('#sliders').data('slider_name');
|
25
|
+
//= require jquery.circular-sliders
|
26
|
+
|
27
|
+
For more options and style customization, please, see [Jquery Circular Sliders](https://github.com/speterlin/jquery.circular-sliders)
|
139
28
|
|
140
29
|
<!-- ## Development -->
|
141
30
|
|
@@ -9,8 +9,8 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ["Sebastian Peterlin"]
|
10
10
|
spec.email = ["speterlin@gmail.com"]
|
11
11
|
|
12
|
-
spec.summary = %q{
|
13
|
-
spec.description = %q{
|
12
|
+
spec.summary = %q{Provides jQuery Circular Sliders for Rails Asset Pipeline.}
|
13
|
+
spec.description = %q{Provides jQuery Circular Sliders for Rails Asset Pipeline.}
|
14
14
|
spec.homepage = "https://github.com/speterlin/circular-sliders-rails"
|
15
15
|
spec.license = "MIT"
|
16
16
|
|
@@ -27,9 +27,9 @@ Gem::Specification.new do |spec|
|
|
27
27
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
28
28
|
spec.require_paths = ["lib"]
|
29
29
|
|
30
|
+
spec.add_dependency "railties", ">= 3.2.0"
|
31
|
+
|
30
32
|
spec.add_development_dependency "bundler", "~> 1.12"
|
31
33
|
spec.add_development_dependency "rake", "~> 10.0"
|
32
34
|
spec.add_development_dependency "rspec", "~> 3.0"
|
33
|
-
|
34
|
-
spec.add_dependency "rails", "~> 5.0"
|
35
35
|
end
|
@@ -0,0 +1,307 @@
|
|
1
|
+
/*
|
2
|
+
* JqueryCircularSliders.js
|
3
|
+
* Add concentric circles with jquery and responsively set each value.
|
4
|
+
* git+https://github.com/speterlin/jquery.circular-sliders.js.git
|
5
|
+
* v1.0.0
|
6
|
+
* MIT License
|
7
|
+
*/
|
8
|
+
|
9
|
+
(function (global, factory) {
|
10
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('jquery')) :
|
11
|
+
typeof define === 'function' && define.amd ? define(['jquery'], factory) :
|
12
|
+
(factory(global.$));
|
13
|
+
}(this, (function ($) { 'use strict';
|
14
|
+
|
15
|
+
$ = $ && $.hasOwnProperty('default') ? $['default'] : $;
|
16
|
+
|
17
|
+
function renderShoeWithGradient(ctx, slider) {
|
18
|
+
ctx.moveTo(slider.centerX - 0.8 * slider.radius, slider.centerY - 0.5 * slider.radius);
|
19
|
+
ctx.arc(slider.centerX - 0.5 * slider.radius, slider.centerY - 0.5 * slider.radius, slider.radius * 0.3, Math.PI, 0, true);
|
20
|
+
ctx.lineTo(slider.centerX + 0.6 * slider.radius, slider.centerY - 0.1 * slider.radius);
|
21
|
+
ctx.arc(slider.centerX + 0.7 * slider.radius, slider.centerY + 0.1 * slider.radius, slider.radius * 0.2, -(Math.PI / 2), Math.PI / 2, false);
|
22
|
+
ctx.lineTo(slider.centerX - 0.8 * slider.radius, slider.centerY + 0.3 * slider.radius);
|
23
|
+
ctx.lineTo(slider.centerX - 0.8 * slider.radius, slider.centerY - 0.5 * slider.radius);
|
24
|
+
return ctx.createLinearGradient(slider.centerX - 0.8 * slider.radius, slider.centerY + 0.3 * slider.radius, slider.centerX - 0.8 * slider.radius, slider.centerY - 0.5 * slider.radius);
|
25
|
+
}
|
26
|
+
|
27
|
+
function renderWaistWithGradient(ctx, slider) {
|
28
|
+
// maybe refactor, wanted to eyeball it without using math, also maybe move up, could put back in (slight difference at edge): ctx.moveTo(slider.centerX - 0.5 * slider.radius, slider.centerY + 0.05 * slider.radius);
|
29
|
+
ctx.arc(slider.centerX, slider.centerY - 0.8 * slider.radius, slider.radius, Math.PI * (2 / 3), Math.PI * (1 / 3), true);
|
30
|
+
// refactor, need to send to 0.85 * slider.radius instead of 0.9 * slider.radius since there is a sharp v bend if not
|
31
|
+
ctx.lineTo(slider.centerX + 0.2 * slider.radius, slider.centerY + 0.85 * slider.radius);
|
32
|
+
ctx.arc(slider.centerX + 0.1 * slider.radius, slider.centerY + 0.9 * slider.radius, slider.radius * 0.1, 0, Math.PI, true);
|
33
|
+
ctx.lineTo(slider.centerX, slider.centerY + 0.4 * slider.radius);
|
34
|
+
ctx.arc(slider.centerX - 0.1 * slider.radius, slider.centerY + 0.9 * slider.radius, slider.radius * 0.1, 0, Math.PI, true);
|
35
|
+
// maybe refactor moveTo, need it to avoid sharp v bend at base of arc
|
36
|
+
ctx.moveTo(slider.centerX - 0.2 * slider.radius, slider.centerY + 0.9 * slider.radius);
|
37
|
+
ctx.lineTo(slider.centerX - 0.5 * slider.radius, slider.centerY + 0.05 * slider.radius);
|
38
|
+
return ctx.createLinearGradient(slider.centerX - 0.2 * slider.radius, slider.centerY + 0.9 * slider.radius, slider.centerX - 0.2 * slider.radius, slider.centerY + 0.05 * slider.radius);
|
39
|
+
}
|
40
|
+
|
41
|
+
function renderPersonWithGradient(ctx, slider, options = {}) {
|
42
|
+
ctx.arc(slider.centerX, slider.centerY - 0.6 * slider.radius, slider.radius * 0.2, 0, Math.PI * 2, false);
|
43
|
+
ctx.moveTo(slider.centerX + 0.08 * slider.radius, slider.centerY - 0.32 * slider.radius);
|
44
|
+
ctx.arc(slider.centerX, slider.centerY - 0.3 * slider.radius, slider.radius * 0.08, 0, Math.PI * 2, false);
|
45
|
+
ctx.moveTo(slider.centerX + 0.05 * slider.radius, slider.centerY - 0.25 * slider.radius);
|
46
|
+
// maybe refactor and add arms, ctx.lineTo(slider.centerX + 0.25 * slider.radius, slider.centerY - 0.1 * slider.radius);
|
47
|
+
ctx.lineTo(slider.centerX + 0.05 * slider.radius, slider.centerY + 0.1 * slider.radius);
|
48
|
+
ctx.arc(slider.centerX, slider.centerY + 0.2 * slider.radius, slider.radius * 0.1, -(Math.PI / 3), Math.PI / 3, false);
|
49
|
+
ctx.lineTo(slider.centerX + 0.05 * slider.radius, slider.centerY + 0.8 * slider.radius);
|
50
|
+
ctx.lineTo(slider.centerX - 0.2 * slider.radius, slider.centerY + 0.8 * slider.radius);
|
51
|
+
ctx.arc(slider.centerX - 0.15 * slider.radius, slider.centerY + 0.8 * slider.radius, slider.radius * 0.05, Math.PI, -(Math.PI / 2), false);
|
52
|
+
ctx.lineTo(slider.centerX - 0.05 * slider.radius, slider.centerY + 0.75 * slider.radius);
|
53
|
+
if (options.style === 'Weight') {
|
54
|
+
ctx.lineTo(slider.centerX - 0.05 * slider.radius, slider.centerY + 0.15 * slider.radius);
|
55
|
+
ctx.arc(slider.centerX - 0.05 * slider.radius, slider.centerY, slider.radius * 0.15, Math.PI / 2, -(Math.PI / 2), false);
|
56
|
+
ctx.lineTo(slider.centerX - 0.05 * slider.radius, slider.centerY - 0.25 * slider.radius);
|
57
|
+
} else {
|
58
|
+
ctx.lineTo(slider.centerX - 0.05 * slider.radius, slider.centerY - 0.25 * slider.radius);
|
59
|
+
}
|
60
|
+
return ctx.createLinearGradient(slider.centerX - 0.05 * slider.radius, slider.centerY + 0.8 * slider.radius, slider.centerX - 0.05 * slider.radius, slider.centerY - 0.8 * slider.radius);
|
61
|
+
}
|
62
|
+
|
63
|
+
function renderLegend(ctx, slider, sliderIndex, movingSliderBall) {
|
64
|
+
ctx.beginPath();
|
65
|
+
if (movingSliderBall) { ctx.font = `bold ${slider.legend.font}`; } else { ctx.font = slider.legend.font; }
|
66
|
+
ctx.fillStyle = slider.legend.color;
|
67
|
+
// maybe refactor, 20px vertical spacing by default, could be an issue if set font above 20px
|
68
|
+
ctx.fillText(`${slider.name}: ${slider.priceUnits}${slider.value} ${slider.units}`, 10, 20 * (sliderIndex + 1));
|
69
|
+
ctx.closePath();
|
70
|
+
}
|
71
|
+
|
72
|
+
function renderCanvas(canvas, movingBall = false) {
|
73
|
+
const ctx = canvas.getContext('2d');
|
74
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
75
|
+
const sliders = canvas.sliders;
|
76
|
+
sliders.forEach((slider, index) => {
|
77
|
+
slider.__render(ctx);
|
78
|
+
if (slider.legend.display) {
|
79
|
+
renderLegend(ctx, slider, index, movingBall && slider === canvas.selectedSlider);
|
80
|
+
}
|
81
|
+
});
|
82
|
+
}
|
83
|
+
|
84
|
+
let isMouseDown = false;
|
85
|
+
|
86
|
+
function roundToStep(value, step) {
|
87
|
+
return Math.round(value / step) * step;
|
88
|
+
}
|
89
|
+
|
90
|
+
function ballLocationForAngle(slider) {
|
91
|
+
return [slider.centerX + slider.radius * Math.cos(slider.angle), slider.centerY + slider.radius * Math.sin(slider.angle)];
|
92
|
+
}
|
93
|
+
|
94
|
+
function angleForValue(slider) {
|
95
|
+
return (2 * Math.PI * (slider.value - slider.minValue) / slider.range) - (Math.PI / 2);
|
96
|
+
}
|
97
|
+
|
98
|
+
function moveBall(mouseX, mouseY, canvas) {
|
99
|
+
const slider = canvas.selectedSlider;
|
100
|
+
const dx = mouseX - slider.centerX;
|
101
|
+
// if draw out in x-y coordinates correct way would be slider.centerY - mouseY, but because top of circle -π / 2, have to do negative of angle which is the same as doing below
|
102
|
+
const dy = mouseY - slider.centerY;
|
103
|
+
slider.angle = Math.atan(dy / dx);
|
104
|
+
// to cover other half of circle, Math.atan only calculates angles between -π/2 and π/2
|
105
|
+
if (dx < 0) { slider.angle += Math.PI; }
|
106
|
+
[slider.ball.x, slider.ball.y] = ballLocationForAngle(slider);
|
107
|
+
// add π / 2 because 0˚ (top of circle) starts at -π / 2, divide by 2π because this is 360˚ in radians, this is reverse of #angleForValue
|
108
|
+
const value = slider.minValue + slider.range * ((slider.angle + (Math.PI / 2)) / (2 * Math.PI));
|
109
|
+
// refactor - bug if give step value below 0.5
|
110
|
+
const roundedValue = roundToStep(value, slider.step);
|
111
|
+
slider.value = roundedValue;
|
112
|
+
renderCanvas(canvas, true);
|
113
|
+
}
|
114
|
+
|
115
|
+
function moveBallToStep(canvas) {
|
116
|
+
const slider = canvas.selectedSlider;
|
117
|
+
slider.angle = angleForValue(slider);
|
118
|
+
[slider.ball.x, slider.ball.y] = ballLocationForAngle(slider);
|
119
|
+
renderCanvas(canvas);
|
120
|
+
}
|
121
|
+
|
122
|
+
function setMouse(e) {
|
123
|
+
const canvas = e.target;
|
124
|
+
// $(window).scrollLeft() and $(window).scrollTop() to account for page scrolling
|
125
|
+
return [parseInt(e.clientX - canvas.offsetLeft + $(window).scrollLeft(), 10), parseInt(e.clientY - canvas.offsetTop + $(window).scrollTop(), 10)];
|
126
|
+
}
|
127
|
+
|
128
|
+
function onBall(x, y, slider) {
|
129
|
+
if (x > (slider.ball.x - slider.ball.radius) && x < (slider.ball.x + slider.ball.radius) && y > (slider.ball.y - slider.ball.radius) && y < (slider.ball.y + slider.ball.radius)) {
|
130
|
+
return true;
|
131
|
+
}
|
132
|
+
return false;
|
133
|
+
}
|
134
|
+
|
135
|
+
function handleMouseDown(e) {
|
136
|
+
e.preventDefault();
|
137
|
+
isMouseDown = true;
|
138
|
+
const [mouseX, mouseY] = setMouse(e);
|
139
|
+
const sliders = e.target.sliders;
|
140
|
+
sliders.forEach((slider) => {
|
141
|
+
if (onBall(mouseX, mouseY, slider)) {
|
142
|
+
e.target.selectedSlider = slider;
|
143
|
+
}
|
144
|
+
});
|
145
|
+
}
|
146
|
+
|
147
|
+
function handleMouseUp(e) {
|
148
|
+
e.preventDefault();
|
149
|
+
isMouseDown = false;
|
150
|
+
moveBallToStep(e.target);
|
151
|
+
}
|
152
|
+
|
153
|
+
function handleMouseMove(e) {
|
154
|
+
if (!isMouseDown) {
|
155
|
+
return;
|
156
|
+
}
|
157
|
+
e.preventDefault();
|
158
|
+
const [mouseX, mouseY] = setMouse(e);
|
159
|
+
moveBall(mouseX, mouseY, e.target);
|
160
|
+
}
|
161
|
+
|
162
|
+
class Ball {
|
163
|
+
constructor(slider, ballColor) {
|
164
|
+
[this.x, this.y] = ballLocationForAngle(slider);
|
165
|
+
this.radius = slider.lineWidth;
|
166
|
+
this.color = ballColor;
|
167
|
+
}
|
168
|
+
}
|
169
|
+
|
170
|
+
function renderSlider(ctx, slider) {
|
171
|
+
ctx.beginPath();
|
172
|
+
ctx.lineWidth = slider.lineWidth;
|
173
|
+
ctx.strokeStyle = slider.strokeColor;
|
174
|
+
ctx.setLineDash([slider.lineDashLength, slider.lineDashSpacing]);
|
175
|
+
ctx.arc(slider.centerX, slider.centerY, slider.radius, 0, Math.PI * 2, false);
|
176
|
+
ctx.stroke();
|
177
|
+
ctx.closePath();
|
178
|
+
if (slider.type !== 'Plain') {
|
179
|
+
ctx.beginPath();
|
180
|
+
ctx.setLineDash([10, 0]);
|
181
|
+
ctx.lineWidth = 5;
|
182
|
+
let myGradient = null;
|
183
|
+
if (slider.type === 'Shoe') {
|
184
|
+
myGradient = renderShoeWithGradient(ctx, slider);
|
185
|
+
} else if (slider.type === 'Waist') {
|
186
|
+
myGradient = renderWaistWithGradient(ctx, slider);
|
187
|
+
} else if (slider.type === 'Height') {
|
188
|
+
myGradient = renderPersonWithGradient(ctx, slider);
|
189
|
+
} else if (slider.type === 'Weight') {
|
190
|
+
myGradient = renderPersonWithGradient(ctx, slider, { style: 'Weight' });
|
191
|
+
}
|
192
|
+
if (slider.gradientFill) {
|
193
|
+
const scale = (slider.value - slider.minValue) / slider.range;
|
194
|
+
myGradient.addColorStop(0, slider.color);
|
195
|
+
myGradient.addColorStop(scale, '#ffffff');
|
196
|
+
ctx.fillStyle = myGradient;
|
197
|
+
ctx.fill();
|
198
|
+
}
|
199
|
+
ctx.stroke();
|
200
|
+
ctx.closePath();
|
201
|
+
}
|
202
|
+
}
|
203
|
+
|
204
|
+
function renderArc(ctx, slider) {
|
205
|
+
// add this if want arc to stop at edge of ball: let angleOffset = Math.atan(slider.ball.radius / slider.radius), then also need check for (π / 2) + slider.angle) < angleOffset) for when go past the 0˚ mark at top of circle, π / 2 + slider.angle since angle starts at -π / 2 at top of circle
|
206
|
+
ctx.beginPath();
|
207
|
+
ctx.arc(slider.centerX, slider.centerY, slider.radius, -(Math.PI / 2), slider.angle, false);
|
208
|
+
ctx.lineWidth = slider.lineWidth;
|
209
|
+
ctx.strokeStyle = slider.color;
|
210
|
+
// have to set lineDashLength to a number > 0 for arc to be completely full in browsers like Safari
|
211
|
+
ctx.setLineDash([10, 0]);
|
212
|
+
ctx.stroke();
|
213
|
+
ctx.closePath();
|
214
|
+
}
|
215
|
+
|
216
|
+
function renderBall(ctx, slider) {
|
217
|
+
ctx.beginPath();
|
218
|
+
ctx.arc(slider.ball.x, slider.ball.y, slider.ball.radius, 0, Math.PI * 2);
|
219
|
+
ctx.fillStyle = slider.ball.color;
|
220
|
+
ctx.fill();
|
221
|
+
ctx.closePath();
|
222
|
+
}
|
223
|
+
|
224
|
+
class CircularSlider {
|
225
|
+
constructor(settings) {
|
226
|
+
const slider = this;
|
227
|
+
Object.keys(settings).forEach((key) => {
|
228
|
+
slider[key] = settings[key];
|
229
|
+
});
|
230
|
+
// centerX, centerY, and radius should be set in defaults (in for loop) or options
|
231
|
+
this.value = this.value || this.minValue;
|
232
|
+
// calculated / created attributes
|
233
|
+
this.range = this.maxValue - this.minValue;
|
234
|
+
this.angle = angleForValue(this);
|
235
|
+
// maybe refactor, I like 2/3 and 1/3 for now
|
236
|
+
const arcSegment = 2 * Math.PI * this.radius / (this.range / this.step);
|
237
|
+
this.lineDashLength = (2 / 3) * arcSegment;
|
238
|
+
this.lineDashSpacing = (1 / 3) * arcSegment;
|
239
|
+
this.ball = new Ball(this, settings.ballColor);
|
240
|
+
}
|
241
|
+
|
242
|
+
__render(ctx) {
|
243
|
+
renderSlider(ctx, this);
|
244
|
+
renderArc(ctx, this);
|
245
|
+
renderBall(ctx, this);
|
246
|
+
}
|
247
|
+
}
|
248
|
+
// $.fn.sliders.CircularSlider = CircularSlider;
|
249
|
+
|
250
|
+
if (typeof $ === 'undefined') {
|
251
|
+
throw new Error('jQuery.CircularSliders requires jQuery');
|
252
|
+
}
|
253
|
+
|
254
|
+
$.fn.sliders = function (slidersOptions) {
|
255
|
+
this.each(function () {
|
256
|
+
if (!$(this).is('canvas')) { throw new Error('Circular Sliders must be called on a Canvas.'); }
|
257
|
+
const canvas = this;
|
258
|
+
const sliders = [];
|
259
|
+
const canvasDefaults = {};
|
260
|
+
[canvasDefaults.centerX, canvasDefaults.centerY, canvasDefaults.radius] = [canvas.width / 2, canvas.height / 2, Math.min(canvas.width, canvas.height) / 4];
|
261
|
+
slidersOptions.forEach((sliderOptions, index) => {
|
262
|
+
canvasDefaults.name = `Slider ${index + 1}`;
|
263
|
+
if (index > 0) {
|
264
|
+
[canvasDefaults.centerX, canvasDefaults.centerY] = [sliders[index - 1].centerX, sliders[index - 1].centerY];
|
265
|
+
canvasDefaults.radius = sliders[index - 1].radius + sliders[index - 1].lineWidth + $.fn.sliders.defaults.lineWidth;
|
266
|
+
}
|
267
|
+
const sliderDefaults = $.extend({}, $.fn.sliders.defaults, canvasDefaults);
|
268
|
+
// true for deep merge
|
269
|
+
const settings = $.extend(true, {}, sliderDefaults, sliderOptions);
|
270
|
+
sliders.push(new CircularSlider(settings));
|
271
|
+
});
|
272
|
+
// maybe look at https://stackoverflow.com/questions/10149963/adding-event-listener-cross-browser
|
273
|
+
canvas.addEventListener('mousedown', handleMouseDown);
|
274
|
+
canvas.addEventListener('mouseup', handleMouseUp);
|
275
|
+
canvas.addEventListener('mousemove', handleMouseMove);
|
276
|
+
|
277
|
+
[canvas.sliders, canvas.selectedSlider] = [sliders, sliders[0]];
|
278
|
+
|
279
|
+
renderCanvas(canvas);
|
280
|
+
});
|
281
|
+
};
|
282
|
+
|
283
|
+
// TODO: add configure(options) and config: config
|
284
|
+
$.fn.sliders.defaults = {
|
285
|
+
name: 'Slider',
|
286
|
+
type: 'Plain',
|
287
|
+
color: '#0000FF',
|
288
|
+
minValue: 0,
|
289
|
+
maxValue: 100,
|
290
|
+
step: 10,
|
291
|
+
units: '',
|
292
|
+
priceUnits: '',
|
293
|
+
// centerX, centerY, and radius set in Canvas because they are specific/modified to each canvas
|
294
|
+
lineWidth: 5,
|
295
|
+
strokeColor: '#D3D3D3',
|
296
|
+
ballColor: '#000000',
|
297
|
+
gradientFill: true,
|
298
|
+
legend: { display: true, font: '12px Arial', color: '#000000' },
|
299
|
+
};
|
300
|
+
|
301
|
+
$.fn.findSliderByName = function (name) {
|
302
|
+
if (!this.is('canvas')) { throw new Error('findSliderByName must be called on a Canvas.'); }
|
303
|
+
const canvas = this[0];
|
304
|
+
return canvas.sliders.filter(slider => slider.name === name)[0];
|
305
|
+
};
|
306
|
+
|
307
|
+
})));
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: circular-sliders-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sebastian Peterlin
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-08-
|
11
|
+
date: 2018-08-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: railties
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 3.2.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 3.2.0
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: bundler
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,22 +66,7 @@ dependencies:
|
|
52
66
|
- - "~>"
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '3.0'
|
55
|
-
|
56
|
-
name: rails
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - "~>"
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '5.0'
|
62
|
-
type: :runtime
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - "~>"
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '5.0'
|
69
|
-
description: A Ruby on Rails gem which allows you to draw concentric responsive circular
|
70
|
-
sliders with jQuery. Requires jQuery.
|
69
|
+
description: Provides jQuery Circular Sliders for Rails Asset Pipeline.
|
71
70
|
email:
|
72
71
|
- speterlin@gmail.com
|
73
72
|
executables: []
|
@@ -87,8 +86,7 @@ files:
|
|
87
86
|
- circular-sliders-rails.gemspec
|
88
87
|
- lib/circular/sliders/rails.rb
|
89
88
|
- lib/circular/sliders/rails/version.rb
|
90
|
-
- vendor/assets/javascripts/circular-sliders.js
|
91
|
-
- vendor/assets/javascripts/shapes.js
|
89
|
+
- vendor/assets/javascripts/jquery.circular-sliders.js
|
92
90
|
homepage: https://github.com/speterlin/circular-sliders-rails
|
93
91
|
licenses:
|
94
92
|
- MIT
|
@@ -113,5 +111,5 @@ rubyforge_project:
|
|
113
111
|
rubygems_version: 2.7.6
|
114
112
|
signing_key:
|
115
113
|
specification_version: 4
|
116
|
-
summary:
|
114
|
+
summary: Provides jQuery Circular Sliders for Rails Asset Pipeline.
|
117
115
|
test_files: []
|
@@ -1,234 +0,0 @@
|
|
1
|
-
//= require shapes
|
2
|
-
|
3
|
-
(function ( $ ) {
|
4
|
-
'use strict';
|
5
|
-
|
6
|
-
// private global variables
|
7
|
-
var isMouseDown = false;
|
8
|
-
var defaults = {
|
9
|
-
name: "Slider",
|
10
|
-
type: "Plain",
|
11
|
-
color: "#0000FF",
|
12
|
-
minValue: 0,
|
13
|
-
maxValue: 100,
|
14
|
-
step: 10,
|
15
|
-
units: "",
|
16
|
-
priceUnits: "",
|
17
|
-
// centerX, centerY, and radius set in $.fn.sliders() because they are specific/modified to each canvas
|
18
|
-
lineWidth: 5,
|
19
|
-
strokeColor: "#D3D3D3",
|
20
|
-
ballColor: "#000000",
|
21
|
-
gradientFill: true,
|
22
|
-
legend: true,
|
23
|
-
legendFont: "12px Arial",
|
24
|
-
legendColor: "#000000"
|
25
|
-
}
|
26
|
-
|
27
|
-
$.fn.sliders = function(slidersOptions) {
|
28
|
-
this.each(function() {
|
29
|
-
var canvas = this;
|
30
|
-
canvas.sliders = [];
|
31
|
-
[defaults.centerX, defaults.centerY, defaults.radius] = [canvas.width / 2, canvas.height / 2, 40];
|
32
|
-
// maybe refactor, add container option if there are multiple containers
|
33
|
-
for (var i = 0; i < slidersOptions.length; i++) {
|
34
|
-
defaults.name = "Slider " + (i + 1);
|
35
|
-
if (i > 0) {
|
36
|
-
defaults.centerX = canvas.sliders[i-1].centerX;
|
37
|
-
defaults.centerY = canvas.sliders[i-1].centerY;
|
38
|
-
defaults.radius = canvas.sliders[i-1].radius + canvas.sliders[i-1].lineWidth + defaults.lineWidth;
|
39
|
-
}
|
40
|
-
var sliderSettings = $.extend( {}, defaults, slidersOptions[i] );
|
41
|
-
canvas.sliders.push(new Slider (sliderSettings));
|
42
|
-
// maybe refactor, visible if have it like this: elem.attr('data-'+sliders[i].name.split(" ").join("_"), sliders[i].minValue);
|
43
|
-
$(canvas).data(canvas.sliders[i].name.split(" ").join("_"), canvas.sliders[i].value);
|
44
|
-
}
|
45
|
-
canvas.selectedSlider = canvas.sliders[0];
|
46
|
-
draw(canvas);
|
47
|
-
canvas.addEventListener("mousedown", handleMouseDown);
|
48
|
-
canvas.addEventListener("mouseup", handleMouseUp);
|
49
|
-
canvas.addEventListener("mousemove", handleMouseMove);
|
50
|
-
})
|
51
|
-
}
|
52
|
-
|
53
|
-
function Slider(settings) {
|
54
|
-
this.name = settings.name;
|
55
|
-
this.type = settings.type;
|
56
|
-
this.centerX = settings.centerX;
|
57
|
-
this.centerY = settings.centerY;
|
58
|
-
this.color = settings.color;
|
59
|
-
this.minValue = settings.minValue;
|
60
|
-
this.maxValue = settings.maxValue;
|
61
|
-
this.step = settings.step;
|
62
|
-
this.units = settings.units;
|
63
|
-
this.priceUnits = settings.priceUnits;
|
64
|
-
this.radius = settings.radius;
|
65
|
-
this.lineWidth = settings.lineWidth;
|
66
|
-
this.strokeColor = settings.strokeColor;
|
67
|
-
this.value = settings.minValue;
|
68
|
-
this.gradientFill = settings.gradientFill;
|
69
|
-
this.legend = settings.legend;
|
70
|
-
this.legendFont = settings.legendFont;
|
71
|
-
this.legendColor = settings.legendColor;
|
72
|
-
// ball starts at top of circle which is - π / 2
|
73
|
-
this.angle = -(Math.PI / 2);
|
74
|
-
this.range = this.maxValue - this.minValue;
|
75
|
-
// maybe refactor, I like 2/3 and 1/3 for now
|
76
|
-
var arcSegment = 2 * Math.PI * this.radius / (this.range / this.step);
|
77
|
-
this.lineDashLength = (2 / 3) * arcSegment;
|
78
|
-
this.lineDashSpacing = (1 / 3) * arcSegment;
|
79
|
-
this.ball = new Ball (settings);
|
80
|
-
}
|
81
|
-
|
82
|
-
function Ball(sliderSettings) {
|
83
|
-
this.x = sliderSettings.centerX;
|
84
|
-
// ball starts at top of circle
|
85
|
-
this.y = sliderSettings.centerY - sliderSettings.radius;
|
86
|
-
this.radius = sliderSettings.lineWidth;
|
87
|
-
this.color = sliderSettings.ballColor;
|
88
|
-
}
|
89
|
-
|
90
|
-
function draw(canvas, movingBall = false) {
|
91
|
-
var ctx = canvas.getContext("2d");
|
92
|
-
// in the future want to be able to clear only the slider using, maybe with svg groups
|
93
|
-
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
94
|
-
var sliders = canvas.sliders;
|
95
|
-
for (var i = 0; i < sliders.length; i++) {
|
96
|
-
drawSlider(ctx, sliders[i]);
|
97
|
-
drawArc(ctx, sliders[i]);
|
98
|
-
drawBall(ctx, sliders[i]);
|
99
|
-
if (sliders[i].legend) { drawLegend(ctx, sliders[i], i, movingBall && sliders[i] == canvas.selectedSlider); }
|
100
|
-
}
|
101
|
-
}
|
102
|
-
|
103
|
-
function drawSlider(ctx, slider) {
|
104
|
-
ctx.lineWidth = slider.lineWidth;
|
105
|
-
ctx.strokeStyle = slider.strokeColor;
|
106
|
-
ctx.setLineDash([slider.lineDashLength, slider.lineDashSpacing]);
|
107
|
-
ctx.beginPath();
|
108
|
-
ctx.arc(slider.centerX, slider.centerY, slider.radius, 0, Math.PI * 2, false);
|
109
|
-
ctx.stroke();
|
110
|
-
ctx.closePath();
|
111
|
-
if (slider.type != "Plain") {
|
112
|
-
ctx.beginPath();
|
113
|
-
ctx.setLineDash([10, 0]);
|
114
|
-
ctx.lineWidth = 5;
|
115
|
-
var my_gradient = null;
|
116
|
-
if (slider.type == "Shoe") {
|
117
|
-
my_gradient = drawShoeWithGradient(ctx, slider);
|
118
|
-
} else if (slider.type == "Waist") {
|
119
|
-
my_gradient = drawWaistWithGradient(ctx, slider);
|
120
|
-
} else if (slider.type == "Height") {
|
121
|
-
my_gradient = drawPersonWithGradient(ctx, slider);
|
122
|
-
} else if (slider.type == "Weight") {
|
123
|
-
my_gradient = drawPersonWithGradient(ctx, slider, {style: "Weight"});
|
124
|
-
}
|
125
|
-
if (slider.gradientFill) {
|
126
|
-
var scale = (slider.value - slider.minValue) / slider.range;
|
127
|
-
my_gradient.addColorStop(0,slider.color);
|
128
|
-
my_gradient.addColorStop(scale,"#ffffff");
|
129
|
-
ctx.fillStyle = my_gradient;
|
130
|
-
ctx.fill();
|
131
|
-
}
|
132
|
-
ctx.stroke();
|
133
|
-
ctx.closePath();
|
134
|
-
}
|
135
|
-
}
|
136
|
-
|
137
|
-
function drawBall(ctx, slider) {
|
138
|
-
ctx.beginPath();
|
139
|
-
ctx.arc(slider.ball.x, slider.ball.y, slider.ball.radius, 0, Math.PI * 2);
|
140
|
-
ctx.fillStyle = slider.ball.color;
|
141
|
-
ctx.fill();
|
142
|
-
ctx.closePath();
|
143
|
-
}
|
144
|
-
|
145
|
-
function drawArc(ctx, slider) {
|
146
|
-
// add this if want arc to stop at edge of ball: var angleOffset = Math.atan(slider.ball.radius / slider.radius), then also need check for (π / 2) + slider.angle) < angleOffset) for when go past the 0˚ mark at top of circle, π / 2 + slider.angle since angle starts at -π / 2 at top of circle
|
147
|
-
ctx.beginPath();
|
148
|
-
ctx.arc(slider.centerX, slider.centerY, slider.radius, -(Math.PI / 2), slider.angle, false);
|
149
|
-
ctx.lineWidth = slider.lineWidth;
|
150
|
-
ctx.strokeStyle = slider.color;
|
151
|
-
// have to set lineDashLength to a number > 0 for arc to be completely full in browsers like Safari, set it arbitrarily to 10 here
|
152
|
-
ctx.setLineDash([10, 0]);
|
153
|
-
ctx.stroke();
|
154
|
-
ctx.closePath();
|
155
|
-
}
|
156
|
-
|
157
|
-
function drawLegend(ctx, slider, sliderIndex, movingSliderBall) {
|
158
|
-
ctx.beginPath();
|
159
|
-
if (movingSliderBall) {ctx.font = "bold " + slider.legendFont;} else {ctx.font = slider.legendFont;}
|
160
|
-
ctx.fillStyle = slider.legendColor;
|
161
|
-
// maybe refactor, 20px vertical spacing by default, could be an issue if set font above 20px
|
162
|
-
ctx.fillText(slider.name + ": " + slider.priceUnits + slider.value + " " + slider.units, 10, 20 * (sliderIndex + 1));
|
163
|
-
ctx.closePath();
|
164
|
-
}
|
165
|
-
|
166
|
-
function moveBall(mouseX, mouseY, canvas) {
|
167
|
-
var slider = canvas.selectedSlider;
|
168
|
-
var dx = mouseX - slider.centerX;
|
169
|
-
var dy = mouseY - slider.centerY;
|
170
|
-
slider.angle = Math.atan(dy / dx);
|
171
|
-
if (dx < 0) { slider.angle += Math.PI; }
|
172
|
-
slider.ball.x = slider.centerX + slider.radius * Math.cos(slider.angle);
|
173
|
-
slider.ball.y = slider.centerY + slider.radius * Math.sin(slider.angle);
|
174
|
-
slider.value = slider.minValue + slider.range * ((slider.angle + (Math.PI / 2)) / (2 * Math.PI)); //add π / 2 because 0˚ starts at -π / 2, divide by 2π because this is 360˚ in radians
|
175
|
-
// refactor - bug if give step value below 0.5
|
176
|
-
var roundedValue = roundToStep(slider.value, slider.step);
|
177
|
-
$(canvas).data(slider.name.split(" ").join("_"), roundedValue);
|
178
|
-
slider.value = roundedValue;
|
179
|
-
draw(canvas, true);
|
180
|
-
}
|
181
|
-
|
182
|
-
function moveBallToStep(canvas) {
|
183
|
-
var slider = canvas.selectedSlider;
|
184
|
-
slider.angle = (2 * Math.PI * (slider.value - slider.minValue) / slider.range) - (Math.PI / 2)
|
185
|
-
slider.ball.x = slider.centerX + slider.radius * Math.cos(slider.angle);
|
186
|
-
slider.ball.y = slider.centerY + slider.radius * Math.sin(slider.angle);
|
187
|
-
draw(canvas);
|
188
|
-
}
|
189
|
-
|
190
|
-
function handleMouseDown(e) {
|
191
|
-
e.preventDefault();
|
192
|
-
isMouseDown = true;
|
193
|
-
var [mouseX, mouseY] = setMouse(e);
|
194
|
-
var sliders = e.target.sliders;
|
195
|
-
for (var i = 0; i < sliders.length; i++) {
|
196
|
-
if (onBall(mouseX, mouseY, sliders[i])) {
|
197
|
-
e.target.selectedSlider = sliders[i];
|
198
|
-
}
|
199
|
-
}
|
200
|
-
}
|
201
|
-
|
202
|
-
function handleMouseUp(e) {
|
203
|
-
e.preventDefault();
|
204
|
-
isMouseDown = false;
|
205
|
-
moveBallToStep(e.target);
|
206
|
-
}
|
207
|
-
|
208
|
-
function handleMouseMove(e) {
|
209
|
-
if (!isMouseDown) {
|
210
|
-
return;
|
211
|
-
}
|
212
|
-
e.preventDefault();
|
213
|
-
var [mouseX, mouseY] = setMouse(e);
|
214
|
-
moveBall(mouseX, mouseY, e.target);
|
215
|
-
}
|
216
|
-
|
217
|
-
function roundToStep(value, step) {
|
218
|
-
return Math.ceil(value / step) * step;
|
219
|
-
}
|
220
|
-
|
221
|
-
function onBall(x, y, slider) {
|
222
|
-
if (x > (slider.ball.x - slider.ball.radius) && x < (slider.ball.x + slider.ball.radius) && y > (slider.ball.y - slider.ball.radius) && y < (slider.ball.y + slider.ball.radius)) {
|
223
|
-
return true;
|
224
|
-
}
|
225
|
-
return false;
|
226
|
-
}
|
227
|
-
|
228
|
-
function setMouse(e) {
|
229
|
-
var canvas = e.target;
|
230
|
-
// $(window).scrollLeft() and $(window).scrollTop() to account for page scrolling
|
231
|
-
return [parseInt(e.clientX - canvas.offsetLeft + $(window).scrollLeft()), parseInt(e.clientY - canvas.offsetTop + $(window).scrollTop())];
|
232
|
-
}
|
233
|
-
|
234
|
-
}( jQuery ));
|
@@ -1,46 +0,0 @@
|
|
1
|
-
// maybe refactor and include these in a react like module, would have to worry about browser support, https://stackoverflow.com/questions/950087/how-do-i-include-a-javascript-file-in-another-javascript-file
|
2
|
-
function drawShoeWithGradient(ctx, slider) {
|
3
|
-
ctx.moveTo(slider.centerX - 0.8 * slider.radius, slider.centerY - 0.5 * slider.radius);
|
4
|
-
ctx.arc(slider.centerX - 0.5 * slider.radius, slider.centerY - 0.5 * slider.radius, slider.radius * 0.3, Math.PI, 0, true);
|
5
|
-
ctx.lineTo(slider.centerX + 0.6 * slider.radius, slider.centerY - 0.1 * slider.radius);
|
6
|
-
ctx.arc(slider.centerX + 0.7 * slider.radius, slider.centerY + 0.1 * slider.radius, slider.radius * 0.2, -(Math.PI / 2), Math.PI / 2, false);
|
7
|
-
ctx.lineTo(slider.centerX - 0.8 * slider.radius, slider.centerY + 0.3 * slider.radius);
|
8
|
-
ctx.lineTo(slider.centerX - 0.8 * slider.radius, slider.centerY - 0.5 * slider.radius);
|
9
|
-
return ctx.createLinearGradient(slider.centerX - 0.8 * slider.radius, slider.centerY + 0.3 * slider.radius, slider.centerX - 0.8 * slider.radius, slider.centerY - 0.5 * slider.radius);
|
10
|
-
}
|
11
|
-
|
12
|
-
function drawWaistWithGradient(ctx, slider) {
|
13
|
-
// maybe refactor, wanted to eyeball it without using math, also maybe move up, could put back in (slight difference at edge): ctx.moveTo(slider.centerX - 0.5 * slider.radius, slider.centerY + 0.05 * slider.radius);
|
14
|
-
ctx.arc(slider.centerX, slider.centerY - 0.8 * slider.radius, slider.radius, Math.PI * (2 / 3), Math.PI * (1 / 3), true);
|
15
|
-
// refactor, need to send to 0.85 * slider.radius instead of 0.9 * slider.radius since there is a sharp v bend if not
|
16
|
-
ctx.lineTo(slider.centerX + 0.2 * slider.radius, slider.centerY + 0.85 * slider.radius);
|
17
|
-
ctx.arc(slider.centerX + 0.1 * slider.radius, slider.centerY + 0.9 * slider.radius, slider.radius * 0.1, 0, Math.PI, true);
|
18
|
-
ctx.lineTo(slider.centerX, slider.centerY + 0.4 * slider.radius);
|
19
|
-
ctx.arc(slider.centerX - 0.1 * slider.radius, slider.centerY + 0.9 * slider.radius, slider.radius * 0.1, 0, Math.PI, true);
|
20
|
-
// maybe refactor moveTo, need it to avoid sharp v bend at base of arc
|
21
|
-
ctx.moveTo(slider.centerX - 0.2 * slider.radius, slider.centerY + 0.9 * slider.radius);
|
22
|
-
ctx.lineTo(slider.centerX - 0.5 * slider.radius, slider.centerY + 0.05 * slider.radius);
|
23
|
-
return ctx.createLinearGradient(slider.centerX - 0.2 * slider.radius, slider.centerY + 0.9 * slider.radius, slider.centerX - 0.2 * slider.radius, slider.centerY + 0.05 * slider.radius);
|
24
|
-
}
|
25
|
-
|
26
|
-
function drawPersonWithGradient(ctx, slider, options = {}) {
|
27
|
-
ctx.arc(slider.centerX, slider.centerY - 0.6 * slider.radius, slider.radius * 0.2, 0, Math.PI * 2, false);
|
28
|
-
ctx.moveTo(slider.centerX + 0.08 * slider.radius, slider.centerY - 0.32 * slider.radius);
|
29
|
-
ctx.arc(slider.centerX, slider.centerY - 0.3 * slider.radius, slider.radius * 0.08, 0, Math.PI * 2, false);
|
30
|
-
ctx.moveTo(slider.centerX + 0.05 * slider.radius, slider.centerY - 0.25 * slider.radius);
|
31
|
-
// maybe refactor and add arms, ctx.lineTo(slider.centerX + 0.25 * slider.radius, slider.centerY - 0.1 * slider.radius);
|
32
|
-
ctx.lineTo(slider.centerX + 0.05 * slider.radius, slider.centerY + 0.1 * slider.radius);
|
33
|
-
ctx.arc(slider.centerX, slider.centerY + 0.2 * slider.radius, slider.radius * 0.1, -(Math.PI / 3), Math.PI / 3, false);
|
34
|
-
ctx.lineTo(slider.centerX + 0.05 * slider.radius, slider.centerY + 0.8 * slider.radius);
|
35
|
-
ctx.lineTo(slider.centerX - 0.2 * slider.radius, slider.centerY + 0.8 * slider.radius);
|
36
|
-
ctx.arc(slider.centerX - 0.15 * slider.radius, slider.centerY + 0.8 * slider.radius, slider.radius * 0.05, Math.PI, -(Math.PI / 2), false);
|
37
|
-
ctx.lineTo(slider.centerX - 0.05 * slider.radius, slider.centerY + 0.75 * slider.radius);
|
38
|
-
if (options.style == "Weight") {
|
39
|
-
ctx.lineTo(slider.centerX - 0.05 * slider.radius, slider.centerY + 0.15 * slider.radius);
|
40
|
-
ctx.arc(slider.centerX - 0.05 * slider.radius, slider.centerY, slider.radius * 0.15, Math.PI / 2, -(Math.PI / 2), false);
|
41
|
-
ctx.lineTo(slider.centerX - 0.05 * slider.radius, slider.centerY - 0.25 * slider.radius);
|
42
|
-
} else {
|
43
|
-
ctx.lineTo(slider.centerX - 0.05 * slider.radius, slider.centerY - 0.25 * slider.radius);
|
44
|
-
}
|
45
|
-
return ctx.createLinearGradient(slider.centerX - 0.05 * slider.radius, slider.centerY + 0.8 * slider.radius, slider.centerX - 0.05 * slider.radius, slider.centerY - 0.8 * slider.radius);
|
46
|
-
}
|