TL;DR; http://jsfiddle.net/k7yxtpc7/
编辑(很长?)解释:
所以我们从引导程序的层次结构开始:
<div class="container-fluid">
<div class="row">
<div class="circle_container col-md-6 col-md-offset-3 col-sm-8 col-sm-offset-2 col-xs-12">
</div>
</div>
</div>
图片的行星将被放入.circle_container。我们的目标是确保整个圈子都能响应.circle_container 的宽度变化并正确适应。这样,Boostrap 对容器所做的任何更改都将反映在圆圈本身上,使其符合 Bootstrap。
首先我们要准备一下.circle_container。由于它是一个完整的圆圈,因此容器必须是方形的。我们必须想办法让.circle_container 的高度总是等于它的宽度。我通过在.circle_container 中放置一个方形 img 来做到这一点,然后根据容器的宽度缩放 img 的大小:
<div class="circle_container ...">
<img class="transparent_square" src="http://i.stack.imgur.com/5Y4F4.jpg" width="2" height="2" />
</div>
.transparent_square{
width: 100%;
height: auto;
}
注意:我在网上找不到透明的方形图片,所以我只好凑合着用一个白色的方形。在您的产品中最好使用2pxx2px 透明图片。
太好了,现在我们有了一个方形容器。但我们也给自己设置了限制。从现在开始,img 必须是 .circle_container 的唯一具有静态(默认)或相对位置的孩子,因为任何进一步的孩子都会扩展容器,破坏方形。不过没什么大不了的,因为无论如何我们都会定位其他孩子absolute。
接下来是中心文本气泡:
<div class="central_text text-center">
<h3>Special for you</h3>
<h5>Lorem ipsum</h5>
</div>
.central_text{
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
position: absolute;
}
翻译技巧利用了css变换中的百分位值使用元素的预渲染宽度和高度,而所有其他定位规则使用其父级 的宽度和高度。通过给元素left: 50%; top: 50%,我们将其左上角放在其父元素的中心,然后我们将其向上和向左平移其自身宽度和高度的50%,有效地将元素置于其父元素的中心。这只是在容器中使元素居中的几种方法中的一种,但它最适合我们的情况,因为元素是 absolutely 定位的。
最后我们到达了我们创建圆圈的部分。总结一下这里的技巧:我们将实际图像放入容器中,容器中心有一个轴心点,并将图像放置在容器的一侧,等于圆的半径。这样,当我们旋转图像的容器时,图像会围绕容器的中心移动一圈,就像一个绘图指南针。在图像到达我们想要的位置后,我们将图像本身在另一个方向上旋转相同的角度以补偿方向上的倾斜,使图像再次直立。
容器和图像:
<div class="moon_container moon1"><img class="moon moon1" src="http://letscode.ghost.io/content/images/2015/09/stackoverflow.png"></div>
.moon_container{
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 20%; /* This is the final width of the image */
}
我将.moon_container 的宽度设置为.circle_container 宽度的20%。这将是我们最后一个圆圈中图像的宽度。增加或减少此数字只需根据您的需要更改图像的大小。
现在从容器中偏移图像:
.moon{
width: 100%;
height: auto;
/* The image can be relative positioned without breaking anything because its parent is absolute */
position: relative;
/* The radius of the circle. This is equal to 175%*20% = 35% of .circle_container's width */
left: 175%;
}
请注意,CSS 的 left 使用元素的直接父级宽度作为基本单位。如果你在上一部分改变了.moon_container的宽度,图片的实际距离也会改变。
最后是旋转(这里我以moon2 为例,因为moon1 不需要旋转):
/* Container rotate 45deg clockwise... */
.moon_container.moon2{
/* 360/8 (the number of images) = 45deg */
transform: translate(-50%, -50%) rotate(45deg);
}
/* ... while the image rotate 45deg counter-clockwise */
.moon.moon2{
transform: rotate(-45deg);
}
为什么是transform: translate(-50%, -50%) rotate(45deg); 而不是transform: rotate(45deg);?因为我们之前为.moon_container(居中技巧)声明了transform: translate(-50%, -50%);。如果我们在这里只写transform: rotate(45deg);,CSS 解析器将用新的规则覆盖之前的规则,丢失translate 部分。所以我们必须手动追加。
对所有 8 张图像重复该过程,我们就完成了!
如果您有不确定数量的图像,只需使用 javascript 计算每个图像的旋转部分。
希望我的解释对你有用。我一直不善于解释……
编辑 2: http://jsfiddle.net/k7yxtpc7/3/ 根据 OP 的要求更改悬停版本的文本。这部分只有一件事需要注意,那就是
$("body").on({
mouseenter : function(event){
...
},
mouseleave : function(event){
...
}
}, ".moon");
最好将所有事件绑定到'body' 或document,而不是将它们绑定到实际元素本身(.moon)。这样你:
- 始终只为悬停事件使用 1 个事件侦听器,而不是 8 个(您可以想象实际产品上的数字是如何扩大的)。
- 以后添加更多图片时,不必再次将事件绑定到新的
.moon。
原答案:
由于要求相当模糊,我不知道我的解决方案是否能满足您的要求。我的解决方案基于 3 个假设:
- 整个图像的行星仅基于视口宽度,类似于 Bootstrap 处理其响应式设计的方式。如果您想考虑视口高度,也许我可以想出另一个版本。
- 图像会根据 Bootstrap 容器的宽度进行缩放,以确保有足够的空间来显示所有图像。
- 排版使用 Bootstrap 的默认设置。
该解决方案以无法即时添加/删除图像为代价避免使用 javascript。如果您打算使用动态数量的图像,我会进行计算。
Sexy animations compatible.
不幸的是,Bootstrap 的 center-block 只能水平居中一个块,我不得不使用 translate 技巧来居中枢轴点。
.central_text{
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
position: absolute;
}
这只是一个答案占位符。一旦我们有满意的解决方案,我会写详细的解释。