CSS 3D等距简单旋转变换

时间:2016-05-05 23:26:00

标签: css css3 transform css-animations css-transforms

我正在尝试用door像折叠动画做一个小的CSS动画。我使用SVG作为基础,给它一个等距转换,现在我希望橙色方块可以折叠,就好像它是一个3D空间。

我尝试使用透视,倾斜,变换3D但失败了。

#svgbox {
  position: absolute;
  transform: rotate(-45deg) skew(15deg, 15deg);
  left: 200px;
}
#rect5 {
  animation: rect5anim 3s ease forwards;
  transform-origin: 0% 50%;
  perspective: 1500px;
  /*transform-style: preserve-3d;*/
}
@keyframes rect5anim {
  0% {
    transform: rotateY(0deg);
  }
  100% {
    transform: rotateY(-180deg);
  }
}
<div id="svgbox">
  <svg viewBox="0 0 1200 1200" width="400" height="400" xmlns="http://www.w3.org/2000/svg">
    <defs>
      <linearGradient x1="123.587715%" y1="49.9380835%" x2="24.1186732%" y2="49.9380835%" id="linearGradient-1" gradientTransform="rotate(45)">
        <stop stop-color="#F6851F" offset="0%"></stop>
        <stop stop-color="#F59427" offset="28.32%"></stop>
        <stop stop-color="#F5BB42" offset="100%"></stop>
      </linearGradient>
      <linearGradient x1="126.190394%" y1="50.060688%" x2="22.2418719%" y2="50.060688%" id="linearGradient-2" gradientTransform="rotate(45)">
        <stop stop-color="#F6851F" offset="0%"></stop>
        <stop stop-color="#F5BB42" offset="100%"></stop>
      </linearGradient>
      <linearGradient x1="122.778325%" y1="50.0081081%" x2="24.5036946%" y2="50.0081081%" id="linearGradient-3" gradientTransform="rotate(45)">
        <stop stop-color="#8CC151" offset="0%"></stop>
        <stop stop-color="#98C54C" offset="14.59%"></stop>
        <stop stop-color="#D7DF23" offset="99%"></stop>
      </linearGradient>
      <linearGradient x1="-27.65086%" y1="50.0081081%" x2="72.4520885%" y2="50.0081081%" id="linearGradient-4" gradientTransform="rotate(45)">
        <stop stop-color="#8CC151" offset="0%"></stop>
        <stop stop-color="#D7DF23" offset="99%"></stop>
      </linearGradient>
    </defs>
    <g>
      <rect id="rect1" width="200" height="200" fill="url(#linearGradient-1)" />
      <rect id="rect2" x="201" width="200" height="200" fill="url(#linearGradient-1)" />
      <rect id="rect3" x="401" width="200" height="200" fill="url(#linearGradient-2)" />
      <rect id="rect4" x="601" width="200" height="200" fill="url(#linearGradient-2)" />
      <rect id="rect5" x="801" width="200" height="200" fill="url(#linearGradient-2)" />

      <rect id="rect6" y="201" width="200" height="200" fill="url(#linearGradient-3)" />
      <rect id="rect7" y="401" width="200" height="200" fill="url(#linearGradient-4)" />
      <rect id="rect8" y="601" width="200" height="200" fill="url(#linearGradient-4)" />
    </g>
  </svg>
</div>

1 个答案:

答案 0 :(得分:2)

问题是因为您正在使用perspective属性而不是将透视应用于转换(transform: perspective(x))。 perspective属性不会影响元素的呈现。它只会创建一个将由其子级使用的3D空间。您可以在this CSS Tricks Article

中找到有关此内容的更多信息

值得注意的另一件事是transform-origin的百分比值似乎在Firefox中运行良好。它需要基于px的值,它也应该参考SVG(0,0)。因此,对于#rect5,设置transform-origin: 801px 100px会在FF中生成预期输出。 This CSS Tricks Article有关于此特定问题的详细信息。

下面是一个片段,它使用带有透视的变换来产生所需的效果。

&#13;
&#13;
#svgbox {
  position: absolute;
  transform: rotate(-45deg) skew(15deg, 15deg);
  left: 200px;
}
#rect5 {
  animation: rect5anim 3s ease forwards;
  transform-origin: 801px 100px;
  transform-style: preserve-3d;
}
@keyframes rect5anim {
  0% {
    transform: perspective(1000px) rotateY(0deg);
  }
  100% {
    transform: perspective(1000px) rotateY(180deg);
  }
}
&#13;
<div id="svgbox">
  <svg viewBox="0 0 1200 1200" width="400" height="400" xmlns="http://www.w3.org/2000/svg">
    <defs>
      <linearGradient x1="123.587715%" y1="49.9380835%" x2="24.1186732%" y2="49.9380835%" id="linearGradient-1" gradientTransform="rotate(45)">
        <stop stop-color="#F6851F" offset="0%"></stop>
        <stop stop-color="#F59427" offset="28.32%"></stop>
        <stop stop-color="#F5BB42" offset="100%"></stop>
      </linearGradient>
      <linearGradient x1="126.190394%" y1="50.060688%" x2="22.2418719%" y2="50.060688%" id="linearGradient-2" gradientTransform="rotate(45)">
        <stop stop-color="#F6851F" offset="0%"></stop>
        <stop stop-color="#F5BB42" offset="100%"></stop>
      </linearGradient>
      <linearGradient x1="122.778325%" y1="50.0081081%" x2="24.5036946%" y2="50.0081081%" id="linearGradient-3" gradientTransform="rotate(45)">
        <stop stop-color="#8CC151" offset="0%"></stop>
        <stop stop-color="#98C54C" offset="14.59%"></stop>
        <stop stop-color="#D7DF23" offset="99%"></stop>
      </linearGradient>
      <linearGradient x1="-27.65086%" y1="50.0081081%" x2="72.4520885%" y2="50.0081081%" id="linearGradient-4" gradientTransform="rotate(45)">
        <stop stop-color="#8CC151" offset="0%"></stop>
        <stop stop-color="#D7DF23" offset="99%"></stop>
      </linearGradient>
    </defs>
    <g>
      <rect id="rect1" width="200" height="200" fill="url(#linearGradient-1)" />
      <rect id="rect2" x="201" width="200" height="200" fill="url(#linearGradient-1)" />
      <rect id="rect3" x="401" width="200" height="200" fill="url(#linearGradient-2)" />
      <rect id="rect4" x="601" width="200" height="200" fill="url(#linearGradient-2)" />
      <rect id="rect5" x="801" width="200" height="200" fill="url(#linearGradient-2)" />

      <rect id="rect6" y="201" width="200" height="200" fill="url(#linearGradient-3)" />
      <rect id="rect7" y="401" width="200" height="200" fill="url(#linearGradient-4)" />
      <rect id="rect8" y="601" width="200" height="200" fill="url(#linearGradient-4)" />
    </g>
  </svg>
</div>
&#13;
&#13;
&#13;