前端量子纠缠 效果炸裂 multipleWindow3dScene

简介: 这篇文章介绍了一个前端三维窗口管理器项目,该项目通过Three.js库创建了一种量子纠缠效果的3D视窗场景,并提供了项目的GitHub地址、运行方法和部分关键源码。

视频效果

量子纠缠

源码地址

改项目目前已达到 9.9k stars
项目地址:https://github.com/bgstaal/multipleWindow3dScene

在这里插入图片描述

运行

1、Vscode安装 Live Server这个插件

在这里插入图片描述

2、点击Go live 就可以看到运行效果了
在这里插入图片描述
在这里插入图片描述

部分源码

import WindowManager from './WindowManager.js'

const t = THREE;
let camera, scene, renderer, world;
let near, far;
let pixR = window.devicePixelRatio ? window.devicePixelRatio : 1;
let cubes = [];
let sceneOffsetTarget = {x: 0, y: 0};
let sceneOffset = {x: 0, y: 0};

let today = new Date();
today.setHours(0);
today.setMinutes(0);
today.setSeconds(0);
today.setMilliseconds(0);
today = today.getTime();

let internalTime = getTime();
let windowManager;
let initialized = false;

// get time in seconds since beginning of the day (so that all windows use the same time)
function getTime ()
{
    return (new Date().getTime() - today) / 1000.0;
}

