webgl+gsap+three实现三维透明地球鼠标点击标注地理坐标位置效果代码

代码语言:html

所属分类:三维

代码描述:webgl+gsap+three实现三维透明地球鼠标点击标注地理坐标位置效果代码

代码标签: webgl gsap three 三维 透明 地球 鼠标 点击 标注 地理 坐标 位置

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

<!DOCTYPE html>
<html lang="en" >

<head>
  <meta charset="UTF-8">

  
  
  
<style>
body {
    padding: 0;
    margin: 0;
    overflow: hidden;
}

.page {
    width: 100%;
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
}

.title {
	 position: fixed;
	 bottom: 10%;
	 left: 0;
	 width: 100%;
	 text-align: center;
	 font-family: sans-serif;
}

#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 {
    top: 0;
    left: 0;
    background-color: white;
    opacity: 0;
    color: #111;
    font-family: sans-serif;
    padding: 5px 10px;
    font-size: 15px;
    border-radius: 3px;
    filter: drop-shadow(0px 0px 3px #555555);
}
</style>

  
</head>

<body >
  <div class="page">
	 <div class="title">click to add a pointer</div>
    <div class="globe-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 sampler2D u_map_tex;

    varying float vOpacity;
    varying vec2 vUv;

    void main() {
        vec3 color = texture2D(u_map_tex, vUv).rgb;
        color -= .2 * length(gl_PointCoord.xy - vec2(.5));
        float dot = 1. - smoothstep(.38, .4, length(gl_PointCoord.xy - vec2(.5)));
        if (dot < 0.5) discard;
        gl_FragColor = vec4(color, dot * vOpacity);
    }
</script>

<script type="x-shader/x-vertex" id="vertex-shader-map">
    uniform sampler2D u_map_tex;
    uniform float u_dot_size;
    uniform float u_time_since_click;
    uniform vec3 u_pointer;

    #define PI 3.14159265359

    varying float vOpacity;
    varying vec2 vUv;

    void main() {

        vUv = uv;

        // mask with world map
        float visibility = step(.2, texture2D(u_map_tex, uv).r);
        gl_PointSize = visibility * u_dot_size;

        // make back dots semi-transparent
        vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
        vOpacity = (1. / length(mvPosition.xyz) - .7);
        vOpacity = clamp(vOpacity, .03, 1.);

        // add ripple
        float t = u_time_since_click - .1;
        t = max(0., t);
        float max_amp = .15;
        float dist = 1. - .5 * length(position - u_pointer); // 0 .. 1
        float damping = 1. / (1. + 20. * t); // 1 .. 0
        float delta = max_amp * damping * sin(5. * t * (1. + 2. * dist) - PI);
        delta *= 1. - smoothstep(.8, 1., dist);
        vec3 pos = position;
        pos *= (1. + delta);

        gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.);
    }
</script>

<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/gsap.3.10.4.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/three.133.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/OrbitControls.133.js"></script>
      <script >


const containerEl = document.querySelector(".globe-wrapper");
const canvas3D = containerEl.querySelector("#globe-3d");
const canvas2D = containerEl.querySelector("#globe-2d-overlay");
const popupEl = containerEl.querySelector(".globe-popup");

let renderer, scene, camera, rayCaster, controls, group;
let overlayCtx = canvas2D.getContext("2d");
let coordinates2D = [0, 0];
let pointerPos;
let clock, mouse, pointer, globe, globeMesh;
let popupVisible;
let earthTexture, mapMaterial;
let popupOpenTl, popupCloseTl;

let dragged = false;

initScene();
window.addEventListener("resize", updateSize);


function initScene() {
  renderer = new THREE.WebGLRenderer({ canvas: canvas3D, alpha: true });
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));

  scene = new THREE.Scene();
  camera = new THREE.OrthographicCamera(-1.1, 1.1, 1.1, -1.1, 0, 3);
  camera.position.z = 1.1;

  rayCaster = new THREE.Raycaster();
  rayCaster.far = 1.15;
  mouse = new THREE.Vector2(-1, -1);
  clock = new THREE.Clock();

  createOrbitControls();

  popupVisible = false;

  new THREE.TextureLoader().load(
  "//repo.bfw.wiki/bfwrepo/image/6098ffa058cd1.png",
  mapTex => {
    earthTexture = mapTex;
    earthTexture.repeat.set(1, 1);
    createGlobe();
    createPointer();
    createPopupTimelines();
    addCanvasEvents();
    updateSize();
    render();
  });
}


function createOrbitControls() {
  controls = new THREE.OrbitControls(camera, canvas3D);
  controls.enablePan = false;
  controls.enableZoom = false;
  controls.enableDamping = true;
  controls.minPolarAngle = .4 * Math.PI;
  controls.maxPolarAngle = .4 * Math.PI;
  controls.autoRotate = true;

  let timestamp;
  controls.addEventListener("start", () => {
    timestamp = Date.now();
  });
  controls.addEventListener("end", () => {
    dragged = Date.now() - timestamp > 200;
  });
}

function createGlobe() {
  const globeGeometry = new THREE.IcosahedronGeometry(1, 22);
  mapMaterial = new THREE.ShaderMaterial({
    vertexShader: document.getElementById("vertex-shader-map").textContent,
    fragmentShader: document.getElementById("fragment-shader-map").textContent,
    uniforms: {
      u_map_tex: { type: "t", value: earthTexture },
      u_dot_size: { type: "f", value: 0 },
      u_pointer: { type: "v3", value: new THREE.Vector3(.0, .0, 1.) },
      u_time_since_click: { value: 0 } },

    alphaTest: false,
    transparent: true });


  globe = new THREE.Points(globeGeometry, mapMaterial);
  sc.........完整代码请登录后点击上方下载按钮下载查看

网友评论0