我见过人们使用transform获得3-D效果。

但是,如果我们只需要旋转<div>的某些部分,我发现没有什么非常有用的。

我想知道我们如何应用变换以获得凹形,凸形等3-D效果。

如果我们只希望变换此<div>的10%或想要从左到右或从上到下增加和减少的变换,该怎么办?

或者,考虑一个球体,并说您想将<div>包裹在球体上,如何实现?

最佳答案

在撰写本文时,HTML元素是扁平的。
即使CSS3引入了3D Tranforms,它们也仅用于转换,而不用于呈现形状。

实际上,您可以通过这样的转换来渲染由6个平面HTMLElement组成的3d立方体,但是它们仍然是平面的。

see this David Walsh article on how to make a CSS Cube

我们可能可以采用这种想法来创建一个球体,但是对于一个如下图所示的光滑球体,它将涉及200个多边形,这意味着200个不同的元素,每个元素都有其唯一的transform声明,您将不得不打破将您的内容纳入这些元素的每一个。

javascript - HTML,CSS中的3D曲率拟合-LMLPHP
我会让你找到数学来做这样的事情...

要在网页中渲染3d对象,可以使用html5 <canvas>元素引入的WebGL API

因此,一种解决方案,如果确实需要您的内容来获得3d效果,则是首先使用html2canvas之类的库获取元素的快照,然后将其用作webgl上下文中的纹理。
这是使用three.js库的示例。



var div = document.querySelector('div');
	html2canvas(div, {
	  onrendered: function(canvas) {
	    initCanvas(div, canvas.toDataURL());
	  }
	});

	function initCanvas(replacedElement, src) {
	  var size = replacedElement.getBoundingClientRect();

	  var scene = new THREE.Scene();
	  var camera = new THREE.PerspectiveCamera(75, size.width / size.height, 0.1, 1000);
	  var renderer = new THREE.WebGLRenderer();

	  renderer.setSize(size.width, size.height);
	  renderer.domElement.setAttribute('style', 'top:' + size.top + 'px; left:' + size.left + 'px; position:absolute;');
	  replacedElement.parentNode.insertBefore(renderer.domElement, replacedElement.nextNode);

	  var geometry = new THREE.SphereGeometry(0.5, 32, 32)
	  var material = new THREE.MeshPhongMaterial()


	  var sphere = new THREE.Mesh(geometry, material);
	  scene.add(sphere);
	  material.map = THREE.ImageUtils.loadTexture(src)
	  material.map.minFilter = THREE.LinearFilter;
	  var light = new THREE.PointLight('#FFF', 10, 100);
	  light.position.set(32, 32, 80);
	  scene.add(light);
	  camera.position.z = 1;

	  function render() {
	    requestAnimationFrame(render);
	    renderer.render(scene, camera);
	    sphere.rotation.x += .01
	    sphere.rotation.y += .01
	  }
	  render();
	}

window.onresize=function(){	html2canvas(div, {
	  onrendered: function(canvas) {
        var c = document.querySelector('canvas');
        if(c)c.parentNode.removeChild(c);
	    initCanvas(div, canvas.toDataURL());
	  }
	});}

