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>


