CSS 对 3D 变换元素进行模糊滤镜
CSS blur filter on 3D transformed elements
document.querySelector( 'style' ).innerHTML += `
hr:nth-of-type( 1 ) {
transform: translateZ( calc( var( --mid ) * 1rem ) );
}
hr:nth-of-type( 2 ) {
transform: translateZ( calc( var( --mid ) * -1rem ) );
}
hr:nth-of-type( 3 ) {
transform: rotateY( 90deg ) translateZ( calc( var( --mid ) * 1rem ) );
}
.rotate_y, .rotate_x, hr {
animation-name: rotateY;
animation-duration: 8s;
animation-delay: 0s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
@keyframes rotateY {
0% {
transform: rotateY( 0deg );
}
100% {
transform: rotateY( 360deg );
}
}
.rotate_x {
animation-name: rotateX;
}
@keyframes rotateX {
0% { transform: rotateX( 0deg ); }
100% { transform: rotateX( 360deg ); }
}
`
:root {
--long: 6;
--mid: calc( var( --long ) / 2 );
}
* {
box-sizing: border-box; transform-style: preserve-3d;
margin: 0rem; padding: 0rem;
}
html, body { height: 100%; }
body, section, div, span {
display: flex;
justify-content: center; align-items: center;
}
body {
perspective: calc( var( --long ) * 3rem )
}
span:nth-of-type( 2 ) {
transform: rotateY( 180deg ) rotateX( calc( 90deg ) );
}
span:nth-of-type( 2 ) hr {
box-shadow: 0rem 0rem 0rem 0.25rem #000 inset;
}
section, hr {
position: absolute;
box-shadow: 0rem 0rem 0rem 0.25rem #444 inset;
border-style: none;
width: calc( var( --long ) * 1rem ); height: calc( var( --long ) * 1rem );
background-color: rgba( 200, 200, 200, 0.9 );
}
section {
box-shadow: 0rem 0rem 0rem 0rem transparent;
background-color: transparent;
}
<style>
hr {
animation-name: brightness;
animation-duration: 4s;
animation-timing-function: ease-in-out;
animation-direction: alternate;
}
span:nth-of-type( 1 ) hr:nth-of-type( 1 ) {
animation-delay: 2s;
}
span:nth-of-type( 1 ) hr:nth-of-type( 2 ) {
animation-delay: 3s;
}
span:nth-of-type( 1 ) hr:nth-of-type( 3 ),
span:nth-of-type( 2 ) hr:nth-of-type( 3 ) {
animation-delay: 2s;
}
span:nth-of-type( 2 ) hr:nth-of-type( 1 ),
span:nth-of-type( 2 ) hr:nth-of-type( 2 ) {
animation-delay: 1s;
}
@keyframes brightness {
0% { filter: brightness( 110% ); }
50% { filter: brightness( 50% ); }
100% { filter: brightness( 110% ); }
}
hr{ filter: blur( 0.5rem ); }
</style>
<section class='rotate_x'>
<div class='rotate_y'>
<span> <hr><hr><hr> </span> <span> <hr><hr><hr> </span>
</div>
</section>
在 chrome 中,这个立方体开始模糊,然后迅速恢复到模糊之前的外观;忽略这一行:
hr{ filter: blur( 0.5rem ); }
下面是一张 gif,演示了它的外观:
目的是模糊 3D 转换元素的面。如何使用 Vanilla CSS?
实现此目的
我首先尝试将立方体元素作为一个整体进行模糊,这完全打破了这种错觉。在这里,我试图分别模糊每个 hr
或“脸”。还是没有得到想要的结果
您应该将立方体包裹在另一个没有应用任何 3D 变换的容器中,比方说 .cube
:
<section class='cube'>
<section class='rotate_x'>
<div class='rotate_y'>
<span> <hr><hr><hr> </span> <span> <hr><hr><hr> </span>
</div>
</section>
</section>
然后你就可以毫无问题地应用滤镜动画了:
您还需要将 perspective: calc( var( --long ) * 3rem );
从 body
移动到 .cube
元素本身。
.cube{
animation: focus 3s linear both alternate;
perspective: calc( var( --long ) * 3rem );
}
@keyframes focus {
from {
filter: blur( 0.5rem );
}
to {
filter: blur( 0rem );
}
}
document.querySelector( 'style' ).innerHTML += `
hr:nth-of-type( 1 ) {
transform: translateZ( calc( var( --mid ) * 1rem ) );
}
hr:nth-of-type( 2 ) {
transform: translateZ( calc( var( --mid ) * -1rem ) );
}
hr:nth-of-type( 3 ) {
transform: rotateY( 90deg ) translateZ( calc( var( --mid ) * 1rem ) );
}
.rotate_y, .rotate_x, hr {
animation-name: rotateY;
animation-duration: 8s;
animation-delay: 0s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
@keyframes rotateY {
0% {
transform: rotateY( 0deg );
}
100% {
transform: rotateY( 360deg );
}
}
.rotate_x {
animation-name: rotateX;
}
@keyframes rotateX {
0% { transform: rotateX( 0deg ); }
100% { transform: rotateX( 360deg ); }
}
`
:root {
--long: 6;
--mid: calc( var( --long ) / 2 );
}
* {
box-sizing: border-box; transform-style: preserve-3d;
margin: 0rem; padding: 0rem;
}
html, body { height: 100%; }
body, section, div, span {
display: flex;
justify-content: center; align-items: center;
}
span:nth-of-type( 2 ) {
transform: rotateY( 180deg ) rotateX( calc( 90deg ) );
}
span:nth-of-type( 2 ) hr {
box-shadow: 0rem 0rem 0rem 0.25rem #000 inset;
}
section, hr {
position: absolute;
box-shadow: 0rem 0rem 0rem 0.25rem #444 inset;
border-style: none;
width: calc( var( --long ) * 1rem ); height: calc( var( --long ) * 1rem );
background-color: rgba( 200, 200, 200, 0.9 );
}
section {
box-shadow: 0rem 0rem 0rem 0rem transparent;
background-color: transparent;
}
.cube{
animation: focus 3s linear both alternate;
perspective: calc( var( --long ) * 3rem );
}
@keyframes focus {
from {
filter: blur( 0.5rem );
}
to {
filter: blur( 0rem );
}
}
<style>
hr {
animation-name: brightness;
animation-duration: 4s;
animation-timing-function: ease-in-out;
animation-direction: alternate;
}
span:nth-of-type( 1 ) hr:nth-of-type( 1 ) {
animation-delay: 2s;
}
span:nth-of-type( 1 ) hr:nth-of-type( 2 ) {
animation-delay: 3s;
}
span:nth-of-type( 1 ) hr:nth-of-type( 3 ),
span:nth-of-type( 2 ) hr:nth-of-type( 3 ) {
animation-delay: 2s;
}
span:nth-of-type( 2 ) hr:nth-of-type( 1 ),
span:nth-of-type( 2 ) hr:nth-of-type( 2 ) {
animation-delay: 1s;
}
@keyframes brightness {
0% { filter: brightness( 110% ); }
50% { filter: brightness( 50% ); }
100% { filter: brightness( 110% ); }
}
</style>
<section class='cube'>
<section class='rotate_x'>
<div class='rotate_y'>
<span> <hr><hr><hr> </span> <span> <hr><hr><hr> </span>
</div>
</section>
</section>
document.querySelector( 'style' ).innerHTML += `
hr:nth-of-type( 1 ) {
transform: translateZ( calc( var( --mid ) * 1rem ) );
}
hr:nth-of-type( 2 ) {
transform: translateZ( calc( var( --mid ) * -1rem ) );
}
hr:nth-of-type( 3 ) {
transform: rotateY( 90deg ) translateZ( calc( var( --mid ) * 1rem ) );
}
.rotate_y, .rotate_x, hr {
animation-name: rotateY;
animation-duration: 8s;
animation-delay: 0s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
@keyframes rotateY {
0% {
transform: rotateY( 0deg );
}
100% {
transform: rotateY( 360deg );
}
}
.rotate_x {
animation-name: rotateX;
}
@keyframes rotateX {
0% { transform: rotateX( 0deg ); }
100% { transform: rotateX( 360deg ); }
}
`
:root {
--long: 6;
--mid: calc( var( --long ) / 2 );
}
* {
box-sizing: border-box; transform-style: preserve-3d;
margin: 0rem; padding: 0rem;
}
html, body { height: 100%; }
body, section, div, span {
display: flex;
justify-content: center; align-items: center;
}
body {
perspective: calc( var( --long ) * 3rem )
}
span:nth-of-type( 2 ) {
transform: rotateY( 180deg ) rotateX( calc( 90deg ) );
}
span:nth-of-type( 2 ) hr {
box-shadow: 0rem 0rem 0rem 0.25rem #000 inset;
}
section, hr {
position: absolute;
box-shadow: 0rem 0rem 0rem 0.25rem #444 inset;
border-style: none;
width: calc( var( --long ) * 1rem ); height: calc( var( --long ) * 1rem );
background-color: rgba( 200, 200, 200, 0.9 );
}
section {
box-shadow: 0rem 0rem 0rem 0rem transparent;
background-color: transparent;
}
<style>
hr {
animation-name: brightness;
animation-duration: 4s;
animation-timing-function: ease-in-out;
animation-direction: alternate;
}
span:nth-of-type( 1 ) hr:nth-of-type( 1 ) {
animation-delay: 2s;
}
span:nth-of-type( 1 ) hr:nth-of-type( 2 ) {
animation-delay: 3s;
}
span:nth-of-type( 1 ) hr:nth-of-type( 3 ),
span:nth-of-type( 2 ) hr:nth-of-type( 3 ) {
animation-delay: 2s;
}
span:nth-of-type( 2 ) hr:nth-of-type( 1 ),
span:nth-of-type( 2 ) hr:nth-of-type( 2 ) {
animation-delay: 1s;
}
@keyframes brightness {
0% { filter: brightness( 110% ); }
50% { filter: brightness( 50% ); }
100% { filter: brightness( 110% ); }
}
hr{ filter: blur( 0.5rem ); }
</style>
<section class='rotate_x'>
<div class='rotate_y'>
<span> <hr><hr><hr> </span> <span> <hr><hr><hr> </span>
</div>
</section>
在 chrome 中,这个立方体开始模糊,然后迅速恢复到模糊之前的外观;忽略这一行:
hr{ filter: blur( 0.5rem ); }
下面是一张 gif,演示了它的外观:
目的是模糊 3D 转换元素的面。如何使用 Vanilla CSS?
实现此目的我首先尝试将立方体元素作为一个整体进行模糊,这完全打破了这种错觉。在这里,我试图分别模糊每个 hr
或“脸”。还是没有得到想要的结果
您应该将立方体包裹在另一个没有应用任何 3D 变换的容器中,比方说 .cube
:
<section class='cube'>
<section class='rotate_x'>
<div class='rotate_y'>
<span> <hr><hr><hr> </span> <span> <hr><hr><hr> </span>
</div>
</section>
</section>
然后你就可以毫无问题地应用滤镜动画了:
您还需要将 perspective: calc( var( --long ) * 3rem );
从 body
移动到 .cube
元素本身。
.cube{
animation: focus 3s linear both alternate;
perspective: calc( var( --long ) * 3rem );
}
@keyframes focus {
from {
filter: blur( 0.5rem );
}
to {
filter: blur( 0rem );
}
}
document.querySelector( 'style' ).innerHTML += `
hr:nth-of-type( 1 ) {
transform: translateZ( calc( var( --mid ) * 1rem ) );
}
hr:nth-of-type( 2 ) {
transform: translateZ( calc( var( --mid ) * -1rem ) );
}
hr:nth-of-type( 3 ) {
transform: rotateY( 90deg ) translateZ( calc( var( --mid ) * 1rem ) );
}
.rotate_y, .rotate_x, hr {
animation-name: rotateY;
animation-duration: 8s;
animation-delay: 0s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
@keyframes rotateY {
0% {
transform: rotateY( 0deg );
}
100% {
transform: rotateY( 360deg );
}
}
.rotate_x {
animation-name: rotateX;
}
@keyframes rotateX {
0% { transform: rotateX( 0deg ); }
100% { transform: rotateX( 360deg ); }
}
`
:root {
--long: 6;
--mid: calc( var( --long ) / 2 );
}
* {
box-sizing: border-box; transform-style: preserve-3d;
margin: 0rem; padding: 0rem;
}
html, body { height: 100%; }
body, section, div, span {
display: flex;
justify-content: center; align-items: center;
}
span:nth-of-type( 2 ) {
transform: rotateY( 180deg ) rotateX( calc( 90deg ) );
}
span:nth-of-type( 2 ) hr {
box-shadow: 0rem 0rem 0rem 0.25rem #000 inset;
}
section, hr {
position: absolute;
box-shadow: 0rem 0rem 0rem 0.25rem #444 inset;
border-style: none;
width: calc( var( --long ) * 1rem ); height: calc( var( --long ) * 1rem );
background-color: rgba( 200, 200, 200, 0.9 );
}
section {
box-shadow: 0rem 0rem 0rem 0rem transparent;
background-color: transparent;
}
.cube{
animation: focus 3s linear both alternate;
perspective: calc( var( --long ) * 3rem );
}
@keyframes focus {
from {
filter: blur( 0.5rem );
}
to {
filter: blur( 0rem );
}
}
<style>
hr {
animation-name: brightness;
animation-duration: 4s;
animation-timing-function: ease-in-out;
animation-direction: alternate;
}
span:nth-of-type( 1 ) hr:nth-of-type( 1 ) {
animation-delay: 2s;
}
span:nth-of-type( 1 ) hr:nth-of-type( 2 ) {
animation-delay: 3s;
}
span:nth-of-type( 1 ) hr:nth-of-type( 3 ),
span:nth-of-type( 2 ) hr:nth-of-type( 3 ) {
animation-delay: 2s;
}
span:nth-of-type( 2 ) hr:nth-of-type( 1 ),
span:nth-of-type( 2 ) hr:nth-of-type( 2 ) {
animation-delay: 1s;
}
@keyframes brightness {
0% { filter: brightness( 110% ); }
50% { filter: brightness( 50% ); }
100% { filter: brightness( 110% ); }
}
</style>
<section class='cube'>
<section class='rotate_x'>
<div class='rotate_y'>
<span> <hr><hr><hr> </span> <span> <hr><hr><hr> </span>
</div>
</section>
</section>