three.js:如何拉伸图像文件定义的形状

时间:2019-05-07 12:50:39

标签: javascript three.js shapes

如何用提供的叶子替换心脏?

我正在使用Three.JS使用下降对象构建此Web应用程序。 我找到了可以开始的心形形状,但是现在我需要用秋天的叶子代替该形状(实际上,这是唯一要做的事情。)

这是图像: image

我不太了解形状在这方面的作用。

亲自尝试:

'use strict';

var container, stats;
var camera, scene, renderer;
var group,
    shapes = [];
init();

function init() {
  container = document.createElement('div');
  document.body.appendChild(container);
  scene = new THREE.Scene();
  camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 1000);
  camera.position.set(0, 150, 500);
  scene.add(camera);

  var light = new THREE.DirectionalLight(0x9955ff, 2);
  light.position.x = -500;
  light.position.y = 500;
  camera.add(light);

  var light = new THREE.DirectionalLight(0x9955ff, 1);
  light.position.x = 500;
  light.position.y = -500;
  light.position.z = -150;
  camera.add(light);

  scene.background = new THREE.Color('#993355');

  var x = -25,
      y = -250;
  var heartShape = new THREE.Shape();
  heartShape.moveTo(x + 25, y + 25);
  heartShape.bezierCurveTo(x + 25, y + 25, x + 20, y, x, y);
  heartShape.bezierCurveTo(x - 30, y, x - 30, y + 35, x - 30, y + 35);
  heartShape.bezierCurveTo(x - 30, y + 55, x - 10, y + 77, x + 25, y + 95);
  heartShape.bezierCurveTo(x + 60, y + 77, x + 80, y + 55, x + 80, y + 35);
  heartShape.bezierCurveTo(x + 80, y + 35, x + 80, y, x + 50, y);
  heartShape.bezierCurveTo(x + 35, y, x + 25, y + 25, x + 25, y + 25);

  var extrudeSettings = { amount: 1, bevelEnabled: true, bevelSegments: 20, steps: 2, bevelSize: 20, bevelThickness: 10 };

  for (var i = -window.innerWidth / 2; i < window.innerWidth / 2; i += 60 + Math.random() * 50) {
    for (var j = 0; j < window.innerHeight; j += 60 + Math.random() * 50) {
      addShape(heartShape, extrudeSettings, '#ff0022', i, j, 0, Math.random() * 0.8, Math.random() * 0.8, Math.PI, 0.1 + Math.random() * 0.3);
    }
  }

  renderer = new THREE.WebGLRenderer({ antialias: true });
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(window.innerWidth, window.innerHeight);
  container.appendChild(renderer.domElement);

  render();
}

function addShape(shape, extrudeSettings, color, x, y, z, rx, ry, rz, s) {
  var geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings);
  var mesh = new THREE.Mesh(geometry, new THREE.MeshPhongMaterial({ color: color }));
  mesh.position.set(x + 25, y - 50, z);
  mesh.rotation.set(rx, ry, rz);
  mesh.scale.set(s, s, s);
  shapes.push({ shape: mesh, x: Math.random(), y: Math.random(), z: Math.random() });
  scene.add(mesh);
}

function animate() {
  var speed = 0.05;
  shapes.forEach(function (el) {
    el.shape.rotation.x += el.x * speed;
    el.shape.rotation.y += el.y * speed;
    el.shape.rotation.z += el.z * speed;
  });
}

function render() {
  requestAnimationFrame(render);
  animate();
  renderer.render(scene, camera);
}
body{
  margin: 0;
  padding: 0;
  overflow: hidden;
}
<script src='https://cdnjs.cloudflare.com/ajax/libs/three.js/r79/three.min.js'></script>

它必须相同,完全相同。只有心需要用叶子代替。

1 个答案:

答案 0 :(得分:0)

您要拉伸图像文件定义的形状。

