• Contact
  • import React, { useEffect, useRef } from "react"; import * as THREE from "three"; export default function RotatingGlobe({ size = "medium", autoRotate = true, speed = 0.2, className = "", }) { const mountRef = useRef(null); const frameRef = useRef(); useEffect(() => { const mount = mountRef.current; if (!mount) return; const scene = new THREE.Scene(); const width = mount.clientWidth; const height = mount.clientHeight; const camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 1000); camera.position.set(0, 0, 2.7); const renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true }); renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); renderer.setSize(width, height); renderer.setClearColor(0x000000, 0); mount.appendChild(renderer.domElement); const ambient = new THREE.AmbientLight(0xffffff, 0.6); scene.add(ambient); const key = new THREE.PointLight(0xffffff, 1.0); key.position.set(5, 3, 5); scene.add(key); const globeGroup = new THREE.Group(); scene.add(globeGroup); // Skeleton globe: green wireframe with more separation const sphereGeo = new THREE.SphereGeometry(1, 32, 32); const wireMaterial = new THREE.MeshBasicMaterial({ color: 0x33ff33, wireframe: true, opacity: 0.85, transparent: true }); const sphere = new THREE.Mesh(sphereGeo, wireMaterial); globeGroup.add(sphere); // Add text "Scripturenews.com" onto the globe (white letters) const canvas = document.createElement('canvas'); canvas.width = 1024; canvas.height = 512; const ctx = canvas.getContext('2d'); ctx.fillStyle = 'transparent'; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.font = 'bold 80px Arial'; ctx.fillStyle = '#ffffff'; // white text ctx.textAlign = 'center'; ctx.fillText('Scripturenews.com', canvas.width/2, canvas.height/2); const textTexture = new THREE.CanvasTexture(canvas); textTexture.encoding = THREE.sRGBEncoding; const textMaterial = new THREE.MeshBasicMaterial({ map: textTexture, transparent: true }); const textMesh = new THREE.Mesh(sphereGeo, textMaterial); globeGroup.add(textMesh); // Atmosphere halo const atmosphereGeo = new THREE.SphereGeometry(1.03, 32, 32); const atmosphereMat = new THREE.MeshBasicMaterial({ color: 0x33ff33, opacity: 0.07, transparent: true, blending: THREE.AdditiveBlending, depthWrite: false, }); const atmosphere = new THREE.Mesh(atmosphereGeo, atmosphereMat); globeGroup.add(atmosphere); // Stars background const starsGeo = new THREE.BufferGeometry(); const starCount = 400; const positions = new Float32Array(starCount * 3); for (let i = 0; i < starCount; i++) { const r = 6 + Math.random() * 12; const theta = Math.random() * Math.PI * 2; const phi = Math.acos((Math.random() * 2) - 1); positions[i*3 + 0] = Math.sin(phi) * Math.cos(theta) * r; positions[i*3 + 1] = Math.sin(phi) * Math.sin(theta) * r; positions[i*3 + 2] = Math.cos(phi) * r; } starsGeo.setAttribute('position', new THREE.BufferAttribute(positions, 3)); const starsMat = new THREE.PointsMaterial({ size: 0.01, transparent: true, opacity: 0.7 }); const starField = new THREE.Points(starsGeo, starsMat); scene.add(starField); let pointer = { x: 0, y: 0 }; function onPointerMove(e) { const rect = mount.getBoundingClientRect(); pointer.x = ((e.clientX - rect.left) / rect.width) * 2 - 1; pointer.y = -(((e.clientY - rect.top) / rect.height) * 2 - 1); } mount.addEventListener('pointermove', onPointerMove); function onResize() { const w = mount.clientWidth; const h = mount.clientHeight; camera.aspect = w / h || 1; camera.updateProjectionMatrix(); renderer.setSize(w, h); } window.addEventListener('resize', onResize); let last = performance.now(); const rotationSpeed = speed * 0.0012; function animate(now) { const dt = now - last; last = now; if (autoRotate) globeGroup.rotation.y -= rotationSpeed * dt; // counter-clockwise globeGroup.rotation.x = THREE.MathUtils.lerp(globeGroup.rotation.x, pointer.y * 0.08, 0.06); globeGroup.rotation.z = THREE.MathUtils.lerp(globeGroup.rotation.z, -pointer.x * 0.04, 0.06); starField.rotation.y += 0.00003 * dt; renderer.render(scene, camera); frameRef.current = requestAnimationFrame(animate); } frameRef.current = requestAnimationFrame(animate); return () => { cancelAnimationFrame(frameRef.current); mount.removeChild(renderer.domElement); mount.removeEventListener('pointermove', onPointerMove); window.removeEventListener('resize', onResize); sphereGeo.dispose(); wireMaterial.dispose(); atmosphereGeo.dispose(); atmosphereMat.dispose(); textTexture.dispose(); textMaterial.dispose(); starsGeo.dispose(); starsMat.dispose(); renderer.dispose(); }; }, [autoRotate, speed]); let maxSizeClass = "w-48 h-48"; if (size === 'small') maxSizeClass = "w-36 h-36"; if (size === 'large') maxSizeClass = "w-72 h-72"; if (typeof size === 'number') maxSizeClass = `w-[${size}px] h-[${size}px]`; return (

    ); }  

Los Angeles Time  

 

 

 

 

4-10-2024

 

 

 

 

 


 

-----------------------------------------------------------------------------------------------------