I have a circular container div with multiple divs with text along its circumference. I need to move the text divs in and out of view along the circumference in either direction on scroll.
I selected and styled the circular container div with d3.js and put it inside a smaller wrapper div with overflow-y set to auto.
<div id="circle-out-container-wrapper"><div id="circle-out-container"></div></div>
var radius = Math.floor(document.documentElement.clientHeight * 1.5);
d3.select('#circle-out-container-wrapper')
.style('overflow-y', 'auto')
.style('overflow-x', 'hidden')
.style('width', '80%')
.style('height', '400px')
.style('left', '0')
.style('top', '0')
.style('position', 'absolute');
d3.select('#circle-out-container')
.style('background-color', 'transparent')
.style('position', 'absolute')
.style('box-sizing', 'border-box')
.style('display', 'block')
.style('border', '1px solid #bce8f1')
.style('border-radius', '50%')
.style('width', (radius * 2) + "px")
.style('height', (radius * 2) + "px")
.style('left', Math.floor(-(radius * 5) / 3) + "px")
.style('top', Math.floor(-(radius * 2) / 3) + "px");
Then I add the text divs and position them with transform.
var params = [];
for (var i = 30; i >= 0; i--) {
params.push(i);
}
var nums = d3.select("#circle-out-container")
.selectAll("div.nums")
.data(params)
.enter()
.append("div")
.attr("class", "circle")
.style("transform", function(d, i) {
var angle = 20 - (i + 1) * (70 / (params.length + 1));
return "rotate(" + angle + "deg) translate(" + radius + "px, 0) rotate(" + -angle + "deg)";
})
.text(function(d) { return d });
This is how I scroll the text divs:
$('#circle-out-container-wrapper').scroll(function() {
b.style("transform", function(d, i) {
var scroll = $('#circle-out-container-wrapper').scrollTop();
var angle = scroll - (i + 1) * (40 / (params.length + 1));
return "rotate(" + angle + "deg) translate(" + radius + "px, 0) rotate(" + -angle + "deg)";
})
});
The container circle has to be static with only about half of it showing. At the moment when scrolling the text divs move but you also scroll down on the circular container div and the displayed arc changes. How do I keep everything in place and move only the text divs along the circular path when I scroll?
Here's a fiddle: http://jsfiddle.net/00drii/etnkLkL3/3/ The circle is inside the modal.
You have to define a circular SVG path with offset-path property. Then animate the offset-distance property over this path using CSS transition, CSS animation or Web Animations API. Other than defining a SVG path, you can give set offset-path: margin-box. This will define the path as the margin boundary of the parent.
I've never worked with d3.js but you need to put the div that contains the numbers outside the container that you need to scroll.
<div id="app">
<!-- container -->
<div id="scroll-container">
<!-- content of the scroll -->
<div class="content"></div>
</div>
<!-- the numbers should be inside this div -->
<div id="canvas">
</div>
</div>
Here you have an example. Adapt it to your needs.
$(function () {
var radius = 200;
var cant = 36;
var i;
var $circle;
var $scrollcont = $("#scroll-container");
var $canvas = $("#canvas");
//---Create circles
for(i = 0; i < cant; i++){
$circle = $("<div/>");
$circle.attr("data-index", i).addClass("circle").text(i + 1);
$canvas.append($circle);
}
var $circles = $canvas.find(".circle");
//---Update circles position
function updateCirclesPosition(){
//---Scroll value
var scroll = $scrollcont.scrollTop();
//---Vars
var index;
var radian;
var posx;
var posy;
$circles.each(function(){
index = Number( $(this).attr("data-index") );
radian = ((index * 10 + scroll / 10) * Math.PI) / 180;
posx = Math.cos( radian ) * radius;
posy = Math.sin( radian ) * radius + radius;
$(this).css("transform", "translate(" + posx + "px, " + posy + "px)");
});
}
//---On scroll event
$("#scroll-container").on("scroll", updateCirclesPosition);
updateCirclesPosition();
});
#app, #scroll-container, #canvas{
height: 400px;
width: 400px;
}
#app{
position: relative;
}
#scroll-container{
overflow-y: scroll;
position: relative;
z-index: 1;
}
#scroll-container .content{
height: 5000px;
}
#canvas{
position: absolute;
left: 0;
top: 0;
z-index: 0;
}
#canvas .circle{
background: #666;
border-radius: 50%;
-moz-border-radius: 50%;
color: #FFF;
font-family: Arial;
font-size: 10px;
height: 20px;
line-height: 20px;
position: absolute;
text-align: center;
width: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<div id="app">
<div id="scroll-container">
<div class="content"></div>
</div>
<div id="canvas">
</div>
</div>
JSFiddle
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With