Want to get this as ready made template with just 1 CLICK INSTALL?
Code Snippet for 3D Sphere Image Gallery:
<style> .mdw-3d-globe-gallery{ --image-width: 10; --image-height: 10; --image-repeat: 2; --auto-rotate: true; --auto-rotate-speed: 10; } .mdw-3d-globe-gallery{ height: var(--min-height, 550px); } </style> <script src="https://cdn.jsdelivr.net/npm/three@0.159.0/build/three.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/three@0.132.2/examples/js/controls/OrbitControls.js"></script> <script> if(!MDWNonce117){ var MDWNonce117 = true function getCSS(el, property, defaultValue = 0){ var val = getComputedStyle(el).getPropertyValue(property) return val ? val.trim() : defaultValue } document.addEventListener('DOMContentLoaded', function(){ document.querySelectorAll('.mdw-3d-globe-gallery').forEach(function(el) { var container = el, planeWidth = parseFloat(getCSS(container, '--image-width', 10))/(100/9), planeHeight = parseFloat(getCSS(container, '--image-height', 10))/(100/9), planeRatio = planeWidth / planeHeight, images = container.querySelectorAll('img'), imageLinks = Array.from(images).map(img => img.src), repeat = parseFloat(getCSS(container, '--image-repeat', 1)), totalItems = Math.floor(imageLinks.length*repeat), scene = new THREE.Scene(), camera = new THREE.PerspectiveCamera(75, container.offsetWidth / container.offsetHeight, 0.1, 1000), renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }), controls = new THREE.OrbitControls(camera, renderer.domElement) camera.position.z = 8.5 renderer.setSize(container.offsetWidth, container.offsetHeight) renderer.setPixelRatio(window.devicePixelRatio) container.appendChild(renderer.domElement) controls.enableDamping = true controls.dampingFactor = 0.05 controls.rotateSpeed = 1.2 controls.enableZoom = false controls.enablePan = false if(getCSS(container, '--auto-rotate', false) == 'true'){ controls.autoRotate = true controls.autoRotateSpeed = parseFloat(getCSS(container, '--auto-rotate-speed', 0))/10 } function animate(){ requestAnimationFrame(animate) controls.update() renderer.render(scene, camera) } function createSphere(){ var fullRepeat = Math.floor(repeat), partialLength = Math.floor((repeat % 1) * imageLinks.length), allImageLink = [ ...Array(fullRepeat).fill(imageLinks).flat(), ...imageLinks.slice(0, partialLength) ], loadedCount = 0, sphereRadius = 5, textureLoader = new THREE.TextureLoader() for (let i = 0; i < totalItems; i++) { textureLoader.load( allImageLink[i], function(texture){ var phi = Math.acos(-1 + (2 * i) / totalItems), theta = Math.sqrt(totalItems * Math.PI) * phi, imageRatio = texture.image.width / texture.image.height, scale texture.wrapS = texture.wrapT = THREE.ClampToEdgeWrapping if(imageRatio > planeRatio){ scale = planeRatio / imageRatio texture.repeat.set(scale, 1) texture.offset.set((1 - scale) / 2, 0) }else{ scale = imageRatio / planeRatio texture.repeat.set(1, scale) texture.offset.set(0, (1 - scale) / 2) } texture.encoding = THREE.sRGBEncoding var geometry = new THREE.PlaneGeometry(planeWidth, planeHeight), material = new THREE.MeshBasicMaterial({ map: texture, side: THREE.DoubleSide }), mesh = new THREE.Mesh(geometry, material) mesh.position.x = sphereRadius * Math.cos(theta) * Math.sin(phi) mesh.position.y = sphereRadius * Math.sin(theta) * Math.sin(phi) mesh.position.z = sphereRadius * Math.cos(phi) mesh.lookAt(0, 0, 0) mesh.rotateY(Math.PI) scene.add(mesh) loadedCount++ if (loadedCount === totalItems) animate() } ) } } createSphere() window.addEventListener('resize', function(){ renderer.setSize(container.offsetWidth, container.offsetHeight) camera.aspect = container.offsetWidth / container.offsetHeight camera.updateProjectionMatrix() }) }) }) } </script>