JavaScript
three.js
es6

おしゃれな3Dメニュー

More than 1 year has passed since last update.

デモ:https://mo49.github.io/qiita/20160908/menu.html

(クリックで表示)


メニューを作る

const imageFiles = [

"nav_camera.png",
"nav_phone.png",
"nav_mail.png",
"nav_settings.png"
];

this.menu1 = this.createMenu(imageFiles, 10);



メニューを表示する

this.showMenu(this.menu1,0,0,0,50,10); // menu, offsetX, offsetY, offsetZ, radius, space


全体はこんな感じ

createMenu (imageFiles, diameter) {

this.menus = [];

for (let [i, src] of imageFiles.entries()) {
const geom = new THREE.PlaneGeometry(diameter,diameter,20);
const plane = this.createMesh(geom, src);
plane.visible = false; // 一旦非表示
this.scene.add(plane);
this.menus.push(plane);
}

return this.menus;
}

createMesh (geom, imageFile) {
const PATH = './img/texture/';
const textureLoader = new THREE.TextureLoader();
const texture = textureLoader.load(PATH + imageFile);
const mat = new THREE.MeshBasicMaterial({transparent:true});
mat.map = texture;

const mesh = new THREE.Mesh(geom, mat);
return mesh;
}

showMenu(menus, offsetX, offsetY, offsetZ, radius, space) {

const that = this;
let degree = 0;
let loopId;

update();
function update() {
loopId = requestAnimationFrame(update);
for (let [i, menu] of menus.entries()) {
menu.visible = true; // 表示
if (degree > i*space) {
continue;
}
const pos = move(radius, i+1); // radius, index
menu.position.set(pos['x'] + offsetX, pos['y'] + offsetY, offsetZ);
}
degree++;
if (degree > menus.length * space) {
stop();
}
}

function stop() {
cancelAnimationFrame(loopId);
console.log("stop");
}

function move (radius, index) {
// speed = speed || 1.0;
const rad = (degree * Math.PI / 180) * 2;
const x = radius * Math.sin(rad);
const y = radius * Math.cos(rad);

return {'x':x, 'y':y};
}

}