计算旋转后box-shadow的位置

发布于 2024-12-25 07:31:30 字数 1077 浏览 4 评论 0原文

当使用 CSS 在旋转的元素上添加阴影时,阴影取决于元素的旋转。 这是一个示例:

.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 或服务器端来完成此操作,这很好。

When putting shadows on rotated elements with CSS, the shadow depends on the rotation of the element. 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>

Is it possible to calculate where the shadow should fall after the rotation, so that the shadow appears to come from the same light source on all elements? I'm assuming I'd have to do it with javascript or server-side, which is fine.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

镜花水月 2025-01-01 07:31:30

为了在所有元素上复制相同的阴影,无论旋转与否,我最终使用了以下内容:

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);

它适合像这样的 box-shadows 参数:

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

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

它并不完美,特别是在阴影位于两个像素之间的小元素上,但它排序的作品。

To replicate the shadow somewhat the same on all elements, rotated or not, I ended up using the following:

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);

Which fits into box-shadows parameters like this:

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

And here's an example: http://jsfiddle.net/3Ybr7/1/

It's not perfect, especially on small elements where the shadow would've been positioned between two pixels, but it sort of works.

奶气 2025-01-01 07:31:30

根据此处的答案:旋转时保持框阴影方向一致,您只能在 CSS 中执行此操作< /em> 使用变换和伪元素。
要点是变换原点随着链式变换中的元素一起移动。这是所有元素具有相同阴影方向的示例:

.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>

Based on the answer here: Keep box-shadow direction consistent while rotating, you can do this in CSS only using transforms and pseudo elements.
The point is that the transforms origin moves with the element in chained transforms. here is your example with the same shadow direction for all the elements:

.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>

回忆凄美了谁 2025-01-01 07:31:30

我编写了一个 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>

I wrote a convertOffset function that takes x and y shadow coordinates and degrees, and returns the new x/y coordinates to match the rotation. Not only does this work with any shadow position, but it also supports inset shadows. Try editing the below snippet and experimenting with different values.

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>

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文