我正在尝试构建类似于此站点英雄单位的内容:http://www.nodeplus.com.cn/
我的方法是制作一个临时的2d画布,打印出我的信息,扫描像素,然后用它们将网格定位在3d空间中:
// STEP 1: if a pixel is detected on every gridX / gridY step, put it in the pos array
for (y = 0; y <= height; y += gridY) {
for (x = 0; x <= width; x += gridX) {
if (buffer32[y * width + x]) {
positions.push({x: x, y: y});
}
}
}
然后我将它们放在3d空间中
for (i = 0; i < len; i++) {
pos = positions[i];
shape = new Shape({
x: pos.x / 10,
y: -pos.y / 10,
z: Math.random() * 4
});
shape.init(scene);
shapes.push(shape);
}
这一切都很好,但是我希望它们能够定位在现场中心。 由于我扫描2d画布并从那里获取位置(从0,0开始)的方式,他们在3d空间中得到一些非常奇怪的定位有三个.js(因为我的像素定位像{x:1600, y:500}在更大的屏幕上)
我不得不放一个奇怪的相机。查看它的位置只是为了看它,如:
camera.position.set(100, 0, 80);
camera.lookAt({
x: 95,
y: -50,
z: scene.position.z
});
这种方法现在适用,但对我来说这不是一个好选择。我想围绕字母旋转相机,不想围绕这样一个奇怪的位置旋转它。
您可以在此处查看代码:
var heroUnit = (function(self) {
function Shape(pos) {
this.pos = pos;
this.mesh = null;
this.radius = 2 + Math.random() * 2;
this.speed = 0.4 + Math.random() * 0.4;
}
Shape.prototype.init = function(scene) {
var geometry, material, mesh,
v1, v2, v3;
geometry = new THREE.Geometry();
v1 = new THREE.Vector3(this.pos.x - this.radius / 2, this.pos.y - this.radius / 2, this.pos.z - this.radius / 2);
v2 = new THREE.Vector3(this.pos.x + this.radius / 2, this.pos.y - this.radius / 2, this.pos.z - this.radius / 2);
v3 = new THREE.Vector3(this.pos.x + this.radius / 2, this.pos.y + this.radius / 2, this.pos.z + this.radius / 2);
geometry.vertices.push(v1);
geometry.vertices.push(v2);
geometry.vertices.push(v3);
geometry.faces.push(new THREE.Face3(0, 1, 2));
geometry.computeFaceNormals();
material = new THREE.MeshLambertMaterial({color: Math.random() * 0xFFFFFF});
mesh = new THREE.Mesh(geometry, material);
this.mesh = mesh;
this.mesh.receiveShadow = true;
//this.mesh.scale.set(Math.random() * 20, Math.random() * 20, Math.random() * 20);
this.mesh.rotation.set(0, 0, 0)
scene.add(this.mesh);
}
var width, height,
aspectRatio, pov,
near, far,
scene, camera,
renderer,
effectPositions,
shapes, light;
function init(string) {
// constants
width = window.innerWidth;
height = window.innerHeight;
pov = 45;
aspectRatio = width / height;
near = 0.1;
far = 1000;
// three.js specific stuff
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(pov, aspectRatio, near, far);
renderer = new THREE.WebGLRenderer();
light = new THREE.DirectionalLight(0x000000, 0.6);
// containers
effectPositions = getPixels(string);
shapes = [];
// set up light
light.position.set(100, 0, 200);
light.castShadow = true;
scene.add(light);
// set size to renderer, color it in dark blue & append it to dom
renderer.setSize(width, height);
renderer.setClearColor(0x17293a);
document.body.appendChild(renderer.domElement);
// set up camera
camera.position.set(100, 0, 80);
camera.lookAt({
x: 50,
y: -50,
z: scene.position.z
});
scene.add(camera);
generateShapes(effectPositions);
}
// generate 3d shapes according to our 2d positions array
function generateShapes(positions) {
var i, n, len,
pos, shape,
maxIterations
len = positions.length;
maxIterations = 2;
for (n = 0; n <= maxIterations; n++) {
for (i = 0; i < len; i++) {
pos = positions[i];
shape = new Shape({
x: pos.x / 10,
y: -pos.y / 10,
z: Math.random() * 4
});
shape.init(scene);
shapes.push(shape);
}
}
}
// get 2d positions
function getPixels(string) {
var canvas, ctx,
idata, buffer32,
x, y,
gridX, gridY,
positions;
//make temp canvas on which to draw and get pixel data
canvas = document.createElement('canvas');
ctx = canvas.getContext('2d');
positions = [];
string = string.toUpperCase().split("").join(String.fromCharCode(8202));
canvas.width = width;
canvas.height = height;
//document.body.appendChild(canvas);
ctx.fillStyle = '#000';
ctx.font = 'bold 260px Arial';
ctx.fillText(string, width / 2 - ctx.measureText(string).width / 2, height / 2);
idata = ctx.getImageData(0, 0, width, height);
buffer32 = new Uint32Array(idata.data.buffer);
gridX = gridY = 14;
// if a pixel is detected on every gridX / gridY step, put it in the pos array
for (y = 0; y <= height; y += gridY) {
for (x = 0; x <= width; x += gridX) {
if (buffer32[y * width + x]) {
positions.push({x: x, y: y});
}
}
}
// return pos array
return positions;
}
// render function
function render(ts) {
renderer.render(scene, camera);
shapes.forEach(function(shape) {
// shape.mesh.position.x = shape.dist + (Math.sin(ts / 500)) * shape.speed;
})
}
return {
init: init,
render: render
}
}(heroUnit || {}))
// init our program
heroUnit.init('100');
// redraw each frame
(function drawFrame(ts) {
window.requestAnimationFrame(drawFrame);
heroUnit.render(ts);
}());
&#13;
<script src="//cdnjs.cloudflare.com/ajax/libs/three.js/r71/three.js"></script>
&#13;
任何想法和建议都欢迎,欢呼,