理解国外大佬用Web做出来跨窗口渲染动画效果

今天刷抖音看见国外一个大佬用Web做出来一个可以跨多浏览器窗口实时互动的渲染动画效果,觉得非常新奇,我就去看了一下源码,作者还写了一个非常好的例子帮助理解,我自己也仿写了作者的例子加深理解
**GitHub预览地址**麻烦帮忙点亮星星谢谢哈哈哈~
整体思路是监听visibilityState,通过localStorage进行存储每一个窗口的的立方体的位置,和窗口相对于电脑屏幕的位置

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)
	}

其中主要的是这个 setupWindowManager方法

import WindowManager from './WindowManager.js'
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);//初始化窗口

		
		windowsUpdated();
	}

初始化窗口的方法

init (metaData)
	{
		this.#windows = JSON.parse(localStorage.getItem("windows")) || [];
		this.#count= localStorage.getItem("count") || 0;
		this.#count++;

		this.#id = this.#count;
		let shape = this.getWinShape();
		this.#winData = {id: this.#id, shape: shape, metaData: metaData};
		this.#windows.push(this.#winData);

		localStorage.setItem("count", this.#count);
		this.updateWindowsLocalStorage();
	}

WindowManager 这个类中constructor方法中就会监听storage获取到窗口中存储的立方体的位置信息


constructor() {
		let that = this;

		// event listener for when localStorage is changed from another window
		addEventListener("storage", (event) => {
			if (event.key == "windows") {
				let newWindows = JSON.parse(event.newValue);
				let winChange = that.#didWindowsChange(that.#windows, newWindows);

				that.#windows = newWindows;

				if (winChange) {
					if (that.#winChangeCallback) that.#winChangeCallback();
				}
			}
		});

		// event listener for when current window is about to ble closed
		window.addEventListener('beforeunload', function (e) {
			let index = that.getWindowIndexFromId(that.#id);

			//remove this window from the list and update local storage
			that.#windows.splice(index, 1);
			that.updateWindowsLocalStorage();
		});
	}
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 = .5;
		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.x = cube.position.x 
			cube.position.y = cube.position.y + (posTarget.y - cube.position.y) * falloff;
			// cube.position.y = cube.position.y 
			cube.rotation.x = _t * .5;
			cube.rotation.y = _t * .5;
		};

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

具体效果图
理解国外大佬用Web做出来跨窗口渲染动画效果_第1张图片

你可能感兴趣的:(threejs,前端)