three实现三维能量场波动流动连线动画效果代码
代码语言:html
所属分类:三维
代码描述:three实现三维能量场波动流动连线动画效果代码
代码标签: three 三维 能量 场 波动 连线 动画 流动
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<style>
body, html{
margin: 0;
height: 100vh;
background: linear-gradient(-45deg, #333, #000);
overflow: hidden;
}
canvas{
display: none;
border: 3px solid #fff3;
position: absolute;
background: #04f1;
left: 50%;
top: 50%;
border-radius: 10px;
transform: translate(-50%, -50%);
}
canvas:focus{
outline: none;
}
</style>
</head>
<body translate="no">
<div id="container"></div>
<canvas id=c></canvas>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/three.160.js"></script>
<script type="module">
var camera
let scene, renderer
let isUserInteracting = false,
lon = 0, lat = 0,
phi = 0, theta = 0,
onPointerDownPointerX = 0,
onPointerDownPointerY = 0,
onPointerDownLon = 0,
onPointerDownLat = 0
const distance = 1e4-9e3
var func = navigator.userAgent.toLowerCase().indexOf('firefox') != -1 ? "onwheel" : "onmousewheel"
window[func]= e => {
let delta = camera.fov
delta += e.deltaY/25
camera.fov = Math.min(140, Math.max(10, delta))
camera.updateProjectionMatrix()
}
var material, loadScene, texture, sceneLoaded = false, geometry
function init(url){
const container = document.getElementById( 'container' )
camera = new THREE.PerspectiveCamera( 100, 16/9, .05, 1e6)
loadScene = () =>{
scene = new THREE.Scene()
geometry = new THREE.SphereGeometry( 1e4, 64, 240 )
geometry.scale( - 1, 1, 1 )
texture = new THREE.CanvasTexture(c)
/*
if(url.toLowerCase().indexOf('.mp4') != -1 ||
url.toLowerCase().indexOf('.webm') != -1){
const vid = document.createElement('video')
vid.muted = true
vid.loop = true
vid.crossOrigin = true
vid.src = url
vid.play()
texture = new THREE.VideoTexture( vid )
}else{
texture = new THREE.TextureLoader().load(url)
texture.wrapS = THREE.RepeatWrapping
texture.wrapT = THREE.RepeatWrapping
texture.repeat.set( 1, 1 )
}
*/
texture.colorSpace = THREE.SRGBColorSpace
texture.anisotropy = renderer.capabilities.getMaxAnisotropy()
texture.wrapS = THREE.RepeatWrapping
texture.wrapT = THREE.RepeatWrapping
texture.repeat.set( 1, 1 )
material = new THREE.MeshBasicMaterial( { map: texture } )
material.map.minFilter = THREE.LinearFilter
const mesh = new THREE.Mesh( geometry, material )
scene.add( mesh )
sceneLoaded = true
}
renderer = new THREE.WebGLRenderer()
renderer.setSize( 1920, 1080 )
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setAnimationLoop( animate )
container.appendChild( renderer.domElement )
document.addEventListener( 'pointerdown', onPointerDown )
document.addEventListener( 'pointermove', onPointerMove )
document.addEventListener( 'pointerup', onPointerUp )
document.addEventListener( 'touchstart', onPointerDown )
document.addEventListener( 'touchmove', onPointerMove )
document.addEventListener( 'touchend', onPointerUp )
loadScene()
}
function onPointerDown( event ) {
isUserInteracting = true
onPointerDownPointerX = event.clientX
onPointerDownPointerY = event.clientY
onPointerDownLon = lon
onPointerDownLat = lat
}
function onPointerMove( event ) {
if ( isUserInteracting === true ) {
var mag = .01 + camera.fov/450
lon = ( onPointerDownPointerX - event.clientX ) * mag + onPointerDownLon
lat = ( onPointerDownPointerY - event.clientY ) * mag + onPointerDownLat
}
}
function onPointerUp() {
isUserInteracting = false
}
function animate() {
if(typeof showRender != 'undefined' && showRender){
if(!sceneLoaded) loadScene()
lat = Math.max( - 89.9, Math.min( 89.9, lat ) )
phi = ( 90 - lat )/180*Math.PI
theta = lon/180*Math.PI
camera.position.x = distance * Math.sin( phi ) * Math.cos( theta )
camera.position.y = distance * Math.cos( phi )
camera.position.z = distance * Math.sin( phi ) * Math.sin( theta )
camera.lookAt( 0, 0, 0 )
renderer.render( scene, camera )
material.map.needsUpdate = true
}else{
sceneLoaded = false
}
}
var url
var l = location.href.split('url=')
if(l.length>1){
url = l[1].split('&')[0]
init(url)
}else{
init('')
}
</script>
<script id="rendered-js" >
c = document.querySelector('#c');
c.tabIndex = 0;
x_ = c.getContext('2d');
c.width = 1920;
c.height = 1080;
camMode = 'HDRI';
HDRIwidth = c.width;
outputAspectRatio = 16 / 9;
output = document.createElement('canvas');
octx = output.getContext('2d');
output.width = c.width;
output.height = output.width / outputAspectRatio;
showOutput = false; // HDRI view, for recording
showRender = false; // actual pipe to environment, for render eval etc
showPreview = false; // thumbnail in upper right
// (only visible in default or HDRI output, not render)
if (showRender) {
outputAspectRatio = 2;
showOutput = true;
showPreview = false;
c.style.display = 'none';
} else {
//showPreview = true
//showOutput = false
setTimeout(() => {
c.style.display = 'block';
c.style.borderRadius = showOutput ? '0' : '10px';
c.style.border = showOutput ? 'none' : '3px solid #fff3';
c.style.margin = showOutput ? 0 : 10;
}, 0);
}
// tempBuffer, needed for optional preview [P]
tempBuffer = document.createElement('canvas');
tempBuffer.width = c.width;
tempBuffer.height = c.height;
tbctx = tempBuffer.getContext('2d');
C = Math.cos;
S = Math.sin;
t = 0;
T = Math.tan;
rsz = window.onresize = () => {
let b = document.body;
let margin = showOutput ? 0 : 10;
let n;
let d = showOutput ? 1 / outputAspectRatio : .5625;
c.style.borderRadius = showOutput ? '0' : '10px';
c.style.border = showOutput ? 'none' : '3px solid #fff3';
//c.width = 1920
c.height = c.width * d;
output.width = c.width;
output.height = output.width * d;
if (b.clientHeight / b.clientWidth > d) {
c.style.width = `${(n = b.clientWidth) - margin * 2}px`;
c.style.height = `${n * d - margin * 2}px`;
} else {
c.style.height = `${(n = b.clientHeight) - margin * 2}px`;
c.style.width = `${n / d - margin * 2}px`;
}
};
rsz();
keyTimer = 0;
keyTimerInterval = .25;
keys = Array(256).fill(false);
window.onkeyup = e => {
keyTimer = 0;
keys[e.keyCode] = false;
};
window.onkeydown = e => {
keys[e.keyCode] = true;
if (keyTimer <= t) {
keyTimer = t + keyTimerInterval;
if (e.keyCode == 72) {
showOutput = !showOutput;
if (showRender) {
if (typeof can != 'undefined') {
outputAspectRatio = 2;
showOutput = true;
showPreview = false;
can.style.display = 'block';
c.style.display = 'none';
rsz2();
}
} else {
showPreview = true;
if (typeof can != 'undefined') can.style.display = 'none';
c.style.display = 'block';
rsz();
}
}
if (e.keyCode == 80) {
showPreview = !showPreview;
}
if (e.keyCode == 82) {
showRender = !showRender;
if (showRender) {
outputAspectRatio = 2;
showPreview = false;
showOutput = true;
can.style.display = 'block';
c.style.display = 'none';
} else {
showPreview = true;
can.style.display = 'none';
c.style.display = 'block';
}
}
if (e.keyCode == 70) {
if (showRender || outputAspectRatio == 16 / 9) {
outputAspectRatio = 2;
} else {
outputAspectRatio = 16 / 9;
}
rsz();
}
}
};
window.addEventListener('resize', rsz2 = () => {
can = document.querySelectorAll('canvas')[0];
if (typeof can != 'undefined') {
can.tabindex = 0;
can.focus();
let b = document.body;
let margin = 10;
let n;
let d = .5625;
can.style.borderRadius = '10px';
can.style.border = '3px solid #fff3';
if (b.clientHeight / b.clientWidth > d) {
can.style.width = `${(n = b.clientWidth) - margin * 2}px`;
can.style.height = `${n * d - margin * 2}px`;
} else {
can.style.height = `${(n = b.clientHeight) - margin * 2}px`;
can.style.width = `${n / d - margin * 2}px`;
}
}
if (showRender) {
showRender = false;
setTimeout(() => {
showRender = true;
}, 0);
}
});
for (let i = 10; i--;) setTimeout(() => {rsz2(), rsz();}, i * 60);
async function Draw() {
if (!t) {
X = Y = Z = 0;
oX = oY = oZ = 0;
Rl = Pt = Yw = 0;
camX = camY = camZ = camD = 0;
camposX = camposY = camposZ = 0;
camRl = camPt = camYw = 0;
Rn = Math.random;
cls = () => {
Z = camZ = 1E6;
x_['globalAlpha'] = 1;
x_.fillStyle = showOutput && showPreview ? '#0008' : '#000a';
x_.fillRect(0, 0, 1e5, 1e5, 0, 0, 1e5, 1e5);
x_.lineJoin = 'roud';
x_.lineCap = 'roud';
octx['globalAlpha'] = 1;
octx.fillStyle = '#000a';
octx.fillRect(0, 0, 1e5, 1e5, 0, 0, 1e5, 1e5);
octx.lineJoin = 'roud';
octx.lineCap = 'roud';
override = false;
};
hoff = .5; // horizontal offset of HDRI output, note it wraps
invertY = true;
x = (func, ...vals) => {
let p = 0,q = 0,d,ox,oy,oz,ox1,oy1,oz1,X1,Y1,Z1,X2,Y2,Z2,X3,Y3,Z3,X4,Y4,Z4;
let ox2, oy2, oz2, s, s2, split, onscreen1, onscreen2;
switch (func) {
// assignments
case 'strokeStyle':
if (vals.length) {
x_[func] = vals[0];
octx[func] = vals[0];
} else {
return x_[func];
}
break;
case 'fillText':
if (Z > 0 && (!showOutput || showPreview || override)) x_[func](vals[0], vals[1], vals[2]);
if (showOutput || showPreview) {
let text = vals[0];
ox = camX - camposX;
oy = camY - camposY;
oz = camZ - camposZ;
p = ((Math.atan2(ox, oz) + Math.PI * 2) / Math.PI / 2 + hoff) % 1;
d = Math.hypot(ox, oy, oz) + .0001;
q = invertY ? 1 - Math.acos(oy / d) / Math.PI : Math.acos(oy / d) / Math.PI;
ox1 = p * output.width;
oy1 = q * output.height;
X1 = ox1 + vals[3];
Y1 = oy1 + vals[4];
octx[func](text, X1, Y1);
if (X1 < 0) octx[func](text, X1 + output.width, Y1);
if (X1 + X2 > output.width) octx[func](text, X1 - output.width, Y1);
}
break;
case 'textAlign':
if (vals.length) {
x_[func] = vals[0];
octx[func] = vals[0];
} else {
return x_[func];
}
break;
case 'globalCompositeOperation':
if (vals.length) {
x_[func] = vals[0];
octx[func] = vals[0];
} else {
return x_[func];
}
break;
case 'lineWidth':
if (vals.length) {
x_[func] = vals[0];
ox = camX - camposX;
oy = camY - camposY;
oz = camZ - camposZ;
p = ((Math.atan2(ox, oz) + Math.PI * 2) / Math.PI / 2 + hoff) % 1;
d = Math.hypot(ox, oy, oz) + .0001;
q = invertY ? 1 - Math.acos(oy / d) / Math.PI : Math.acos(oy / d) / Math.PI;
//modsize = .4+Math.abs(.5 - q)*2
modsize = .5 + (2 * Math.abs(.5 - q) * 1.5) ** 2 / 1.5;
.........完整代码请登录后点击上方下载按钮下载查看
















网友评论0