div {
  background-color: rgba(255, 255, 255, 0.5);
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r71/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>
<div>


  <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet bibendum augue, nec convallis enim bibendum non. Donec sagittis finibus lorem nec porttitor. Donec vel tincidunt ante. Praesent semper luctus arcu, at eleifend nibh dapibus sit
    amet. Aenean maximus ex in luctus bibendum. Nullam in ligula quis tellus convallis rutrum. Vivamus id placerat metus. Morbi efficitur sem at cursus bibendum. Ut fermentum odio in lectus posuere accumsan. Etiam imperdiet metus at ornare tempus. Suspendisse
    nulla metus, aliquam viverra elementum sed, consequat ac est. Sed lorem neque, finibus ac ultricies vel, ullamcorper ut nibh. Praesent est nulla, dictum eu commodo nec, sollicitudin condimentum ante.
  </p>
  <p>
    Donec metus nulla, rutrum ultrices elementum quis, blandit ac nisl. Etiam fermentum pharetra dui, vel eleifend ante blandit nec. Nunc varius eget arcu sit amet fermentum. Sed lorem turpis, mattis suscipit orci ut, feugiat volutpat dolor. Ut eu est dolor.
    Nulla aliquam libero at libero maximus, eget porta lorem malesuada. Curabitur in odio dolor. Praesent iaculis feugiat ipsum at malesuada. Nulla sed commodo leo, at fringilla arcu. Nulla tempus tellus sit amet augue sodales efficitur. Vestibulum tristique
    nunc et eros ornare, et mollis mi pellentesque. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.
  </p>
  <p>
    Donec eu posuere sem. Etiam et massa non purus vehicula feugiat. Integer porta velit metus, eget tempor purus posuere non. Nam aliquam, lectus nec finibus venenatis, nunc urna porta lorem, commodo vehicula ex ante at augue. Vivamus nec erat sit amet nibh
    congue ullamcorper eget a eros. Integer varius turpis ut ex mollis, nec scelerisque est pretium. Phasellus nec lorem convallis, tincidunt ligula nec, ornare metus. Vivamus at lorem eget augue rhoncus varius. Curabitur hendrerit, nibh ut sagittis ultrices,
    ipsum elit tempus arcu, ac ullamcorper metus magna in lacus. Morbi elementum imperdiet magna in ultrices. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec sed fermentum leo, ac cursus sapien. Proin neque nisi, tempor vel massa et, consectetur
    eleifend sem.
  </p>
  <p>
    Aliquam erat volutpat. Donec lectus velit, rhoncus non euismod in, scelerisque sed libero. Nunc et neque est. Nam viverra ac quam interdum auctor. Nulla sed lacus mauris. Proin sit amet ultricies lorem. Vestibulum ante ipsum primis in faucibus orci luctus
    et ultrices posuere cubilia Curae; In hac habitasse platea dictumst. Nulla sed cursus neque.
  </p>
  <p>
    Curabitur blandit ipsum fermentum mauris consequat, ut feugiat nisl consequat. Nullam sit amet commodo diam. Etiam fringilla felis et augue mattis, sed dapibus massa tristique. Mauris ut nisi eget ex faucibus hendrerit. Mauris ut nisi nulla. Aenean et
    urna dolor. Aenean consectetur metus urna, a mattis orci pretium nec. Pellentesque non augue magna. In accumsan nisl tellus, id porttitor nisi feugiat eu. Curabitur eleifend urna ac augue congue tincidunt.
  </p>
</div>





但是<canvas>元素仅呈现像素图像,而不是HTML元素,这意味着内容将不再是可选的,链接将被破坏等... *,您将面对html2canvas' limitations
*请注意,您可以通过大量计算来解决这些问题

如果您真的不需要对内容产生这种影响,另一种解决方案是使用CSS径向渐变和边框半径来伪造内容,如James Holdernessthis answer中所建议的那样:



var div = document.querySelector('div');
var pt=-100;
function animBG(){
	pt=((pt+101)%300)-100;
	div.style.backgroundImage= 'radial-gradient(ellipse at '+pt+'% '+pt+'% , rgb(255, 255, 255) 0%, rgb(214, 214, 214) 45%, rgb(174, 176, 173) 58%)';
	requestAnimationFrame(animBG)
	}
animBG();

div {
		  height: 600px;
		  width: 600px;
		  border-radius: 100%;
		  background: transparent radial-gradient(ellipse at 30% 20%, rgb(255, 255, 255) 0%, rgb(214, 214, 214) 45%, rgb(174, 176, 173) 58%) repeat scroll 0% 0%;
		  text-align: center;
		  position: relative;
          box-shadow: inset 0px 0px 15px rgba(60,60,60,.5);
		}
		div>p {
		  width: 344px;
		  position: absolute;
		  top: 50%;
		  left: 50%;
		  -webkit-transform: translate(-50%, -50%);
		  transform: translate(-50%, -50%);
		  color: rgba(0, 0, 0, .7)
		}

<div>


  <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet bibendum augue, nec convallis enim bibendum non. Donec sagittis finibus lorem nec porttitor. Donec vel tincidunt ante. Praesent semper luctus arcu, at eleifend nibh dapibus sit
    amet. Aenean maximus ex in luctus bibendum. Nullam in ligula quis tellus convallis rutrum. Vivamus id placerat metus. Morbi efficitur sem at cursus bibendum. Ut fermentum odio in lectus posuere accumsan. Etiam imperdiet metus at ornare tempus. Suspendisse
    nulla metus, aliquam viverra elementum sed, consequat ac est. Sed lorem neque, finibus ac ultricies vel, ullamcorper ut nibh. Praesent est nulla, dictum eu commodo nec, sollicitudin condimentum ante.
  </p>

</div>

关于javascript - HTML,CSS中的3D曲率拟合,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31957252/

10-13 21:49