我有一个带有文字旋转的div。如何获得文本深度以提供更好的3D效果?为了澄清,在90deg
,文字变得1px
厚,因为我们只能从侧面看到它 - 我该如何制作它,例如,10px
厚?此外,应显示适当的深度 - 即在0deg
我们看不到深度;在45deg
我们看到5px
的深度;在90deg
,我们看到了10px
个完整的深度;等
我正在使用仅限CSS的解决方案。
#spinner {
animation-name: spinner;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-duration: 3s;
transform-style: preserve-3d;
text-align:center;
}
@keyframes spinner {
from {
transform: rotateY(0deg);
}
to {
transform: rotateY(-360deg);
}
}

<p id="spinner">Stop, I'm getting dizzy!</p>
&#13;
答案 0 :(得分:26)
简单text-shadow
可以解决问题:
body {
perspective: 500px;
}
#spinner {
text-align: center;
animation-name: spin, depth;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-duration: 3s;
}
@keyframes spin {
from { transform: rotateY(0deg); }
to { transform: rotateY(-360deg); }
}
@keyframes depth {
0% { text-shadow: 0 0 black; }
25% { text-shadow: 1px 0 black, 2px 0 black, 3px 0 black, 4px 0 black, 5px 0 black; }
50% { text-shadow: 0 0 black; }
75% { text-shadow: -1px 0 black, -2px 0 black, -3px 0 black, -4px 0 black, -5px 0 black; }
100% { text-shadow: 0 0 black; }
}
<p id="spinner">Stop, I'm getting dizzy!</p>
另一项改进可能是使用::before
和::after
伪类克隆文本:
body {
perspective: 1000px;
}
#spinner {
font-size: 50px;
text-align: center;
animation-name: spin, depth;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-duration: 3s;
transform-style: preserve-3d;
position: relative;
}
#spinner::before,
#spinner::after {
content: "Stop, I'm getting dizzy!";
display: block;
position: absolute;
width: 100%;
height: 100%;
top: 0;
transform: rotateY(0.5deg);
transform-origin: 0 50%;
}
#spinner::after {
transform: rotateY(-0.5deg);
transform-origin: 100% 50%;
}
@keyframes spin {
from { transform: rotateY(0deg); }
to { transform: rotateY(-360deg); }
}
@keyframes depth {
0% { text-shadow: 0 0 black; }
25% { text-shadow: 1px 0 black, 2px 0 black, 3px 0 black, 4px 0 black, 5px 0 black, 6px 0 black; }
50% { text-shadow: 0 0 black; }
75% { text-shadow: -1px 0 black, -2px 0 black, -3px 0 black, -4px 0 black, -5px 0 black, -6px 0 black; }
100% { text-shadow: 0 0 black; }
}
<p id="spinner">Stop, I'm getting dizzy!</p>
答案 1 :(得分:5)
纯CSS解决方案看起来不太好。要获得真正的3D效果,请使用JS。我建议使用using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
DataTable dt = new DataTable();
dt.Columns.Add("Col1", typeof(string));
dt.Columns.Add("Col2", typeof(string));
dt.Columns.Add("Col3", typeof(string));
dt.Rows.Add(new object[] {"AAA","BBB","DEF"});
dt.Rows.Add(new object[] {"AAA","BBB","QEW"});
dt.Rows.Add(new object[] {"RRR","WWW","123"});
dt.Rows.Add(new object[] {"RRR","WWW","321"});
dt.Rows.Add(new object[] {"XXX","WWW","421"});
var results = dt.AsEnumerable()
.GroupBy(x => new {col1 = x.Field<string>("Col1"), col2 = x.Field<string>("Col2") })
.Select(x => new {
col1 = x.FirstOrDefault().Field<string>("Col1"),
col2 = x.FirstOrDefault().Field<string>("Col2"),
col3 = string.Join("",x.Select(y => y.Field<string>("Col3")).ToArray())
})
.ToList();
}
}
}
,因为它包含一个相当简单易用的three.js
功能。
我编写了一个脚本,用类textGeometry
替换元素的内容,其中包含一个webGL场景,其中元素内的文本正在旋转。
你当然可以用three.js做各种很酷的效果来制作你的文字look nicer。有关文本格式,请参阅textGeometry doc。请查看three.js docs以获取更多详细信息。
我在代码的注释中添加了一些注释。
rotatingText
&#13;
.rotatingText {
width: 100%;
height: 200px;
}
&#13;
答案 2 :(得分:2)
我使用:before
和:after
元素添加了额外的文本图层,并且我将Y轴分别偏移-3deg和3deg。结果是文本现在具有“某种”深度。如果我使用较短的字符串(例如“RPK”),我可以将偏移量增加到大约7度,并且看起来还不错。但是,这只会给外边缘增加一个“深度”。
#spinner {
animation-name: spinner;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-duration: 3s;
transform-style: preserve-3d;
text-align:center;
font-size:2em;
}
#spinner:after,
#spinner:before {
content:"Stop, I'm getting dizzy!";
position:absolute;
top:0;
left:0;
width:100%;
text-align:center;
transform: rotateY(2deg);
}
#spinner:before {
transform: rotateY(-2deg);
}
#spinner,
#spinner:after,
#spinner:before {
font-weight:narrow;
}
@keyframes spinner {
from {
transform: rotateY(0deg);
}
to {
transform: rotateY(-360deg);
}
}
<p id="spinner">Stop, I'm getting dizzy!</p>
在此版本中,我更改了rotate
的{{1}}属性。同样,使用较短的字符串,这种效果会更好。
translateZ
#spinner {
animation-name: spinner;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-duration: 3s;
transform-style: preserve-3d;
text-align: center;
font-size: 2em;
}
#spinner:after,
#spinner:before {
content: "Stop, I'm getting dizzy!";
position: absolute;
top: 0;
left: 0;
width: 100%;
text-align: center;
transform: translateZ(3px);
}
#spinner:before {
transform:translateZ(-3px);
}
@keyframes spinner {
from {
transform: rotateY(0deg);
}
to {
transform: rotateY(-360deg);
}
}
我不会接受这个作为答案,因为它没有给我我所追求的确切效果。我相信那里有人会找到完美的方法:o)
答案 3 :(得分:2)
添加原始元素的多个克隆,每个克隆后面翻译1px,然后处理它们的颜色以给出3d外观并不是那么糟糕,
check the Pen (仅在Chrome上测试)
<强> HTML 强>
<section>
<p >Stop, I'm getting dizzy!</p>
</section>
<强> SCSS 强>
section{
animation-name: spinner;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-duration: 4s;
transform-style: preserve-3d;
}
p {
text-align: center;
font-size: 2em;
position:absolute;
width:100%;
letter-spacing: 0.2em;
}
@keyframes spinner {
from {
transform: rotateY(0deg);
}
to {
transform: rotateY(-360deg);
}
}
$colors: #000,#111,#222,#333,#444,#555,#666,#777,#888,#999,#aaa,#bbb;
@for $i from 1 through length($colors) {
p:nth-child( #{$i} ){
transform: translateZ(- $i+px);
color: (nth($colors, $i));
}
}
<强> JS 强>
var p = document.querySelector('p');
for(var i = 0 ; i<13 ; i++){
var node = document.createElement('p');
var child = "Stop, I'm getting dizzy!";
child = document.createTextNode(child);
node.appendChild(child);
p.parentNode.appendChild(node);
}
section {
animation-name: spinner;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-duration: 4s;
transform-style: preserve-3d;
}
p {
text-align: center;
font-size: 2em;
position: absolute;
width: 100%;
letter-spacing: 0.2em;
}
p:last-child {
-webkit-text-fill-color: silver;
}
@keyframes spinner {
from {
transform: rotateY(0deg);
}
to {
transform: rotateY(-360deg);
}
}
p:nth-child(1) {
transform: translateZ(-1px);
color: #000;
}
p:nth-child(2) {
transform: translateZ(-2px);
color: #111;
}
p:nth-child(3) {
transform: translateZ(-3px);
color: #222;
}
p:nth-child(4) {
transform: translateZ(-4px);
color: #333;
}
p:nth-child(5) {
transform: translateZ(-5px);
color: #444;
}
p:nth-child(6) {
transform: translateZ(-6px);
color: #555;
}
p:nth-child(7) {
transform: translateZ(-7px);
color: #666;
}
p:nth-child(8) {
transform: translateZ(-8px);
color: #777;
}
p:nth-child(9) {
transform: translateZ(-9px);
color: #888;
}
p:nth-child(10) {
transform: translateZ(-10px);
color: #999;
}
p:nth-child(11) {
transform: translateZ(-11px);
color: #aaa;
}
p:nth-child(12) {
transform: translateZ(-12px);
color: #bbb;
}
<section>
<p>Stop, I'm getting dizzy!</p>
<p>Stop, I'm getting dizzy!</p>
<p>Stop, I'm getting dizzy!</p>
<p>Stop, I'm getting dizzy!</p>
<p>Stop, I'm getting dizzy!</p>
<p>Stop, I'm getting dizzy!</p>
<p>Stop, I'm getting dizzy!</p>
<p>Stop, I'm getting dizzy!</p>
<p>Stop, I'm getting dizzy!</p>
<p>Stop, I'm getting dizzy!</p>
<p>Stop, I'm getting dizzy!</p>
<p>Stop, I'm getting dizzy!</p>
</section>