【问题标题】:Keep box-shadow direction consistent while rotating旋转时保持盒子阴影方向一致
【发布时间】:2016-02-01 21:00:50
【问题描述】:

例如给予时a <div> box-shadow 以及旋转它会导致 box-shadow 方向的旋转 - 当 box-shadow 应该产生照明错觉时这是有问题的。

示例:https://jsfiddle.net/5h7z4swk/

div {
  width: 50px;
  height: 50px;
  margin: 20px;
  box-shadow: 10px 10px 10px #000;
  display: inline-block;
}
#box1 {
  background-color: #b00;
}
#box2 {
  background-color: #0b0;
  transform: rotate(30deg);
}
#box3 {
  background-color: #00b;
  transform: rotate(60deg);
}
#box4 {
  background-color: #b0b;
  transform: rotate(90deg);
}
@keyframes spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
#box6 {
  background-color: #0bb;
  animation-name: spin;
  animation-duration: 2s;
  animation-iteration-count: infinite;
}
<div id="box1"></div>
<div id="box2"></div>
<div id="box3"></div>
<div id="box4"></div>
<div id="box6"></div>

这个问题的答案应该类似于这个模型:

如何在旋转&lt;div&gt; 的同时保持盒子阴影的方向相同?

解决方案应该是纯CSS...

注意:CSS 中的动画用于演示目的。用例将使用 JavaScript 设置旋转。但是 JavaScript 对 box-shadow 一无所知,因为定义一个(或许多...)阴影是设计的责任。这就是为什么它应该是一个纯 CSS 解决方案。

【问题讨论】:

  • 它按你的意愿工作
  • 如果没有某种 javascript 库和大量数学运算,这可能会非常困难,因为浏览器没有任何类型的光源
  • @zgood 你可能在想我在想什么,但我们都误解了 OP。如果您查看 web-tiki 提供的答案,我认为这就是 OP 想要的

标签: html css css-animations css-transforms


【解决方案1】:

在旋转期间保持偏移箱阴影的方向一致使用 CSS 转换很简单。
这种方法依赖于 transform origin 随变换一起移动的事实。这意味着当在同一个元素上设置多个变换时,每个变换的坐标系都会根据之前的坐标系发生变化。

在下面的例子中,蓝色元素是伪元素,阴影是 div 元素:

div {
  width: 40px; height: 40px;
  margin: 40px;
  box-shadow: 0px 0px 10px 5px #000;
  animation: spinShadow 2s infinite;
  background-color: #000;
}
@keyframes spinShadow {
  to { transform: rotate(360deg); }
}
div:before {
  content: '';
  position: absolute;
  left:-5px; top:-5px;
  width: 50px; height: 50px;
  transform: rotate(0deg) translate(-10px, -10px) rotate(0deg);
  animation:inherit;
  animation-name: spinElt;
  background-color: #0bb;
}
@keyframes spinElt {
  to { transform: rotate(-360deg) translate(-10px, -10px) rotate(360deg); }
}
&lt;div&gt;&lt;/div&gt;

伪元素上的transition属性说明(步骤说明见以下代码sn-p):

transform: rotate(-360deg) translate(-10px, -10px) rotate(360deg)
  1. rotate(-360deg) 会阻止父元素的旋转以使伪元素变为静态。
  2. translate(-10px, -10px) 伪元素被翻译成阴影偏移
  3. rotate(360deg) 伪元素与父元素同向旋转

div {
  width: 40px; height: 40px;
  margin: 40px;
  box-shadow: 0px 0px 10px 5px #000;
  animation: spinShadow 2s infinite;
  background-color: #000;
}
@keyframes spinShadow {
  to { transform: rotate(360deg); }
}
div:before {
  content: '';
  position: absolute;
  left:-5px; top:-5px;
  width: 50px; height: 50px;
  animation:inherit;
  background-color: #0bb;
}
#first:before{
  transform: rotate(0deg);
  animation-name: first;
}  
@keyframes first {
  to { transform: rotate(-360deg); }
}
#second:before{
  transform: rotate(0deg) translate(-10px, -10px);
  animation-name: second;
}  
@keyframes second {
  to { transform: rotate(-360deg) translate(-10px, -10px); }
}
#complete:before{
  transform: rotate(0deg) translate(-10px, -10px) rotate(0deg);
  animation-name: complete;
}  
@keyframes complete {
  to { transform: rotate(-360deg) translate(-10px, -10px) rotate(360deg); }
}
<ol>
  <li>Counter rotate:<div id="first"></div></li>
  <li>Translate :<div id="second"></div></li>
  <li>Rotate:<div id="complete"></div></li>
<ol>

【讨论】:

  • 我以为他想要静态的影子。我删除了我的答案,因为这是一个更好的解决方案。但我以为影子不会移动
  • 哇。比我想象的要容易得多,而且非常聪明。干得好
【解决方案2】:

您也可以在动画帧中集成 box-shadow 方向:

div {
  display: inline-block;
  margin: 1em ;
  height: 50px;
  width: 50px;
  box-shadow: 15px 15px 15px 5px gray;
  animation: rte 5s infinite linear;
}

.red {
  background: red
}

.green {
  background: green;
  animation-delay:2s;
}

.blue {
  background: blue;
  animation-delay:4s;
}

.bob {
  background: #b0b;
  animation-delay:6s;
}

.cyan {
  background: cyan;
  animation-delay:8s;
}

@keyframes rte {
  25% {
    box-shadow:  15px -15px 15px 5px gray;
  }
  50% {
      box-shadow:  -15px -15px 15px 5px gray;
  }
  75% {
    box-shadow:  -15px 15px 15px 5px gray;
  }
  100% {
    transform: rotate(360deg);
  }
}
<div class="red"></div>
<div class="green"></div>
<div class="blue"></div>
<div class="bob"></div>
<div class="cyan"></div>

【讨论】:

    【解决方案3】:

    受其他答案的启发,我也创建了自己的答案: https://jsfiddle.net/zoxgbcrg/1/

    .shadow {
      background-color: black !important;
      width: 40px;
      height: 40px;
      box-shadow: 0px 0px 10px 5px #000;
      margin-top: 35px;
      margin-left: 35px;
      position: absolute;
      z-index: -1;
    }
    &lt;div class="box1 shadow"&gt;&lt;/div&gt;&lt;div class="box1"&gt;&lt;/div&gt;

    诀窍还在于创建一个额外的&lt;div&gt; 来处理阴影。就我而言,它不是:before,而是由margin 移动的真实DOM 元素。

    注意:今天(2016 年 1 月 31 日)Firefox 和 Chrome 似乎存在细微的渲染差异。因此,对于 Firefox,https://jsfiddle.net/zoxgbcrg/ 正在创建所需的结果,对于 Chrome,我建议 https://jsfiddle.net/zoxgbcrg/1/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多