JavaScript实现飞舞的泡泡效果

 更新时间:2020年02月07日 08:09:16   作者:盈嘉小红砖  
这篇文章主要为大家详细介绍了JavaScript实现飞舞的泡泡效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了JavaScript实现飞舞泡泡效果的具体代码,供大家参考,具体内容如下

示例

CSS

html,
body {
 margin: 0;
 padding: 0;
 width: 100%;
 height: 100%;
}

canvas {
 position: fixed;
 width: 100%;
 height: 100%;
}

JS

const nbObjects = 800;
var conf, scene, camera, cameraCtrl, light, renderer;
var whw, whh;

var objects;
var spriteMap, spriteMaterial;

var mouse = new THREE.Vector2();
var mouseOver = false;
var mousePlane = new THREE.Plane(new THREE.Vector3(0, 0, 1), 0);
var mousePosition = new THREE.Vector3();
var raycaster = new THREE.Raycaster();

function init() {
 conf = {
 opacity: 0.8
 };

 scene = new THREE.Scene();
 camera = new THREE.PerspectiveCamera(100, window.innerWidth / window.innerHeight, 0.1, 1000);
 cameraCtrl = new THREE.OrbitControls(camera);
 cameraCtrl.autoRotate = true;
 cameraCtrl.autoRotateSpeed = 5;

 renderer = new THREE.WebGLRenderer();
 renderer.setSize(window.innerWidth, window.innerHeight);
 document.body.appendChild(renderer.domElement);

 initScene();

 onWindowResize();
 window.addEventListener('resize', onWindowResize, false);

 animate();
};

function initScene() {
 scene = new THREE.Scene();
 scene.background = new THREE.Color(0xFFF8DC);

 camera.position.z = 30;
 camera.position.y = 20;
 camera.lookAt(0, 0, 0);

 spriteMap = new THREE.Texture();
 var bubble = new Image();
 bubble.src = "data:image/png;base64,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";
 bubble.onload = function () {
 spriteMap.image = bubble;
 spriteMap.needsUpdate = true;
 };

 objects = [];
 for (var i = 0; i < nbObjects; i++) {
 var object = new Truc();
 objects.push(object);
 scene.add(object.sprite);
 }
}

function animate() {
 requestAnimationFrame(animate);

 cameraCtrl.update();

 renderer.render(scene, camera);
};

function Truc() {
 this.init();
 this.shuffle();
}

Truc.prototype.init = function () {
 this.material = new THREE.SpriteMaterial({
 color: randomColor({ luminosity: 'light' }),
 map: spriteMap,
 transparent: true,
 opacity: 1,
 depthTest: false,
 depthWrite: false,
 blending: THREE.AdditiveBlending
 });
 this.sprite = new THREE.Sprite(this.material);
};

Truc.prototype.shuffle = function () {
 this.scale1 = 0.1;
 this.scale2 = 2 + rnd(3);
 this.sprite.scale.set(this.scale1, this.scale1, 1);

 var rndv = getRandomVec3();
 this.sprite.position.set(rndv.x, rndv.y, rndv.z).multiplyScalar(50);
 this.sprite.position.y -= 25;

 this.material.opacity = conf.opacity;

 this.tt = this.scale2;
 TweenMax.to(this.sprite.scale, 1, { x: this.scale2, y: this.scale2, ease: Power2.easeIn });
 TweenMax.to(this.sprite.position, this.scale2, { y: this.sprite.position.y + 100, ease: Power2.easeIn });

 this.t1 = 1;
 TweenMax.to(this.sprite.position, this.t1, {
 x: this.sprite.position.x + rnd(10, true),
 z: this.sprite.position.z + rnd(10, true),
 ease:Linear.ease,
 repeat: Math.floor((this.tt/this.t1)/2),
 yoyo: true
 });

 TweenMax.to(this.material, 1, {
 opacity: 0,
 delay: this.tt-1,
 ease: Power2.easeIn,
 onCompleteParams: [this],
 onComplete: function (o) {
  o.shuffle();
 }
 });
};

function getRandomVec3() {
 const u = Math.random();
 const v = Math.random();
 const theta = u * 2.0 * Math.PI;
 const phi = Math.acos(2.0 * v - 1.0);
 const r = Math.cbrt(Math.random());
 const sinTheta = Math.sin(theta);
 const cosTheta = Math.cos(theta);
 const sinPhi = Math.sin(phi);
 const cosPhi = Math.cos(phi);
 const x = r * sinPhi * cosTheta;
 const y = r * sinPhi * sinTheta;
 const z = r * cosPhi;
 return { x: x, y: y, z: z };
}

function rnd(max, negative) {
 return negative ? Math.random() * 2 * max - max : Math.random() * max;
}

function onWindowResize() {
 whw = window.innerWidth / 2;
 whh = window.innerHeight / 2;
 camera.aspect = window.innerWidth / window.innerHeight;
 camera.updateProjectionMatrix();
 renderer.setSize(window.innerWidth, window.innerHeight);
}

init();

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • javascript闭包的理解和实例

    javascript闭包的理解和实例

    所谓闭包,值得是词法表示包括不必要计算的变量的函数,也就是说,该函数可以使用函数外定义的变量。
    2010-08-08
  • 分析JavaScript数组操作难点

    分析JavaScript数组操作难点

    本篇文章通过例举代码分析的方式给大家讲解了JavaScript数组操作难点以及需要注意的地方,一起学习参考下吧。
    2017-12-12
  • JS中通过slice()&substring()截取字符串前几位的方法

    JS中通过slice()&substring()截取字符串前几位的方法

    在Javascript使用字符串中,我们不一定需要全部的字符串,这时就需要截取字符串,本文主要介绍js中截取字符串前几位的两种方法:1、使用slice() 方法;2、使用substring() 方法,本文通过示例代码介绍的非常详细,需要的朋友参考下吧
    2023-12-12
  • javascript之嵌套函数使用方法

    javascript之嵌套函数使用方法

    在javascript中允许使用嵌套函数,下面是简单的例子。
    2010-03-03
  • 详解如何用webpack打包一个网站应用项目

    详解如何用webpack打包一个网站应用项目

    本篇文章主要介绍了如何用webpack打包一个网站应用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • javascript实现对表格元素进行排序操作

    javascript实现对表格元素进行排序操作

    这篇文章主要介绍了javascript实现对表格元素进行排序操作,分别可以实现点击之后排序和还原,和排升序和降序的功能,文章末尾附完整代码,感兴趣的小伙伴们可以参考一下
    2015-11-11
  • javascript内嵌式与外链式的基本应用方式

    javascript内嵌式与外链式的基本应用方式

    这篇文章主要介绍了javascript内嵌式与外链式的基本应用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • (转载)JavaScript中匿名函数,函数直接量和闭包

    (转载)JavaScript中匿名函数,函数直接量和闭包

    (转载)JavaScript中匿名函数,函数直接量和闭包...
    2007-05-05
  • js的新生代垃圾回收知识点总结

    js的新生代垃圾回收知识点总结

    在本篇文章里小编给大家整理的是关于js的新生代垃圾回收的相关知识点内容,有需要的朋友们可以参考学习下。
    2019-08-08
  • JavaScript中的DOM遍历详解

    JavaScript中的DOM遍历详解

    文档对象模型 (DOM) 表示 HTML 文档的结构,导航或“遍历”此结构是 Web 开发的基本方面,使开发人员能够在网页上选择、修改、删除或添加内容,本文深入研究了使用 JavaScript 进行 DOM 遍历的艺术,提供了一个强大的工具包来处理各种遍历场景
    2023-09-09

最新评论