首先,使用在线图像转换器(例如https://image.online-convert.com/convert-to-svg)将文件转换为SVG格式。 (对于您的情况,您将必须手动编辑生成的SVG文件以删除边界圆。)如果需要,可以将SVG内容定义为字符串。

var text = `<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
 "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
 width="800.000000pt" height="800.000000pt" viewBox="0 0 800.000000 800.000000"
 preserveAspectRatio="xMidYMid meet">
<metadata>
Created by potrace 1.15, written by Peter Selinger 2001-2017
</metadata>
<g transform="translate(0.000000,800.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="m311 -1104 c9 -47 29 -114 44 -150 53 -126 236 -481 250 -487 8 -3
27 2 41 12 41 27 50 15 57 -77 10 -147 47 -198 142 -198 30 0 44 7 71 36 19
19 38 33 44 29 20 -12 22 -79 5 -182 -27 -165 -5 -311 70 -468 42 -88 66 -104
131 -87 60 16 213 86 529 242 207 102 277 142 342 194 45 36 87 66 93 66 20 0
5 -54 -100 -375 -108 -330 -125 -398 -118 -480 6 -70 27 -95 80 -95 50 0 58
-20 24 -63 -104 -128 -106 -132 -106 -170 0 -53 37 -88 125 -117 76 -24 98
-39 87 -56 -4 -6 -52 -41 -107 -77 -157 -102 -225 -186 -225 -276 0 -53 37
-96 112 -128 32 -14 58 -32 58 -40 0 -25 -103 -62 -343 -122 -313 -79 -327
-87 -267 -152 39 -44 26 -58 -38 -40 -77 20 -522 215 -740 323 -138 69 -206
98 -213 91 -7 -7 -2 -48 15 -130 14 -66 42 -212 63 -324 36 -198 37 -211 38
-436 l0 -233 -30 -29 c-43 -43 -109 -58 -157 -38 -48 20 -81 71 -73 112 3 17
30 71 60 120 30 50 61 110 70 134 17 50 19 165 4 231 -6 25 -35 161 -64 304
-29 142 -58 263 -64 269 -8 8 -27 4 -68 -12 -112 -45 -340 -160 -538 -271
-214 -121 -410 -220 -431 -220 -20 0 -17 10 16 59 63 93 50 98 -280 104 -228
4 -276 7 -342 25 -101 27 -218 74 -216 87 1 6 20 15 43 20 63 17 103 46 207
153 114 118 134 160 103 219 -15 28 -38 44 -114 81 l-96 46 48 6 c57 7 67 19
67 82 0 37 -12 70 -66 175 -79 154 -131 234 -218 333 l-65 75 32 3 c40 4 53
15 60 50 3 15 -7 133 -23 263 -45 365 -54 488 -41 537 14 50 27 54 36 10 30
-142 186 -273 524 -443 287 -143 369 -164 401 -100 21 43 25 177 7 263 -8 39
-13 81 -10 92 5 19 7 18 25 -11 18 -30 21 -31 70 -27 94 9 148 97 148 239 0
79 29 114 58 69 17 -28 54 -25 85 8 32 33 73 123 82 177 12 74 15 85 30 85 8
0 15 -4 15 -10 0 -16 25 -11 53 10 26 20 31 33 62 145 l17 60 14 -28 c8 -15
18 -27 22 -27 21 0 58 41 118 131 74 111 131 233 163 354 38 137 42 146 59
143 11 -2 21 -27 33 -88z"/>
</g>
</svg>`;

然后,使用THREE.SVGLoader解析并拉伸文件。

var data = new THREE.SVGLoader().parse( text );

var paths = data.paths;

var shapes = [];

for ( var i = 0; i < paths.length; i ++ ) {

    Array.prototype.push.apply( shapes, paths[ i ].toShapes() ); // catenate, so we can create a single geometry and mesh

}

var extrusionSettings = {
    depth: 20,
    bevelEnabled: false
};

var geometry = new THREE.ExtrudeBufferGeometry( shapes, extrusionSettings );
geometry.center();

var mesh = new THREE.Mesh( geometry, material );
mesh.scale.y *= - 1;

scene.add( mesh );

SVGLoader位于threejs/examples/js/loaders/目录中,必须包含在您的项目中。

rendering of extruded shape

three.js r.104