Подтвердить что ты не робот

CSS только 3D прядильный текст

У меня есть 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>
4b9b3361

Ответ 1

Простой 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>

Ответ 2

Чистое решение CSS не будет выглядеть хорошо. Для действительно 3D-эффекта используйте JS. Я рекомендую использовать three.js, потому что у него есть довольно простая в использовании функция textGeometry.

Я написал script, который заменяет содержимое элементов классом rotatingText сценой webGL, где текст, находящийся внутри элемента, вращается.

Вы можете, конечно, делать всевозможные классные эффекты с помощью трёх .js, чтобы сделать ваш текст выглядеть лучше. См. textGeometry doc для форматирования текста. Подробнее см. three.js docs.

Я добавил некоторые примечания в комментарии к коду.

.rotatingText {
  width: 100%;
  height: 200px;
}
<!--your rotating text, just give it class rotatingText-->
<div class="rotatingText">Stop, I'm getting dizzy!</div>


<!--three.js library-->
<script src="https://ajax.googleapis.com/ajax/libs/threejs/r69/three.min.js"></script>
<!--the default font for three.js-->
<script src="http://threejs.org/examples/fonts/helvetiker_regular.typeface.js"></script>
<!--the script that converts each .rotatingText element into 3D -->
<script>
  function rotateText(container,i){
    var t = THREE;
    var containerW = container.offsetWidth;
    var containerH = container.offsetHeight;
    var theText = container.innerHTML; //grab the text from the element...
    container.innerHTML = ""; // ...and clear it
    var renderer = new t.WebGLRenderer({
      alpha: true,
      antialiasing: true
    });
    renderer.setSize(containerW, containerH);
    renderer.setClearColor(0x000000, 0);
    container.appendChild(renderer.domElement);
    var scene = new t.Scene();
    var camera = new t.PerspectiveCamera(
      75, //vertical field of view
      containerW / containerH, //aspect ratio
      0.1, //near plane
      1000 //far plane
    );
    scene.add(camera);
    camera.position.set(0, 0, 100);
    // This is your 3D text:
    var geometry = new t.TextGeometry(theText, { //insert the text we grabbed earlier here
      size: 10, //your font size
      height: 1 //your font depth
    });
    var material = new t.MeshLambertMaterial({
      color: 0x000000 //your font color
    });
    var text = new t.Mesh(geometry, material); //this is your 3D text object
    //I created a pivot object to act as the center point for rotation:
    geometry.computeBoundingBox();
    var textWidth = geometry.boundingBox.max.x - geometry.boundingBox.min.x;
    text.position.set(-0.5 * textWidth, 0, 0);
    scene.add(text);
    var pivot = new t.Object3D();
    pivot.add(text);
    scene.add(pivot);
    //Then just render your scene and request for new frames
    this.render = function() {
      pivot.rotation.y += .02; //how much you want your text to rotate per frame
      requestAnimationFrame(render);
      renderer.render(scene, camera);
    }
    render();
  }

  var rotatingTextElements = document.getElementsByClassName("rotatingText");
  for (var i = 0; i < rotatingTextElements.length; i++) {
    rotateText(rotatingTextElements[i]);
  }
</script>

Ответ 3

Я добавил дополнительные слои текста, используя элементы :before и :after, и я смещал их ось Y на -3deg и 3deg соответственно. В результате текст теперь имеет "своего рода" глубину. Если я использую более короткую строку (например, "RPK" ), я могу увеличить смещение до 7deg и все еще иметь вид OK. Однако это только дает внешним краям дополнительную "глубину".

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

Ответ 4

Добавление нескольких клонов исходного элемента, каждый из которых переведен на 1px позади, а затем работает над их цветом, чтобы придать 3D-вид не совсем так,

проверить 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>