Skip to content

Instantly share code, notes, and snippets.

@ilumin
Created August 24, 2014 06:19
Show Gist options
  • Save ilumin/42a62ff08a68fb0b5579 to your computer and use it in GitHub Desktop.
Save ilumin/42a62ff08a68fb0b5579 to your computer and use it in GitHub Desktop.
d3js scroll to animate arc path
<button class="inc">+</button>
<button class="dec">-</button>
<input type="text" class="manual" placeholder="set angle">
var w = 400
, h = 400
, strokeColor = "#ffc000"
// variable for arc
, arcStartAngle = 0
, arcInnerRadius = w / 2 - 20
, arcOuterRadius = w / 2 - 10
// variable for circle
, circleRadius = 10
, anglePoint = 0
// variable for animate arc path
, fullAngle = Math.PI * 2
, maxStep = 24 * 60
, angleStep = fullAngle / maxStep
, currentStep = 0
, animateDuration = 50
;
// create main svg
var svg = d3.select("body").append("svg:svg")
.attr("width", w)
.attr("height", h)
.attr("id", "clock")
;
// create arc group
var arcGroup = svg.append("svg:g")
.attr(
"transform",
"translate(" + w / 2 + "," + h / 2 + ")"
)
;
// create arc object (not display in svg,
// but use as data of path)
var arc = d3.svg.arc()
.innerRadius( arcInnerRadius )
.outerRadius( arcOuterRadius )
.startAngle( arcStartAngle )
;
// create arc path
var arcPath = arcGroup.append("path")
.datum({ endAngle: arcStartAngle })
.style("fill", strokeColor)
.attr("d", arc)
;
var circle = arcGroup.append("circle")
.attr("r", circleRadius)
.attr("fill", "#ffffff")
.attr("stroke", strokeColor)
.attr("stroke-width", circleRadius/2 + 2)
.attr("transform", "translate(0,-" + (h/2 - circleRadius - 5) + ")")
;
// init
setAngleStep(currentStep);
// register scroll event
$('#clock').bind('mousewheel', function(e){
if ( e.originalEvent.wheelDelta<0 ){
currentStep--;
}
else {
currentStep++;
}
setAngleStep(currentStep);
});
$('.inc').click(function(){
// currentStep++;
currentStep = currentStep + 60;
if( currentStep > maxStep ){
currentStep = maxStep;
return;
}
setAngleStep(currentStep);
});
$('.dec').click(function(){
// currentStep--;
currentStep = currentStep - 60;
if( currentStep < 0 ){
currentStep = 0;
return;
}
setAngleStep(currentStep);
});
$('.manual').change(function(){
currentStep = parseInt(this.value);
if (currentStep > maxStep)
currentStep = maxStep;
if (currentStep < 0)
currentStep = 0;
setAngleStep(currentStep);
});
// set animate step
function setAngleStep(step) {
if (step > maxStep || step < 0)
return;
arcPath.transition()
.duration(animateDuration)
.ease("linear")
.call(
arcTween,
angleStep * step,
arc
);
}
// animate function
function arcTween(transition, newAngle, arc) {
// arc path transition
transition.attrTween("d", function(d) {
var interpolate = d3.interpolate(d.endAngle, newAngle);
return function(t) {
d.endAngle = interpolate(t);
// transalte circle
anglePoint = Math.ceil(d.endAngle / angleStep) / 4;
moveCircle(anglePoint);
return arc(d);
};
});
}
function moveCircle(angle) {
var r = h/2 - 15;
var x = r * Math.sin(angle * Math.PI / 180);
var y = -r * Math.cos(angle * Math.PI / 180);
console.log(angle, x, y);
circle.attr(
"transform",
"translate(" + x + "," + y + ")"
);
}
// ===
console.log('[done]');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment