JSFiddle - React, Tailwind, and code Playground
by grano
HTML
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/controls/OrbitControls.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/17.2.0/Tween.min.js"></script>
<script>
var sphereRadius = {
value: 20
};
function getMaterial(params) {
var diffuse = params.diffuse === undefined ? 0xffffff : params.diffuse;
var diffuseBack = params.diffuseBack === undefined ? diffuse : params.diffuseBack;
var inside = params.inside === undefined ? true : params.inside;
inside = inside ? 1 : -1;
let lambert = new THREE.ShaderMaterial({
uniforms: THREE.UniformsUtils.merge([THREE.ShaderLib.lambert.uniforms, {
clippingSphere: {
value: new THREE.Vector4()
},
diffuseBack: {
value: new THREE.Color()
}
}]),
lambert.vertexShader: THREE.ShaderLib.lambert.vertexShader
.replace(/varying vec3 vLightFront;/g, 'varying vec3 vLightFront;\nvarying vec4 worldPosition;')
.replace(/#include <worldpos_vertex>/g, 'worldPosition = modelMatrix * vec4( transformed, 1.0 );'),
fragmentShader: THREE.ShaderLib.lambert.fragmentShader
.replace(/uniform float opacity;/g, 'uniform float opacity;\nuniform vec4 clippingSphere;\nuniform vec3 diffuseBack;')
.replace(/varying vec3 vLightFront;/g, 'varying vec3 vLightFront;\nvarying vec4 worldPosition;')
.replace(/#include <clipping_planes_fragment>/g, '#include <clipping_planes_fragment>\n if (distance(worldPosition.xyz, clippingSphere.xyz) * sign(clippingSphere.w) > clippingSphere.w) discard;')
.replace(/#include <dithering_fragment>/g, '#include <dithering_fragment>\n if (!gl_FrontFacing) gl_FragColor.xyz = diffuseBack;'),
lights: true,
side: THREE.DoubleSide,
flatShading: false
});
lambert.uniforms.clippingSphere.value.set(0, 0, 0, sphereRadius.value * inside);
...
CSS
body {
overflow: hidden;
margin: 0;
}
#circle {
position: absolute;
text-align: center;
width: 60px;
height: 60px;
-webkit-border-radius: 30px;
-moz-border-radius: 30px;
border-radius: 30px;
background: rgba(0, 128, 128, .5);
font-size: 50px;
font-family: Times New Roman;
color: rgba(0, 165, 255, .75);
cursor: pointer;
}
.noselect {
-webkit-touch-callout: none;
/* iOS Safari */
-webkit-user-select: none;
/* Safari */
-khtml-user-select: none;
/* Konqueror HTML */
-moz-user-select: none;
/* Firefox */
-ms-user-select: none;
/* Internet Explorer/Edge */
user-select: none;
/* Non-prefixed version, currently
supported by Chrome and Opera */
}
/* unvisited link */
a:link {
color: orange;
}
/* visited link */
a:visited {
color: orange;
}
/* mouse over link */
a:hover {
color: orange;
}
/* selected link */
a:active {
color: orange;
}
JavaScript
var hide = true;
circle.addEventListener("click", function() {
if (hide) {
circle.style.background = "#20869f";
circle.style.color = "aqua";
info.style.width = "640px";
info.style.height = "214px";
} else {
circle.style.background = "rgba(0, 128, 128, .5)";
circle.style.color = "rgba(0, 165, 255, .5)";
info.style.width = "62px";
info.style.height = "62px";
}
hide = !hide;
}, false);
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(1, 1.5, 8).setLength(55);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setClearColor(0x779999);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.target.set(0, -10, 0);
controls.update();
controls.enablePan = false;
controls.maxDistance = 80;
controls.maxPolarAngle = THREE.Math.degToRad(95);
var light = new THREE.DirectionalLight(0xffffff, 0.5);
light.position.set(10, 5, 10);
scene.add(light);
var light2 = new THREE.DirectionalLight(0xffffff, 0.5);
light2.position.set(10, 5, -10);
scene.add(light2);
scene.add(new THREE.AmbientLight(0xffffff, 0.6));
//scene.add(new THREE.GridHelper(50, 10));
var r = "https://threejs.org/examples/textures/cube/Bridge2/";
var urls = [r + "posx.jpg", r + "negx.jpg",
r + "posy.jpg", r + "negy.jpg",
r + "posz.jpg", r + "negz.jpg"
];
textureCube = new THREE.CubeTextureLoader().load(urls);
textureCube.format = THREE.RGBFormat;
textureCube.mapping = THREE.CubeReflectionMapping;
scene.add(new THREE.Mesh(new THREE.SphereGeometry(20.1, 64, 32), new THREE.MeshBasicMaterial({
color: "white",
transparent: true,
opacity: 0.075,
envMap: textureCube
})));
// sea
var seaGeom = new THREE.PlaneGeometry(50, 50, 15, 15);
seaGeom.rotateX(-Math.PI * 0.5);
seaGeom.translate(0, -2.5, 0);
seaGeom.vertices.forEach(v => {
...