if (new URLSearchParams(window.location.search).get("clear"))
{
    localStorage.clear();
}
else
{    
    // this code is essential to circumvent that some browsers preload the content of some pages before you actually hit the url
    document.addEventListener("visibilitychange", () => 
    {
        if (document.visibilityState != 'hidden' && !initialized)
        {
            init();
        }
    });

    window.onload = () => {
        if (document.visibilityState != 'hidden')
        {
            init();
        }
    };

    function init ()
    {
        initialized = true;

        // add a short timeout because window.offsetX reports wrong values before a short period 
        setTimeout(() => {
            setupScene();
            setupWindowManager();
            resize();
            updateWindowShape(false);
            render();
            window.addEventListener('resize', resize);
        }, 500)    
    }

    function setupScene ()
    {
        camera = new t.OrthographicCamera(0, 0, window.innerWidth, window.innerHeight, -10000, 10000);

        camera.position.z = 2.5;
        near = camera.position.z - .5;
        far = camera.position.z + 0.5;

        scene = new t.Scene();
        scene.background = new t.Color(0.0);
        scene.add( camera );

        renderer = new t.WebGLRenderer({antialias: true, depthBuffer: true});
        renderer.setPixelRatio(pixR);

          world = new t.Object3D();
        scene.add(world);

        renderer.domElement.setAttribute("id", "scene");
        document.body.appendChild( renderer.domElement );
    }

    function setupWindowManager ()
    {
        windowManager = new WindowManager();
        windowManager.setWinShapeChangeCallback(updateWindowShape);
        windowManager.setWinChangeCallback(windowsUpdated);

        // here you can add your custom metadata to each windows instance
        let metaData = {foo: "bar"};

        // this will init the windowmanager and add this window to the centralised pool of windows
        windowManager.init(metaData);

        // call update windows initially (it will later be called by the win change callback)
        windowsUpdated();
    }

    function windowsUpdated ()
    {
        updateNumberOfCubes();
    }

    function updateNumberOfCubes ()
    {
        let wins = windowManager.getWindows();

        // remove all cubes
        cubes.forEach((c) => {
            world.remove(c);
        })

        cubes = [];

        // add new cubes based on the current window setup
        for (let i = 0; i < wins.length; i++)
        {
            let win = wins[i];

            let c = new t.Color();
            c.setHSL(i * .1, 1.0, .5);

            let s = 100 + i * 50;
            let cube = new t.Mesh(new t.BoxGeometry(s, s, s), new t.MeshBasicMaterial({color: c , wireframe: true}));
            cube.position.x = win.shape.x + (win.shape.w * .5);
            cube.position.y = win.shape.y + (win.shape.h * .5);

            world.add(cube);
            cubes.push(cube);
        }
    }

    function updateWindowShape (easing = true)
    {
        // storing the actual offset in a proxy that we update against in the render function
        sceneOffsetTarget = {x: -window.screenX, y: -window.screenY};
        if (!easing) sceneOffset = sceneOffsetTarget;
    }

    function render ()
    {
        let t = getTime();

        windowManager.update();

        // calculate the new position based on the delta between current offset and new offset times a falloff value (to create the nice smoothing effect)
        let falloff = .05;
        sceneOffset.x = sceneOffset.x + ((sceneOffsetTarget.x - sceneOffset.x) * falloff);
        sceneOffset.y = sceneOffset.y + ((sceneOffsetTarget.y - sceneOffset.y) * falloff);

        // set the world position to the offset
        world.position.x = sceneOffset.x;
        world.position.y = sceneOffset.y;

        let wins = windowManager.getWindows();

        // loop through all our cubes and update their positions based on current window positions
        for (let i = 0; i < cubes.length; i++)
        {
            let cube = cubes[i];
            let win = wins[i];
            let _t = t;// + i * .2;

            let posTarget = {x: win.shape.x + (win.shape.w * .5), y: win.shape.y + (win.shape.h * .5)}

            cube.position.x = cube.position.x + (posTarget.x - cube.position.x) * falloff;
            cube.position.y = cube.position.y + (posTarget.y - cube.position.y) * falloff;
            cube.rotation.x = _t * .5;
            cube.rotation.y = _t * .3;
        };

        renderer.render(scene, camera);
        requestAnimationFrame(render);
    }

    // resize the renderer to fit the window size
    function resize ()
    {
        let width = window.innerWidth;
        let height = window.innerHeight

        camera = new t.OrthographicCamera(0, width, 0, height, -10000, 10000);
        camera.updateProjectionMatrix();
        renderer.setSize( width, height );
    }
}
相关文章
|
3月前
|
量子技术
量子模拟:探索宇宙基本规律的强大工具
【9月更文挑战第19天】量子模拟利用量子计算机或系统来模拟复杂量子现象,突破传统计算限制,有效探索宇宙基本规律。它能高效模拟宇宙演化、研究暗物质及暗能量特性,并验证量子宇宙学理论。随着量子技术进步,其未来应用将更加广泛,助力揭示更多宇宙奥秘。
|
4月前
【光波电子学】MATLAB绘制平面介质中的波场-以TE波为例
本文介绍了使用MATLAB绘制平面介质中TE波的波场分布方法,详细阐述了波导层、衬底层和覆盖层的波动方程及边界条件。
69 7
|
5月前
|
自然语言处理 算法 图形学
几分钟生成四维内容,还能控制运动效果:北大、密歇根提出DG4D
【7月更文挑战第25天】北京大学与密歇根大学合作提出DreamGaussian4D (DG4D),解决四维内容生成中的挑战,如长时间优化、运动控制及细节质量。DG4D结合几何变换与Gaussian Splatting,大幅减少优化时间至几分钟,并增强了运动的可控性与细节质量。此框架包括Image-to-4D GS模块和Video-to-Video Texture Refinement模块,分别负责高质量四维内容生成和纹理精细化。[论文](https://arxiv.org/abs/2312.17142)
54 1
|
7月前
|
人工智能 计算机视觉
CVPR 2024:跳舞时飞扬的裙摆,AI也能高度还原了,南洋理工提出动态人体渲染新范式
【5月更文挑战第6天】南洋理工大学研究团队在CVPR 2024会议上提出SurMo,一种动态人体渲染新方法,能高度还原视频中的人物动作和细节,如飞扬的裙摆。SurMo通过4D运动建模,结合表面运动编码、物理运动解码和4D外观解码,实现动态图像的精确合成。尽管面临复杂动作捕捉和计算资源需求的挑战,SurMo在动态人体渲染任务上表现出色,展现了表面基运动三角平面的强大表达能力。[论文链接](https://arxiv.org/pdf/2404.01225.pdf)
162 1
|
量子技术
叠加态和超级定位:量子世界的奇特现象
在量子力学中,叠加态是一种非常特殊的态。当一个量子系统可以处于多个可能的状态时,它可以被描述为这些状态的线性叠加。这意味着系统处于叠加态时,它同时处于多个状态的叠加之中。叠加态可以用波函数的线性组合来表示
185 0
叠加态和超级定位:量子世界的奇特现象
物理学家使人类尺度的物体接近静止状态,达到量子状态
物理学家使人类尺度的物体接近静止状态,达到量子状态
|
编解码 量子技术
量子并不总意味着小尺度,量子物理学家用它探索系外行星生命
量子并不总意味着小尺度,量子物理学家用它探索系外行星生命
108 0
Google Earth Engine——美国PRISM插值程序模拟了天气和气候如何随海拔变化,并考虑了海岸效应、温度反转和可能导致雨影的地形障碍。
Google Earth Engine——美国PRISM插值程序模拟了天气和气候如何随海拔变化,并考虑了海岸效应、温度反转和可能导致雨影的地形障碍。
178 0
Google Earth Engine——美国PRISM插值程序模拟了天气和气候如何随海拔变化,并考虑了海岸效应、温度反转和可能导致雨影的地形障碍。
|
存储 传感器 编解码
模拟变色龙,软体机器人也能实时根据背景变色!依赖温度实现,研究登上Nature子刊
模拟变色龙,软体机器人也能实时根据背景变色!依赖温度实现,研究登上Nature子刊
183 0
|
机器学习/深度学习 PyTorch 算法框架/工具
北大图灵班本科生带来动画CG福音,「最懂骨骼的卷积网络」,无需配对样本实现动作迁移 | SIGGRAPH
云栖号资讯:【点击查看更多行业资讯】在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来! 我有一个动画形象,我有一套人体动作,可想要把它们组合成真正的动画,可不是 1+1 这么简单。 别看这体型迥异的三位动作整齐划一,支撑动画的骨架却差异甚大。
北大图灵班本科生带来动画CG福音,「最懂骨骼的卷积网络」,无需配对样本实现动作迁移 | SIGGRAPH