"css"
Bootstrap 3.0.0 Snippet by evarevirus

<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css"> <script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script> <script src="//code.jquery.com/jquery-1.11.1.min.js"></script> <!------ Include the above in your HEAD tag ----------> <!DOCTYPE html><html lang='en' class=''> <head><script src='//production-assets.codepen.io/assets/editor/live/console_runner-079c09a0e3b9ff743e39ee2d5637b9216b3545af0de366d4b9aad9dc87e26bfd.js'></script><script src='//production-assets.codepen.io/assets/editor/live/events_runner-73716630c22bbc8cff4bd0f07b135f00a0bdc5d14629260c3ec49e5606f98fdd.js'></script><script src='//production-assets.codepen.io/assets/editor/live/css_live_reload_init-2c0dc5167d60a5af3ee189d570b1835129687ea2a61bee3513dee3a50c115a77.js'></script><meta charset='UTF-8'><meta name="robots" content="noindex"><link rel="shortcut icon" type="image/x-icon" href="//production-assets.codepen.io/assets/favicon/favicon-8ea04875e70c4b0bb41da869e81236e54394d63638a1ef12fa558a4a835f1164.ico" /><link rel="mask-icon" type="" href="//production-assets.codepen.io/assets/favicon/logo-pin-f2d2b6d2c61838f7e76325261b7195c27224080bc099486ddd6dccb469b8e8e6.svg" color="#111" /><link rel="canonical" href="https://codepen.io/edankwan/pen/emqgpr?limit=all&page=27&q=css" /> <script src="https://s.codepen.io/assets/libs/modernizr.js" type="text/javascript"></script> <script src='https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js'></script><link rel='stylesheet prefetch' href='https://fonts.googleapis.com/css?family=Oswald:400'> <style class="cp-pen-styles">html, body { position: absolute; width: 100%; height: 100%; margin: 0 0; overflow: hidden; font-family: 'Lato', sans-serif; background-color: #000; color: #fff; } .world { position: absolute; width: 100%; height: 100%; cursor: pointer; cursor: move; cursor: -moz-grab; cursor: -webkit-grab; cursor: grab; } .world-bg { position: absolute; width: 100%; height: 100%; background-position: 50% 50%; background-size: cover; } .world-globe { position: absolute; left: 50%; top: 50%; width: 0; height: 0; } .world-globe-pole { position: absolute; width: 530px; height: 530px; left: -265px; top: -265px; border-radius: 50% 50%; background-color: #fff; } .world-globe-doms-container { position: absolute; left: 50%; top: 50%; width: 0; height: 0; } .world-globe-halo { position: absolute; left: 50%; top: 50%; width: 730px; height: 715px; margin-left: -368px; margin-top: -350px; } .info { position: absolute; left: 0; bottom: 0; width: 100%; padding: 10px 10px; box-sizing: border-box; background-color: rgba(0, 0, 0, 0.8); color: #fff; font-size: 12px; } .info-desc { color: #ddd; font-size: 10px; } a { color: #ff5f5f; } </style></head><body> <div class="world"> <div class="world-bg"></div> <div class="world-globe"> <div class="world-globe-pole"></div> <div class="world-globe-doms-container"></div> <div class="world-globe-halo"></div> </div> </div> <div class="info"> <div class="info-title">CSS Non-webgl realistic globe Demo</div> <div class="info-desc">Example for my meetup talk. Use <a href="https://github.com/edankwan/PerspectiveTransform.js" target="_blank">PerspectiveTransform</a> and visual trick to create a CSS 3D globe.</div> <div class="info-links"><a href="https://twitter.com/edankwan" target="_blank">@edankwan</a></div> </div> <script src='//production-assets.codepen.io/assets/common/stopExecutionOnTimeout-b2a7b3fe212eaa732349046d8416e00a9dec26eb7fd347590fbced3ab38af52e.js'></script><script src='//cdnjs.cloudflare.com/ajax/libs/dat-gui/0.5/dat.gui.min.js'></script><script src='//cdnjs.cloudflare.com/ajax/libs/stats.js/r11/Stats.js'></script><script src='https://s3-us-west-2.amazonaws.com/s.cdpn.io/6043/css_globe_PerspectiveTransform.js'></script><script src='//cdnjs.cloudflare.com/ajax/libs/gsap/1.16.1/TweenMax.min.js'></script> <script >var config = { percent: 0, lat: 0, lng: 0, segX: 14, segY: 12, isHaloVisible: true, isPoleVisible: true, autoSpin: true, zoom: 0, skipPreloaderAnimation: false, goToHongKong: function() { goTo(22.28552,114.15769); } }; var stats; var imgs; var preloader; var preloadPercent; var globeDoms; var vertices; var world; var worldBg; var globe; var globeContainer; var globePole; var globeHalo; var pixelExpandOffset = 1.5; var rX = 0; var rY = 0; var rZ = 0; var sinRX; var sinRY; var sinRZ; var cosRX; var cosRY; var cosRZ; var dragX; var dragY; var dragLat; var dragLng; var isMouseDown = false; var isTweening = false; var tick = 1; var URLS = { bg: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/6043/css_globe_bg.jpg', diffuse: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/6043/css_globe_diffuse.jpg', halo: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/6043/css_globe_halo.png', }; var transformStyleName = PerspectiveTransform.transformStyleName; function init(ref) { world = document.querySelector('.world'); worldBg = document.querySelector('.world-bg'); worldBg.style.backgroundImage = 'url(' + URLS.bg + ')'; globe = document.querySelector('.world-globe'); globeContainer = document.querySelector('.world-globe-doms-container'); globePole = document.querySelector('.world-globe-pole'); globeHalo = document.querySelector('.world-globe-halo'); globeHalo.style.backgroundImage = 'url(' + URLS.halo + ')'; regenerateGlobe(); var gui = new dat.GUI(); gui.add(config, 'lat', -90, 90).listen(); gui.add(config, 'lng', -180, 180).listen(); gui.add(config, 'isHaloVisible'); gui.add(config, 'isPoleVisible'); gui.add(config, 'autoSpin'); gui.add(config, 'goToHongKong'); gui.add(config, 'zoom', 0, 1).listen(); stats = new Stats(); stats.domElement.style.position = 'absolute'; stats.domElement.style.left = 0; stats.domElement.style.top = 0; document.body.appendChild( stats.domElement ); // events world.ondragstart = function () {return false;}; world.addEventListener('mousedown', onMouseDown); world.addEventListener('mousemove', onMouseMove); world.addEventListener('mouseup', onMouseUp); world.addEventListener('touchstart', touchPass(onMouseDown)); world.addEventListener('touchmove', touchPass(onMouseMove)); world.addEventListener('touchend', touchPass(onMouseUp)); loop(); } function touchPass(func) { return function(evt) { evt.preventDefault(); func.call(this, {pageX: evt.changedTouches[0].pageX, pageY: evt.changedTouches[0].pageY}); }; } function onMouseDown(evt) { isMouseDown = true; dragX = evt.pageX; dragY = evt.pageY; dragLat = config.lat; dragLng = config.lng; } function onMouseMove(evt) { if(isMouseDown) { var dX = evt.pageX - dragX; var dY = evt.pageY - dragY; config.lat = clamp(dragLat + dY * 0.5, -90, 90); config.lng = clampLng(dragLng - dX * 0.5, -180, 180); } } function onMouseUp(evt) { if(isMouseDown) { isMouseDown = false; } } function regenerateGlobe() { var dom, domStyle; var x, y; globeDoms = []; while (dom = globeContainer.firstChild) {if (window.CP.shouldStopExecution(1)){break;} globeContainer.removeChild(dom); } window.CP.exitedLoop(1); var segX = config.segX; var segY = config.segY; var diffuseImgBackgroundStyle = 'url(' + URLS.diffuse + ')'; var segWidth = 1600 / segX | 0; var segHeight = 800 / segY | 0; vertices = []; var verticesRow; var radius = (536) / 2; var phiStart = 0; var phiLength = Math.PI * 2; var thetaStart = 0; var thetaLength = Math.PI; for ( y = 0; y <= segY; y ++ ) {if (window.CP.shouldStopExecution(3)){break;} verticesRow = []; for ( x = 0; x <= segX; x ++ ) {if (window.CP.shouldStopExecution(2)){break;} var u = x / segX; var v = 0.05 + y / segY * (1 - 0.1); var vertex = { x: - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength ), y: -radius * Math.cos( thetaStart + v * thetaLength ), z: radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength ), phi: phiStart + u * phiLength, theta: thetaStart + v * thetaLength }; verticesRow.push( vertex ); } window.CP.exitedLoop(2); vertices.push( verticesRow ); } window.CP.exitedLoop(3); for ( y = 0; y < segY; ++y ) {if (window.CP.shouldStopExecution(5)){break;} for ( x = 0; x < segX; ++x ) {if (window.CP.shouldStopExecution(4)){break;} dom = document.createElement('div'); domStyle = dom.style; domStyle.position = 'absolute'; domStyle.width = segWidth + 'px'; domStyle.height = segHeight + 'px'; domStyle.overflow = 'hidden'; domStyle[PerspectiveTransform.transformOriginStyleName] = '0 0'; domStyle.backgroundImage = diffuseImgBackgroundStyle; dom.perspectiveTransform = new PerspectiveTransform(dom , segWidth, segHeight); dom.topLeft = vertices[ y ][ x ]; dom.topRight = vertices[ y ][ x + 1]; dom.bottomLeft = vertices[ y + 1 ][ x ]; dom.bottomRight = vertices[ y + 1 ][ x + 1 ]; domStyle.backgroundPosition = (-segWidth * x) + 'px ' + (-segHeight * y) + 'px'; globeContainer.appendChild(dom); globeDoms.push(dom); } window.CP.exitedLoop(4); } window.CP.exitedLoop(5); } function loop() { requestAnimationFrame(loop); stats.begin(); render(); stats.end(); } function render() { if(config.autoSpin && !isMouseDown && !isTweening) { config.lng = clampLng(config.lng - 0.2); } rX = config.lat / 180 * Math. PI; rY = (clampLng(config.lng) - 270) / 180 * Math. PI; globePole.style.display = config.isPoleVisible ? 'block' : 'none'; globeHalo.style.display = config.isHaloVisible ? 'block' : 'none'; var ratio = Math.pow(config.zoom, 1.5); pixelExpandOffset = 1.5 + (ratio) * -1.25; ratio = 1 + ratio * 3; globe.style[transformStyleName] = 'scale3d(' + ratio + ',' + ratio + ',1)'; ratio = 1 + Math.pow(config.zoom, 3) * 0.3; worldBg.style[transformStyleName] = 'scale3d(' + ratio + ',' + ratio + ',1)'; transformGlobe(); } function clamp(x, min, max) { return x < min ? min : x > max ? max : x; } function clampLng(lng) { return ((lng + 180) % 360) - 180; } function transformGlobe() { var dom, perspectiveTransform; var x, y, v1, v2, v3, v4, vertex, verticesRow, i, len; if(tick ^= 1) { sinRY = Math.sin(rY); sinRX = Math.sin(-rX); sinRZ = Math.sin(rZ); cosRY = Math.cos(rY); cosRX = Math.cos(-rX); cosRZ = Math.cos(rZ); var segX = config.segX; var segY = config.segY; for ( y = 0; y <= segY; y ++ ) {if (window.CP.shouldStopExecution(7)){break;} verticesRow = vertices[y]; for ( x = 0; x <= segX; x ++ ) {if (window.CP.shouldStopExecution(6)){break;} rotate(vertex = verticesRow[x], vertex.x, vertex.y, vertex.z); } window.CP.exitedLoop(6); } window.CP.exitedLoop(7); for ( y = 0; y < segY; y ++ ) {if (window.CP.shouldStopExecution(9)){break;} for ( x = 0; x < segX; x ++ ) {if (window.CP.shouldStopExecution(8)){break;} dom = globeDoms[x + segX * y]; v1 = dom.topLeft; v2 = dom.topRight; v3 = dom.bottomLeft; v4 = dom.bottomRight; expand(v1, v2); expand(v2, v3); expand(v3, v4); expand(v4, v1); perspectiveTransform = dom.perspectiveTransform; perspectiveTransform.topLeft.x = v1.tx; perspectiveTransform.topLeft.y = v1.ty; perspectiveTransform.topRight.x = v2.tx; perspectiveTransform.topRight.y = v2.ty; perspectiveTransform.bottomLeft.x = v3.tx; perspectiveTransform.bottomLeft.y = v3.ty; perspectiveTransform.bottomRight.x = v4.tx; perspectiveTransform.bottomRight.y = v4.ty; perspectiveTransform.hasError = perspectiveTransform.checkError(); if(!(perspectiveTransform.hasError = perspectiveTransform.checkError())) { perspectiveTransform.calc(); } } window.CP.exitedLoop(8); } window.CP.exitedLoop(9); } else { for ( i = 0, len = globeDoms.length; i < len; i ++ ) {if (window.CP.shouldStopExecution(10)){break;} perspectiveTransform = globeDoms[i].perspectiveTransform; if(!perspectiveTransform.hasError) { perspectiveTransform.update(); } else { perspectiveTransform.style[transformStyleName] = 'translate3d(-8192px, 0, 0)'; } } window.CP.exitedLoop(10); } } function goTo(lat, lng) { var dX = lat - config.lat; var dY = lng - config.lng; var roughDistance = Math.sqrt(dX * dX + dY * dY); isTweening = true; TweenMax.to(config, roughDistance * 0.01, {lat: lat, lng: lng, ease:'easeInOutSine'}); TweenMax.to(config, 1, {delay: roughDistance * 0.01, zoom: 1, ease:'easeInOutSine', onComplete: function(){ isTweening = false; }}); } function rotate(vertex, x, y, z) { x0 = x * cosRY - z * sinRY; z0 = z * cosRY + x * sinRY; y0 = y * cosRX - z0 * sinRX; z0 = z0 * cosRX + y * sinRX; var offset = 1 + (z0 / 4000); x1 = x0 * cosRZ - y0 * sinRZ; y0 = y0 * cosRZ + x0 * sinRZ; vertex.px = x1 * offset; vertex.py = y0 * offset; } // shameless stole and edited from threejs CanvasRenderer function expand( v1, v2 ) { var x = v2.px - v1.px, y = v2.py - v1.py, det = x * x + y * y, idet; if ( det === 0 ) { v1.tx = v1.px; v1.ty = v1.py; v2.tx = v2.px; v2.ty = v2.py; return; } idet = pixelExpandOffset / Math.sqrt( det ); x *= idet; y *= idet; v2.tx = v2.px + x; v2.ty = v2.py + y; v1.tx = v1.px - x; v1.ty = v1.py - y; } init(); //# sourceURL=pen.js </script> </body></html>

Related: See More


Questions / Comments: