旋转后计算箱形阴影的位置

时间:2012-01-08 14:17:13

标签: javascript html css css3 css-transforms

使用CSS在阴影上旋转元素时,阴影取决于元素的旋转。 Here's an example:

.box {
  width: 200px;
  height: 100px;
  position: absolute;
  left: 20px;
  background-color: #BBF;
  -moz-box-shadow: 10px 10px 5px #888;
  -webkit-box-shadow: 10px 10px 5px #888;
  box-shadow: 10px 10px 5px #888;
}
#box1 {
  top: 20px;
}
#box2 {
  top: 170px;
  -webkit-transform: rotate(20deg);
  -moz-transform: rotate(20deg);
  -o-transform: rotate(20deg);
  -ms-transform: rotate(20deg);
}
#box3 {
  top: 80px;
  left: 250px;
  -webkit-transform: rotate(120deg);
  -moz-transform: rotate(120deg);
  -o-transform: rotate(120deg);
  -ms-transform: rotate(120deg);
}
<div id="box1" class="box"></div>
<div id="box2" class="box"></div>
<div id="box3" class="box"></div>

是否可以计算旋转后阴影应落在哪里,以便阴影看起来来自所有元素上的相同光源?我假设我必须使用javascript或服务器端,这很好。

3 个答案:

答案 0 :(得分:3)

为了在所有元素上复制阴影,旋转或不旋转,我最终使用了以下内容:

var shadowOffset = 13;
var shadowX = Math.round(Math.sin(angle * (Math.PI / 180)) * shadowOffset, 2);
var shadowY = Math.round(Math.cos(angle * (Math.PI / 180)) * shadowOffset, 2);

适合像这样的盒阴影参数:

$("#box2").css({ "box-shadow": shadowX + "px " + shadowY + "px 5px #888" });

这是一个例子:http://jsfiddle.net/3Ybr7/1/

它并不完美,特别是在阴影位于两个像素之间的小元素上,但它有点有效。

答案 1 :(得分:2)

基于此处的答案:Keep box-shadow direction consistent while rotating,您可以使用转换和伪元素在仅限CSS 中执行此操作。
关键在于变换原点随着链式变换中的元素移动。这是所有元素具有相同阴影方向的示例:

.box {
  width: 200px; height: 100px;
  position: absolute;
  left: 20px;
}
.box:before {
  content: '';
  position: absolute;
  top: 5px; left: 5px;
  width: 190px; height: 90px;
  background-color: #888;
  box-shadow: 0px 0px 5px 5px #888;
}
.box:after {
  content: '';
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  background-color: #BBF;
}

#box1 { top: 20px; }
#box1:before { transform: translate(10px, 10px); }

#box2 { top: 170px; transform: rotate(20deg); }
#box2:before { transform: rotate(-20deg) translate(10px, 10px) rotate(20deg); }

#box3 { top: 80px; left: 250px; transform: rotate(120deg); }
#box3:before { transform: rotate(-120deg) translate(10px, 10px) rotate(120deg); }
<div id="box1" class="box"></div>
<div id="box2" class="box"></div>
<div id="box3" class="box"></div>

答案 2 :(得分:0)

我编写了一个convertOffset函数,它接受x和y阴影坐标和度数,并返回新的x / y坐标以匹配旋转。这不仅适用于任何阴影位置,而且还支持嵌入阴影。尝试编辑以下代码段并尝试使用不同的值。

var xOffset = -4;
var yOffset = 5;
var blurSpreadColor = '4px 0 #222';
var inset = false;

for (var i = 1; i < 6; i++) {
  var el = document.getElementById('div' + i);
  var degrees = (i - 1) * 26;
  var offset = convertOffset(xOffset, yOffset, degrees);

  el.style.transform = 'rotate(' + degrees + 'deg)';
  el.style.boxShadow = (inset ? 'inset ' : '') + offset[0] + 'px ' + offset[1] + 'px ' + blurSpreadColor;
}

function convertOffset(x, y, deg) {
  var radians = deg * Math.PI / 180;
  var sin = Math.sin(radians);
  var cos = Math.cos(radians);

  return [
    Math.round((x * cos + y * sin) * 100) / 100,
    Math.round((-x * sin + y * cos) * 100) / 100
  ];
}
.box {
  width: 100px;
  height: 50px;
  background: lightblue;
  margin: 35px 8px;
  display: inline-block;
}
<div class="box" id="div1"></div>
<div class="box" id="div2"></div>
<div class="box" id="div3"></div>
<div class="box" id="div4"></div>
<div class="box" id="div5"></div>