three+gsap实现三维圆点构成的地球旋转动画效果代码

代码语言:html

所属分类:三维

代码描述:three+gsap实现三维圆点构成的地球旋转动画效果代码,单击增加圆点及旋转坐标。

代码标签: three gsap 三维 圆点 地球 旋转 动画

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="en" >
<head>
  <meta charset="UTF-8">
<style>
    body {
  padding: 0;
  margin: 0;
}
.title {
	position: fixed;
	top: 7px;
	color: #ddd;
	font-family: sans-serif;
	width: 100%;
	text-align: center;
	opacity: 0;
}
.demo {
  width: 100%;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #1C1C1E;
}
#globe-3d, #globe-2d-overlay, #globe-popup-overlay, .globe-popup {
  display: block;
  position: absolute;
}
#globe-2d-overlay, #globe-popup-overlay {
  pointer-events: none;
}
.globe-popup-overlay {
  width: 100%;
  height: 100%;
  opacity: 0;
}
.globe-popup {
  top: 0;
  left: 0;
  background-color: rgba(75, 192, 200, .9);
  opacity: 0;
  color: #111;
  font-family: sans-serif;
  font-weight: bold;
  padding: 5px 10px;
  font-size: 15px;
  border-radius: 3px;
}
</style>

</head>
<body>
<!-- partial:index.partial.html -->
<div class="title">单击地球增加点</div>
<div class="demo">
    <div class="animation-wrapper">
        <canvas id="globe-3d"></canvas>
        <canvas id="globe-2d-overlay"></canvas>
        <div id="globe-popup-overlay">
            <div class="globe-popup"></div>
        </div>
    </div>
</div>


<script type="x-shader/x-fragment" id="fragment-shader-map">
    uniform vec3 u_color_main;

    varying float vOpacity;

    float circle(vec2 st, float r) {
        vec2 dist = st - vec2(.5);
        return 1. - smoothstep(.99 * r, 1.01 * r, dot(dist, dist) * 4.);
    }

    void main() {
        float dot = circle(gl_PointCoord.xy, .7);
        if (dot < 0.5) discard;
        gl_FragColor = vec4(u_color_main, dot * vOpacity);
    }
</script>

<script type="x-shader/x-vertex" id="vertex-shader-map">
    uniform sampler2D u_visibility;
    uniform float u_size;
    uniform float u_time_since_click;
    uniform vec3 u_clicked;

    varying float vOpacity;

    void main() {

        // mask with world map
        float visibility = 1. - step(.4, texture2D(u_visibility, uv).x);
        gl_PointSize = visibility * u_size;

        // add ripple
        float time = u_time_since_click;
        float dist = length(position - u_clicked);
        float damping = pow(1. - sin(min(time, 1.)), 5.);
        float wave = (1. + sin(3. * dist + 13. * time));
        float delta = -.025 * damping * wave;

        // make backside dots darker
        vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
        vOpacity = (1. / length(mvPosition.xyz) - .7);
        vOpacity = clamp(vOpacity, 0., .5) + .01;

        gl_Position = projectionMatrix * modelViewMatrix * vec4(position * (1. + delta), 1.);
    }
</script>
<!-- partial -->
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/gsap.3.10.1.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/three.126.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/OrbitControls.126.js"></script>
<script>


const demo = document.querySelector('.demo');
const container = document.querySelector('.animation-wrapper');
const globeCanvas = container.querySelector('#globe-3d');
const globeOverlayCanvas = container.querySelector('#globe-2d-overlay');
const popup = container.querySelector('.globe-popup');


document.addEventListener('DOMContentLoaded', () => {
    gsap.set(demo, {
        height: window.innerHeight
    });

    let surface = new Surface();

    new THREE.TextureLoader().load(
        '//repo.bfw.wiki/bfwrepo/image/6098ff67cddfe.png',
        (mapTex) => {
            surface.earthTexture = mapTex;
            surface.earthTexture.repeat.set(1, 1);
            surface.earthTextureData = surface.getImageData();
            surface.createGlobe();
            surface.addAnchor();
            surface.addCanvasEvents();
            surface.updateDotSize();
            surface.loop();
        });

    window.addEventListener('resize', () => {
        gsap.set(demo, {
            height: window.innerHeight
        });

        surface.updateSize();
        surface.setupOverlayGraphic();
        surface.updateDotSize();
        surface.addCanvasEvents();
    }, false);
	
	 gsap.to('.title', {
		 delay: 5,
		 duration: .2,
		 opacity: 1
	 })

});


class Surface {

    constructor() {
        this.renderer = new THREE.WebGLRenderer({canvas: globeCanvas, alpha: true});
        this.scene = new THREE.Scene();
        this.camera = new THREE.OrthographicCamera(-1, 1, 1, -1, .1, 2);
        this.camera.position.z = 1.1;
        this.updateSize();

        this.rayCaster = new THREE.Raycaster();
        this.rayCaster.far = 1.15;
        this.mouse = new THREE.Vector2();
        this.coordinates2D = [0, 0];

        this.setupOverlayGraphic();
        this.createOrbitControls();

        this.clock = new THREE.Clock();
        this.clickTime = 0;

        this.group = new THREE.Group();
        this.group.scale.setScalar(0.9);
        this.scene.add(this.group);

        this.selectionVisible = false;
    }

    createOrbitControls() {
        this.controls = new THREE.OrbitControls(this.camera, globeCanvas);
        this.controls.enablePan = true;
        this.controls.enableZoom = false;
        this.controls.enableDamping = true;
        this.controls.minPolarAngle = .35 * Math.PI;
        this.controls.maxPolarAngle = .65 * Math.PI;
        this.controls.autoRotate = true;
    }

    createGlobe() {
        const globeGeometry = new THREE.IcosahedronGeometry(1, 14);
        this.mapMaterial = new THREE.ShaderMaterial({
            vertexShader: document.getElementById('vertex-shader-map').textContent,
            fragmentShader: document.getElementById('fragment-shader-map').textContent,
            uniforms: {
                u_visibility: {type: 't', value: this.earthTexture},
                u_size: {type: 'f', value: 0},
                u_color_main: {type: 'v3', value: new THREE.Color(0xc1c1c2)},
                u_clicked: {type: 'v3', value: new THREE.Vector3(.0, .0, 1.)},
                u_time_since_click: {value: 3.},
            },
            alphaTest: false,
            transparent: true
        });

        const globe = new THREE.Points(globeGeometry, this.mapMaterial);
        this.group.add(globe);

        this.blackGlobe = new THREE.Mesh(globeGeometry, new THREE.MeshBasicMaterial({
            color: 0x2C2C2E,
            transparent: true,
            opacity: 0.2
        }));
        this.blackGlobe.scale.setScalar(0.99);
        this.group.add(this.blackGlobe);
    }

    addAnchor() {
        const geometry = new THREE.SphereGeometry(.02, 16, 16);
        const material = new THREE.MeshBasicMaterial({
            color: 0x4BC0C8,
            transparent: true,
            opacity: 1
        });
        this.anchor = new THREE.Mesh(geometry, material);
        this.group.add(this.anchor);
    }

    setupOverlayGraphic() {
        this.overlayCtx = globeOverlayCanvas.getContext('2d');
        this.overlayCtx.strokeStyle = '#4BC0C8';
        this.overlayCtx.lineWidth = 5;
        this.overlayCtx.lineCap = 'round';
    }

    updateOverlayGraphic() {
        if (this.anchor) {
            let activePointPosition = this.anchor.position.clone();
            activePointPosition.applyMatrix4(this.group.matrixWorld);
        .........完整代码请登录后点击上方下载按钮下载查看

网友评论0