利用JavaScript实现3D可旋转粒子矩阵效果

目录
  • 演示
  • 技术栈
    • dat.gui.min.js
  • 源码
    • js部分

演示

技术栈

本次使用了dat.gui.min.js这个新库(就是在我文章里没有出现过的那么他们的功能有哪些呢?——可以百度搜搜)不想搜的话就听我简单絮叨两句吧。

dat.gui.min.js

就是能调节数据的功能框

使用起来也很简单例如建立一个对象

        gui = {
            lightY:30, //灯光y轴的位置
            sphereX:0, //球的x轴的位置
            sphereZ:0, //球的z轴的位置
            cubeX:25, //立方体的x轴位置
            cubeZ:-5 //立方体的z轴的位置
        };
var datGui = new dat.GUI();
        //将设置属性添加到gui当中,gui.add(对象,属性,最小值,最大值)
        datGui.add(gui,"lightY",0,100);
        datGui.add(gui,"sphereX",-30,30);
        datGui.add(gui,"sphereZ",-30,30);
        datGui.add(gui,"cubeX",0,60);
        datGui.add(gui,"cubeZ",-30,30);

源码

js部分

/**
  Scroll to zoom, or use options

  Read description for notes on possible
  issues.
*/

window.addEventListener('load', function() {
  var canvas = document.getElementById("animation"),
      context = canvas.getContext("2d"),
      width, height, resize,
      gui = new dat.GUI(),
      stats = new Stats(),
      generatePoints,
      settings = {
        viewDistance: 100,
        offsetFromCenter: 100,
        margin: 20
      },
      points = [], limit = settings.offsetFromCenter, step = settings.margin, cp = {x:0,y:0,z:0};

  function generateParticles() {
    points = [];
    limit = settings.offsetFromCenter;
    step = settings.margin;
    cp = {x:0,y:0,z:0};
    for(var y = -limit; y < limit; y += step) {
      for(var x = -limit; x < limit; x += step) {
        for(var z = -limit; z < limit; z += step) {
          var v  = {x:x,y:y,z:z},
              dx = (v.x - cp.x),
              dy = (v.y - cp.y),
              dz = (v.z - cp.z),
              d  = Math.sqrt(dx * dx + dy * dy + dz * dz),
              zf = ~~(255 * (1 - (d / 150)));

          if(zf < 0) zf = 0;

          // generate a color based on the particle's position
          v.c = {r: 255-zf, g: zf, b: zf, a: 240};
          v.c.l = (v.c.r | (v.c.g << 8) | (v.c.b << 16) | (v.c.a << 24));

          points.push(v);
        }
      }
    }
  }

  var f1 = gui.addFolder('View'),
      f2 = gui.addFolder('Particle placement');

  f1.add(settings, 'viewDistance', -200, 600).step(10).name("Distance").listen().onChange(function() {
    if(settings.viewDistance === 0) settings.viewDistance = -1;
  });

  f2.add(settings, 'offsetFromCenter', 100, 400).step(10).name("Offset from origin").onChange(generateParticles);
  f2.add(settings, 'margin', 5, 40).step(5).name("Margin between").onChange(generateParticles);
  f1.open();
  f2.open();

  gui.close();

  stats.setMode(0); // FPS mode

  // Place the statistics at the bottom right.
  stats.domElement.style.position = 'absolute';
  stats.domElement.style.right = '5px';
  stats.domElement.style.bottom = '5px';
  document.body.appendChild(stats.domElement);

  resize = function() {
    // resize the canvas
    canvas.width  = width  = window.innerWidth;
    canvas.height = height = window.innerHeight;
  }; resize();

  window.addEventListener('resize', resize);

  window.addEventListener('mousewheel', function(event) {
    if(event.wheelDeltaY < 0 || event.deltaY > 0) {
      settings.viewDistance += 10;
    } else {
      settings.viewDistance -= 10;
    }

    if(settings.viewDistance == 0)   settings.viewDistance = -1;
    if(settings.viewDistance < -200) settings.viewDistance = -200;
    if(settings.viewDistance > 600)  settings.viewDistance = 600;

    return event.preventDefault();
  });

  // generate cube
  for(var y = -limit; y < limit; y += step) {
    for(var x = -limit; x < limit; x += step) {
      for(var z = -limit; z < limit; z += step) {
        var v  = {x:x,y:y,z:z},
            dx = (v.x - cp.x), dy = (v.y - cp.y), dz = (v.z - cp.z),
            d  = Math.sqrt(dx * dx + dy * dy + dz * dz),
            zf = ~~(255 * (1 - (d / 150)));

        if(zf < 0) zf = 0;

        // generate a color based on the particle's position
        v.c = {r: 255-zf, g: zf, b: zf, a: 240};
        v.c.l = (v.c.r | (v.c.g << 8) | (v.c.b << 16) | (v.c.a << 24));

        points.push(v);
      }
    }
  }

  var fsin = Math.sin, fcos = Math.cos,
      rotateY = 0.005, rotateX = 0.003, rotateZ = -0.001, // rotate
      cosy = fcos(rotateY), siny = fsin(rotateY),
      cosx = fcos(rotateX), sinx = fsin(rotateX),
      cosz = fcos(rotateZ), sinz = fsin(rotateZ);

  var i, c, d, dd, d32, cx, cy, cos, sin, x, y, scale, cpx, cpy, cps,
      px, py, sy, sx, lx, ly, sl;

  +(function render() {
    stats.begin();

    context.fillStyle = 'rgba(0, 0, 0, 0.6)';
    context.fillRect(0, 0, width, height);

    d = context.getImageData(0, 0, width, height);
    dd = d.data;
    d32 = new Uint32Array(dd.buffer); // create a 32-bit view for faster access
    cx = width / 2;
    cy = height / 2;

    // further behind should be rendered first.
    points.sort(function(a, b) {
      return ((300 / ((a.z + settings.viewDistance) || 1)) - (300 / ((b.z + settings.viewDistance) || 1)));
    })

    for(i = 0; i < points.length; i += 1) {
      c = points[i];

      // calculate the cos and sin beforehand!
      x = c.x, z = c.z, c.x = (x * cosy + z * siny), c.z = (x * -siny + z * cosy); // rotate y
      z = c.z, y = c.y, c.y = (y * cosx + z * sinx), c.z = (y * -sinx + z * cosx); // rotate x
      x = c.x, y = c.y, c.y = (y * cosz + x * sinz), c.x = (y * -sinz + x * cosz); // rotate z
      scale = (300 / ((c.z + settings.viewDistance) || 1)), cpx = ~~(cx + c.x * scale), cpy = ~~(cy + c.y * scale), cps = scale;
      sl = (2 * cps);
      sy = cpy, sx = cpx, ly = ~~(sy + sl), lx = ~~(sx + sl);

      if(sl > 0 && sl < 1000 && cpx >= -sl && cpy >= -sl && cpx < width && cpy < height) {
        if(ly !== 0 && lx !== 0) {
          for(py = sy; py < ly; py += 1) {
            for(px = sx; px < lx; px += 1) {
              if(px >= 0 && py >= 0 && px < width && py < height) {
                d32[(py * width + px)] = c.c.l;
              }
            }
          }
        }
      }
    }

    context.putImageData(d, 0, 0);
    stats.end();

    // for some reason, if I don't do this, GC doesn't come along and clean my stuff up...
    // thus: memory leak, at 2.5g Chrome tells my tab to commit suicide.
    // Google search: Google Chrome putImageData memory leak
    // many results.
    d = dd = d32 = null;
    return setTimeout(function(){requestAnimFrame(render);},1);
  }());
});

到此这篇关于利用JavaScript实现3D可旋转粒子矩阵效果的文章就介绍到这了,更多相关JavaScript 3D旋转粒子矩阵内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • js实现3D旋转效果

    本文实例为大家分享了js实现3D旋转效果的具体代码,供大家参考,具体内容如下 实现效果: 实现过程: 步骤一:先写一个简单的html结构,创建一个box盒子,里面放对应的图片(也可以用js创建图片,这里为了好理解,我们直接用html创建). <body><div class="box"> <img src="./img/1.jpg" alt=""> <img src="./img/2.jpg&q

  • 基于Three.js制作一个3D中国地图

    目录 1.使用geoJson绘制3d地图 1.1 创建场景相关 1.2 根据json绘制地图 2.增加光照 3.增加阴影模糊 4.增加鼠标事件 5.渲染 6.动画效果 不想看繁琐步骤的,可以直接去github下载项目,如果可以顺便来个star哈哈 本项目使用vue-cli创建,但不影响使用,主要绘制都已封装成类 1.使用geoJson绘制3d地图 1.1 创建场景相关 // 创建webGL渲染器 this.renderer = new THREE.WebGLRenderer( { antiali

  • 基于JS实现简单的3D立方体自动旋转

    目录 演示 技术栈 源码 css js 雪花部分 演示 技术栈 display:inline-block,block,inline元素的区别: display:block将元素显示为块级元素,从而可以更好地操控元素的宽高,以及内外边距,每一个块级元素都是从新的一行开始. display : inline将元素显示为行内元素,高度,行高以及底边距不可改变,高度就是内容文字或者图片的宽度,不可以改变.多个相邻的行内元素排在同一行里,知道页面一行排列不下,才会换新的一行. display:inline

  • Three.js实现脸书元宇宙3D动态Logo效果

    目录 背景 什么是元宇宙 实现效果 试炼一:THREE.TorusGeometry 试炼二:THREE.TorusKnotGeometry 试炼三:THREE.TubeGeometry 试炼四:Blender + Three.js 用Blender建模 加载Logo模型 添加材质 展示加载进度 点击更换材质 加载人物模型 总结 参考资料 本文主要讲述通过 Three.js + Blender 技术栈,实现 Meta 公司炫酷的 3D 动态 Logo,内容包括基础模型圆环.环面扭结.管道及模型生成

  • js实现3D粒子酷炫动态旋转特效

    js实现3D粒子酷炫动态旋转特效(效果比较酷炫,中途不仅有形态的变换,还有颜色的变化,希望大家能够喜欢) 代码实现过程中的静态截图 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <TITLE> New Document </TITLE> <META NAME="Generator" CONTEN

  • 利用Three.js实现3D三棱锥立体特效

    目录 演示 技术栈 源码 css部分 js部分 演示 技术栈 3D特效的话最容易让人想到的应该是three.js吧.我们今天来说说它. Three.js是基于原生WebGL封装运行的三维引擎,在所有WebGL引擎中,Three.js是国内文资料最多.使用最广泛的三维引擎. Threejs是一款WebGL三维引擎,它可以用来做什么许多许多地场景应用 一个小案例 <!DOCTYPE html> <html lang="en"> <head> <me

  • 利用JavaScript实现3D可旋转粒子矩阵效果

    目录 演示 技术栈 dat.gui.min.js 源码 js部分 演示 技术栈 本次使用了dat.gui.min.js这个新库(就是在我文章里没有出现过的那么他们的功能有哪些呢?——可以百度搜搜)不想搜的话就听我简单絮叨两句吧. dat.gui.min.js 就是能调节数据的功能框 使用起来也很简单例如建立一个对象 gui = { lightY:30, //灯光y轴的位置 sphereX:0, //球的x轴的位置 sphereZ:0, //球的z轴的位置 cubeX:25, //立方体的x轴位置

  • JavaScript实现鼠标移动粒子跟随效果

    本文实例为大家分享了JavaScript实现鼠标移动粒子跟随效果的具体代码,供大家参考,具体内容如下 ※ 如上图是最终显示效果,跟随鼠标的移动,生成的粒子跟随. 需要用到的js库:Underscore.Underscore是一个JavaScript实用库,提供了一整套函数式编程的实用功能,但是没有扩展任何JavaScript内置对象.它是这个问题的答案:"如果我在一个空白的HTML页面前坐下,并希望立即开始工作,我需要什么?"...它弥补了部分jQuery没有实现的功能,同时又是Bac

  • JS实现六边形3D拖拽翻转效果的方法

    效果图 实例代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv=&q

  • 使用3D引擎threeJS实现星空粒子移动效果

    three.js是JavaScript编写的WebGL第三方库.提供了非常多的3D显示功能.Three.js 是一款运行在浏览器中的 3D 引擎,你可以用它创建各种三维场景,包括了摄影机.光影.材质等各种对象. 下载地址: http://threejs.org/ 首先创建一个HTML文件,引入three.js引擎包. <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <titl

  • 利用JavaScript制作一个酷炫的3D图片演示

    目录 前言 一.页面特效效果展示 二.功能描述 三.功能实现 前言 对于学前端的小伙伴来说,吸引你们入坑的大都是一些炫酷的页面.但往往那些页面的源代码对初学的伙伴们都不太友好.今天给大家分享一个代码简单.适合初学者.高级感炫酷感爆棚的特效页面(有npy的快乐加倍!). 一.页面特效效果展示 注:上述效果图只是部分效果,原谅我还没有学会自制gif图! 二.功能描述 1.打开页面,所有图片会自动转动 2.图片的大小和间隔可随鼠标滚轮滚动而改变 3.鼠标按住页面任意位置,拖动光标,页面可随之旋转 三.

  • 利用JavaScript在网页实现八数码启发式A*算法动画效果

    最近人工智能课老师布置了一个八数码实验,网上看到很多八数码的启发式A*算法,但是大多数都是利用C或者C++在控制台实现的,于是我用js在网页中做了一个类似的. 首先八数码就是一个九宫格,其中有一个空格,其他八个对应数字1-8, 移动空格,使得最后状态为有序,如下图 启发式算法是指在求解时,利用启发函数将不符合规则的解节点去掉,从而缩小问题的解空间. A*算法是利用评价函数的启发式算法,在本例中,利用当前节点状态与最终节点状态所不同的格子数来评估节点的优劣,将优越节点储存并在之后展开,将劣质节点抛

  • WPF实现3D粒子波浪效果

    本文实例为大家分享了WPF实现3D粒子波浪效果的具体代码,供大家参考,具体内容如下 实现效果如下: 步骤: 1.3D粒子类Particle.cs public class Particle { public Point3D Position;//位置 public double Size;//尺寸 public int XIndex;//X位置标识 public int YIndex;//Y位置标识 } 2.粒子系统ParticleSystem类 public class ParticleSys

  • 利用JavaScript实现春节倒计时效果(移动端和PC端)

    目录 效果预览 html部分 移动端样式(mobile.css) pc端样式(style.css) js部分 效果演示 移动端 pc端 效果预览 html部分 <!DOCTYPE html> <!--geyao--> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale

  • 利用JavaScript实现仿京东放大镜效果

    功能实现 1.鼠标经过小图片盒子,黄色的遮挡层和大图片显示,离开时就隐藏2个盒子功能 2.黄色遮挡层跟着鼠标走 把鼠标的坐标给盒子,不断地进行赋值操作 把鼠标地坐标给遮挡层不合适,因为遮挡层坐标以父盒子为准 首先是获得鼠标在盒子内地坐标 然后把数值给遮挡层地left和top值 此时用到鼠标移动事件,但是还是在小图片盒子内移动 发现,遮挡层位置不对,需要再减去盒子自身高度和宽度地一半 遮挡层不能超出小图片盒子范围 如果小于0,就把坐标设置为0 如果大于遮挡层最大地移动距离,就把坐标设置为最大地移动

  • 利用JavaScript模拟京东快递单号查询效果

    1.上面放大框开始是隐藏的,当输入单号后,就显示,并且里面的内容是输入框的内容的字体的放大 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="vi

随机推荐