circular-sliders-rails 1.1.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
-

|
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
|
-
}
|