Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // base variables
- var width = 500;
- var height = 500;
- var arcInnerRadius = 180;
- var arcOuterRadius = 200;
- var arcStartAngle = 180;
- var arcEndAngle = 360;
- var sliderCircleRadius = 16;
- var sliderRadius = 190; //
- var yAxisOffset = 120; // 0: a half circle. 120: 120px 'longer' then a half circle
- var svg = d3
- .select("body")
- .append("svg")
- .attr("width", width)
- .attr("height", height)
- .append("g")
- .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); // move the arc to the center of its container
- var arc = d3
- .arc()
- .innerRadius(arcInnerRadius)
- .outerRadius(arcOuterRadius)
- .startAngle(degToRad(arcStartAngle))
- .endAngle(degToRad(arcEndAngle));
- svg.on("touchstart", function(d) {}).on("touchmove", function(d) {}); // for touch devices
- var def = svg.append("defs");
- var gradient = def
- .append("linearGradient")
- .attr("id", "gradientDef")
- .attr("x1", "0%")
- .attr("y1", "0%")
- .attr("x2", "0%")
- .attr("y2", "100%");
- gradient
- .append("stop")
- .attr("offset", "0%")
- .attr("style", "stop-color: #f7be56; stop-opacity:1");
- gradient
- .append("stop")
- .attr("offset", "50%")
- .attr("style", "stop-color: #89fe40; stop-opacity:1");
- gradient
- .append("stop")
- .attr("offset", "100%")
- .attr("style", "stop-color: #2ac8fc; stop-opacity:1");
- var drag = d3
- .drag()
- .on("start", dragstarted)
- .on("drag", dragged)
- .on("end", dragended);
- function dragstarted(d) {
- d3.event.sourceEvent.stopPropagation();
- d3.select(this).classed("dragging", true);
- }
- var handle = [
- {
- x: -calcStarterPointX(),
- y: yAxisOffset
- }
- ];
- var dot = svg.append("g").attr("class", "dot");
- function dragged(d) {
- if (d.y <= yAxisOffset) {
- var c = Math.sqrt(Math.pow(d3.event.x, 2) + Math.pow(d3.event.y, 2));
- var a = Math.acos(d3.event.x / c);
- d3.select(this) // this = circle
- .attr("cx", function() {
- var value = sliderRadius * Math.cos(a);
- return (d.x = d.y < yAxisOffset ? (d.x = value) : d.x);
- })
- .attr("cy", function() {
- var value =
- d3.event.y < 0
- ? -sliderRadius * Math.sin(a)
- : sliderRadius * Math.sin(a);
- return (d.y = value <= yAxisOffset ? value : yAxisOffset);
- });
- // sides
- var sideA = sliderRadius;
- var sideB = Math.sqrt(Math.pow(d.x, 2) + Math.pow(d.y, 2));
- var sideC = Math.sqrt(Math.pow(d.x, 2) + Math.pow(sliderRadius - d.y, 2));
- var alpha = calcDegreeLawOfCosines(sideA, sideB, sideC);
- if (d3.event.x >= 0 && d3.event.x <= sliderRadius) {
- drawNewArc(-(alpha - 180) + 90);
- } else if (d3.event.x >= -sliderRadius && d3.event.x < 0) {
- drawNewArc(alpha - 90);
- }
- drawCircle();
- }
- }
- function dragended(d) {
- d3.select(this).classed("dragging", false);
- }
- drawCircle();
- function drawNewArc(value) {
- d3.selectAll("#baseArc").remove();
- var startAngle =
- yAxisOffset > 0
- ? degToRad(
- 180 -
- (90 -
- calcDegreeLawOfCosines(
- yAxisOffset,
- sliderRadius,
- calcStarterPointX()
- ))
- )
- : 180;
- var newArc = d3
- .arc()
- .innerRadius(arcInnerRadius)
- .outerRadius(arcOuterRadius)
- .startAngle(startAngle)
- .endAngle(degToRad(value + 180));
- dot
- .append("path")
- .attr("d", newArc)
- .attr("id", "baseArc")
- .attr("fill", "url(#gradientDef")
- .attr("transform", "rotate(90)")
- .classed("arc", true);
- }
- function drawCircle() {
- d3.selectAll(".toggle-circle").remove();
- dot
- .selectAll("circle")
- .data(handle)
- .enter()
- .append("circle")
- .attr("r", sliderCircleRadius)
- // .attr("cx", 480)
- // .attr("cy", 250)
- .attr("cx", function(d) {
- return d.x;
- })
- .attr("cy", function(d) {
- return d.y;
- })
- .classed("toggle-circle", true)
- .call(drag);
- }
- // helper functions
- function degToRad(degree) {
- return (degree * Math.PI) / 180;
- }
- function radToDeg(radian) {
- return (180 / Math.PI) * radian;
- }
- function calcStarterPointX() {
- // Pythagorean theorem
- return Math.sqrt(Math.pow(sliderRadius, 2) - Math.pow(yAxisOffset, 2));
- }
- function calcDegreeLawOfCosines(sideA, sideB, sideC) {
- return radToDeg(
- Math.acos(
- (Math.pow(sideC, 2) - Math.pow(sideA, 2) - Math.pow(sideB, 2)) /
- (-2 * sideA * sideB)
- )
- );
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement