最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

利用JavaScript實(shí)現(xiàn)3D可旋轉(zhuǎn)粒子矩陣效果

 更新時(shí)間:2022年06月28日 10:03:26   作者:肥學(xué)  
dat.gui.js是一個(gè)一個(gè)輕量級(jí)的圖形用戶界面庫(kù),或者說(shuō)GUI組件,只有幾十KB,可以用于創(chuàng)建操作控制三維場(chǎng)景的菜單欄等。本文將利用dat.gui.min.js實(shí)現(xiàn)3D可旋轉(zhuǎn)粒子矩陣效果,感興趣的可以了解一下

演示

技術(shù)棧

本次使用了dat.gui.min.js這個(gè)新庫(kù)(就是在我文章里沒(méi)有出現(xiàn)過(guò)的那么他們的功能有哪些呢?——可以百度搜搜)不想搜的話就聽(tīng)我簡(jiǎn)單絮叨兩句吧。

dat.gui.min.js

就是能調(diào)節(jié)數(shù)據(jù)的功能框

使用起來(lái)也很簡(jiǎn)單例如建立一個(gè)對(duì)象

        gui = {
            lightY:30, //燈光y軸的位置
            sphereX:0, //球的x軸的位置
            sphereZ:0, //球的z軸的位置
            cubeX:25, //立方體的x軸位置
            cubeZ:-5 //立方體的z軸的位置
        };
var datGui = new dat.GUI();
        //將設(shè)置屬性添加到gui當(dāng)中,gui.add(對(duì)象,屬性,最小值,最大值)
        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);
  }());
});

到此這篇關(guān)于利用JavaScript實(shí)現(xiàn)3D可旋轉(zhuǎn)粒子矩陣效果的文章就介紹到這了,更多相關(guān)JavaScript 3D旋轉(zhuǎn)粒子矩陣內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • ES6如何將?Set?轉(zhuǎn)化為數(shù)組示例詳解

    ES6如何將?Set?轉(zhuǎn)化為數(shù)組示例詳解

    這篇文章主要為大家介紹了ES6如何將?Set?轉(zhuǎn)化為數(shù)組的方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • 微信小程序使用vant組件庫(kù)的詳細(xì)步驟

    微信小程序使用vant組件庫(kù)的詳細(xì)步驟

    VantWeapp是有贊團(tuán)隊(duì)開(kāi)源的小程序UI組件庫(kù),可快速搭建小程序項(xiàng)目,小程序支持npm安裝第三方包,但需使用開(kāi)發(fā)者工具構(gòu)建,VantWeapp提供全局和局部注冊(cè)方式,支持自定義事件和插槽,可通過(guò)解除樣式隔離、使用外部樣式類和CSS變量修改組件樣式
    2024-09-09
  • Firefox下提示illegal character并出現(xiàn)亂碼的原因

    Firefox下提示illegal character并出現(xiàn)亂碼的原因

    Firefox下提示illegal character并出現(xiàn)亂碼的問(wèn)題,時(shí)間是是因?yàn)榫幋a的問(wèn)題導(dǎo)致。
    2010-03-03
  • JavaScript中new操作符使用詳解

    JavaScript中new操作符使用詳解

    new操作符是JavaScript中創(chuàng)建對(duì)象實(shí)例的重要方式,理解new操作符的工作原理對(duì)于掌握J(rèn)avaScript的面向?qū)ο缶幊讨陵P(guān)重要,本文將詳細(xì)介紹new操作符的原理及實(shí)現(xiàn),感興趣的小伙伴跟著小編一起來(lái)看看吧
    2024-11-11
  • 詳解JavaScript如何控制并發(fā)請(qǐng)求數(shù)量

    詳解JavaScript如何控制并發(fā)請(qǐng)求數(shù)量

    某些情況下,我們可能需要對(duì)需要執(zhí)行的多個(gè)異步任務(wù)進(jìn)行異步數(shù)量控制,只允許固定數(shù)量的任務(wù)執(zhí)行,本文為大家整理了JS控制并發(fā)請(qǐng)求數(shù)量的相關(guān)代碼,希望對(duì)大家有所幫助
    2024-01-01
  • JavaScript實(shí)現(xiàn)瀏覽器網(wǎng)頁(yè)自動(dòng)滾動(dòng)并點(diǎn)擊的示例代碼

    JavaScript實(shí)現(xiàn)瀏覽器網(wǎng)頁(yè)自動(dòng)滾動(dòng)并點(diǎn)擊的示例代碼

    這篇文章主要介紹了JavaScript實(shí)現(xiàn)瀏覽器網(wǎng)頁(yè)的自動(dòng)滾動(dòng)并點(diǎn)擊的示例代碼,幫助大家更好的理解和學(xué)習(xí)JavaScript的使用,感興趣的朋友可以了解下
    2020-12-12
  • 純?cè)鷍s實(shí)現(xiàn)table表格的增刪

    純?cè)鷍s實(shí)現(xiàn)table表格的增刪

    本文主要介紹了純?cè)鷍avascript實(shí)現(xiàn)table表格的增刪的方法,文章底部提供了完整的代碼。需要的朋友一起來(lái)看下吧
    2017-01-01
  • JS實(shí)現(xiàn)的簡(jiǎn)潔二級(jí)導(dǎo)航菜單雛形效果

    JS實(shí)現(xiàn)的簡(jiǎn)潔二級(jí)導(dǎo)航菜單雛形效果

    這篇文章主要介紹了JS實(shí)現(xiàn)的簡(jiǎn)潔二級(jí)導(dǎo)航菜單雛形效果,通過(guò)簡(jiǎn)單的JavaScript響應(yīng)鼠標(biāo)事件遍歷頁(yè)面元素實(shí)現(xiàn)二級(jí)導(dǎo)航菜單切換的效果,非常簡(jiǎn)單實(shí)用,需要的朋友可以參考下
    2015-10-10
  • 詳解用Webpack與Babel配置ES6開(kāi)發(fā)環(huán)境

    詳解用Webpack與Babel配置ES6開(kāi)發(fā)環(huán)境

    這篇文章主要介紹了詳解用Webpack與Babel配置ES6開(kāi)發(fā)環(huán)境,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • 在VS?Code中使用Snippet?Craft擴(kuò)展提高編碼效率的過(guò)程詳解

    在VS?Code中使用Snippet?Craft擴(kuò)展提高編碼效率的過(guò)程詳解

    這篇文章主要介紹了在VS?Code中使用Snippet?Craft擴(kuò)展提高編碼效率,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2024-08-08

最新評(píng)論

建平县| 闽侯县| 开平市| 梁平县| 永新县| 昌图县| 南通市| 泸定县| 青神县| 平泉县| 新昌县| 滁州市| 库车县| 台南县| 杂多县| 长白| 平武县| 竹溪县| 应城市| 泗阳县| 惠安县| 沂源县| 湖州市| 灵寿县| 柘荣县| 大冶市| 枣强县| 洞头县| 桐柏县| 巨鹿县| 新余市| 罗田县| 忻城县| 龙里县| 博湖县| 阿拉善左旗| 饶平县| 嘉峪关市| 汉源县| 屏东市| 长阳|