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