使用 three.js 来做球的 3d 特效

ui 在设计图中给了一张小球, 要求球做成旋转的效果

我一看这个不是有点 3 d 的效果吗. 并且这球之间的关系一点都不好构建啊. 于是我在脑内构建了非常炫酷的效果. 但是苦于没有思路

后来在群里问群友, 群友给了一个思路, 于是我在网上找到了一篇关于腾讯前端设计高的粒子特效. 文章放在这里 (https://tgideas.qq.com/webplat/info/news_version3/804/7104/7106/m5723/201704/577405.shtml)

从这篇文章来看, 是先设计出 3d 模型, 然后把 3d 模型利用 three.js 的 loader 加载进来解析. 其中主要的就是模型顶点的数据

于是恰巧有个同事会 3d 建模, 于是拜托他建了一个 3d模型,

虽然和原图相差太大, 但是马马虎虎还可以用. 但是这个模型还有点解析不正常, 后来让我让他改了很多遍,  简直想死啊,  模型到手后就开始做解析

loader.load(‘./model/xiaoqiu2.obj‘, function (geo) {
        geo.traverse(function (child) {
            if (child.isMesh) {
                THREE.GeometryUtils.merge(ball, new THREE.Geometry().fromBufferGeometry(child.geometry));
            }
        })
        ball.normalize()
        ball.scale(100, 100, 100);
        var starField = new THREE.Points(ball, starsMaterial);
        scene.add(starField);
    })

这里. obj 格式的模型直接加载进来是 一个group. 这个 group 里面有许多的 mesh,  这样所有的顶点数据就不好找, 如果想做粒子切换效果, 需要把 mesh 合并为一个. 这里我使用GeometryUtils来做合并. 合并之后的可以直接在vertices里面拿到模型所有的顶点数据. 然后做一个旋转动画

var animate = function () {
        ball.rotateX(0.01)
        ball.rotateY(0.01)
        ball.rotateZ(0.01)
        renderer.render(scene, camera);
        globalID = requestAnimationFrame(animate);
    };

效果如下

其实我原本也想加个球到文字的切换效果, 但是后来发现太卡, 于是去掉了. 这里把参考代码放上

切换使用的是 Tween.js

for (var i = 0; i < sourceLength; i++) {
            var o = target.vertices[i % length];
            new TWEEN.Tween(source.vertices[i]).to({
                x: o.x,
                y: o.y,
                z: o.z
            }, 0).easing(TWEEN.Easing.Exponential.In).delay(5000 * Math.random()).start()
        }

关于文字是先用 canvas 画出想要的文字, 然后把顶点数据导出来

function getTextData(text) {
        // 创建canvas
        const textCanvas = document.createElement(‘canvas‘);
        const textCtx = textCanvas.getContext(‘2d‘);

        function map(n, a, b, c, d) {
            return (n - a) * (d - c) / (b - a) + c;
        }

        function generatePointsFromImgData(imgData) {
            let points = [];
            let {data, width: w, height: h} = imgData;
            let multX = 1;
            let multY = 1;
            let aspect = w / h;
            if (aspect > 1) {
                multX = aspect;
            } else if (aspect < 1) {
                multY = h / w;
            }
            let offsetX = multX * 0.5;
            let offsetY = multY * 0.5;
            for (let i = 3; i < data.length; i += 4) {
                if (data[i] <= 0x20) {
                    continue;
                }
                let j = i * 0.25;
                let x = j % w;
                let y = Math.floor(j / w);
                let tX = x / w;
                let tY = y / h;
                let vX = tX * multX - offsetX;
                let vY = tY * multY - offsetY;
                // let vZ = (Math.random() * 2 - 1) * 0.1 - 0.05;
                let vZ = Math.sin((Math.sin(tX * 4) * 3 + Math.cos(tY * 2) * 2) * 8) * 0.2;
                let p = new THREE.Vector3(vX, -vY, vZ).multiplyScalar(0.7);
                points.push(p);
            }
            return points;
        }

        function generatePointsFromWord(text = ‘Jquery‘) {
            textCtx.resetTransform();
            textCtx.clearRect(0, 0, textCanvas.width, textCanvas.height);
            textCtx.fillStyle = ‘white‘;
            let h = map(text.length, 1, 25, 48, 12);
            textCtx.font = `normal ${h}px Arial`;
            textCtx.textBaseline = ‘middle‘;
            textCtx.textAlign = ‘center‘;
            let w = Math.floor(textCtx.measureText(text).width);
            textCtx.fillText(text, w * 0.5, h * 0.5);
            let imgData = textCtx.getImageData(0, 0, w, h);
            textCtx.clearRect(0, 0, textCanvas.width, textCanvas.height);
            return generatePointsFromImgData(imgData);
        }

        return generatePointsFromWord(text);

    }

这样就可以在两个模型之间做切换了

原文地址:https://www.cnblogs.com/cgdx/p/10836883.html

时间: 2024-10-05 12:20:32

使用 three.js 来做球的 3d 特效的相关文章

js和CSS3炫酷3D相册展示

<!doctype html> <html> <head> <meta charset="UTF"> <title>js和CSS3炫酷3D相册展示</title> <style> *{margin:0;padding:0;} body{background:url(img/bg.jpg);width:100%;height:100%;overflow:hidden;}; h1{width:277;hei

商城倒计时JS怎么做

商城倒计时JS怎么做 <style type="text/css"> div { text-align: center; color:#333; font-size: 36px; } </style> </head> <body> <div>距离2019年春节还有:<span>0</span>天<span>0</span>时<span>0</span>分&

腾讯QQ空间穿越时光轴3D特效

<DOCTYPE html> <html> <head> <title>腾讯QQ空间穿越光轴3D特效</title> <style> *{margin:0;padding:0;} body{ background-image:url("images/bg.png") fixed;//拖动鼠标图片不会上下移动 height:2000px; } .con{ width:1000px; /*heigth:500px;*/

二.ubuntu14.04 3D特效设置

一.如果按照第一篇都设置好了(显卡驱动等都已经正常),然后 1.安装CCSM设置管理器 用鼠标点击屏幕左侧Unity程序启动栏中的“Ubuntu软件中心”(有“A”字形的公文包图标), 在弹出的“Ubuntu 软件中心”窗口右上角的搜索栏中,输入“compiz”, 可以看到,默认的“Compiz”这个软件已经安装在系统上了,3D桌面就是由这个软件来运行才能实现的. 现在需要做的只是安装用户配置和调节各种特效的软件,点击选中“CompziConfig设置管理器”(简称CCSM), 点击右边的“安装

2D特效和3D特效

2D居中效果 div{ width: height: backgroundcolor: position:absolute; left:50%; top:50%; transform:translate(-50%,-50%) }    将DIV绝对定位后,使用transform(使改变,使移动)将其移动. 2D旋转效果 div:hover{ transform:rotate(45deg) } 当鼠标放到DIV上,这个DIV旋转45度角. 中心在左上角加一句代码在div中: Transform-o

Cocos2d-x学习笔记(十二)3D特效

特效类即是GridAction类,其实就是基于网格的3D动作类.需开启OpenGL的深度缓冲,否则容易3D失真. 下边是一个snippet,创建网格对象,并将其添加到当前layer:同时,将进行3D特效的对象,添加到网格对象上. gridNodeTarget = NodeGrid::create(); addChild(gridNodeTarget);// add to current layer auto bg = Sprite::create("background.png");

分享JQuery动画插件Velocity.js的六种列表加载特效

分享JQuery动画插件Velocity.js的六种列表加载特效.在这款实例中给中六种不同的列表加载效果.分别为从上飞入.从右侧飞入.从左侧飞入.和渐显.一起看下效果图: 在线预览   源码下载 实现的代码. html代码: <h1> Velocity.js <i>slice + sequence</i></h1> <pre>Only anim X number with FX#1, animate Y number with FX#2 etc

JS实现转动随机数抽奖的特效代码

JS实现转动随机数抽奖的特效代码 大家都玩过抽奖游戏,或者梦想抽到大奖吧.可是有没有想过抽奖游戏是怎么实现的呐?今天就给大家分享一款转动随机数抽奖的JS特效代码. 实现代码例如以下 <!Doctype html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=GBK"> <script src="htt

JS框架_(JQbar.js)柱状图动态百分比进度条特效

柱状图动态百分比进度条效果 <html> <head> <title>jqbar.js柱状图动态百分比进度条特效</title> <link href="css/demo.css" rel="stylesheet" type="text/css" /> <link rel="stylesheet" href="css/jqbar.css" /