-
-
-
-
-
-
-
-
-
-
+
+
-
-
+
+ }
+
+ function validateEmail(email) {
+ const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
+ return re.test(String(email).toLowerCase());
+ }
+
+ function selectAvatar(avatarId) {
+ // Store the selected avatar or perform any action
+ console.log('Selected avatar:', avatarId);
+ }
+
+ function bet(option) {
+ // Perform the betting action
+ console.log('Bet on:', option);
+ }
+
+ document.addEventListener('DOMContentLoaded', () => {
+ startBallAnimation();
+ preload();
+ });
+
+ function startBallAnimation() {
+ const ball = document.createElement('div');
+ ball.className = 'ball';
+ document.body.appendChild(ball);
+
+ let posX = Math.random() * (window.innerWidth - 100);
+ let posY = Math.random() * (window.innerHeight - 100);
+ let velX = (Math.random() * 20) - 10; // Increased speed
+ let velY = (Math.random() * 30) - 15; // Increased speed for higher bounce
+ const ballSize = 100;
+ const gravity = 0.5; // Increased gravity
+ const colors = Array.from({length: 40}, (_, i) => `hsl(${i * 9}, 100%, 50%)`);
+ let colorIndex = 0;
+
+ function createFragment(x, y) {
+ const fragment = document.createElement('div');
+ fragment.className = 'fragment';
+ fragment.style.left = `${x}px`;
+ fragment.style.top = `${y}px`;
+ fragment.style.background = ball.style.background;
+ document.body.appendChild(fragment);
+
+ const fragmentVelX = (Math.random() * 20) - 10;
+ const fragmentVelY = (Math.random() * 20) - 10;
+ const fragmentLife = Math.random() * 1000 + 500; // random lifespan between 500ms and 1500ms
+
+ function moveFragment() {
+ x += fragmentVelX;
+ y += fragmentVelY;
+ fragment.style.transform = `translate(${x}px, ${y}px)`;
+ if (fragmentLife > 0) {
+ requestAnimationFrame(moveFragment);
+ } else {
+ fragment.remove();
+ }
+ }
+ moveFragment();
+ }
+
+ function changeColor() {
+ colorIndex = (colorIndex + 1) % colors.length;
+ ball.style.background = colors[colorIndex];
+ }
+
+ function moveBall() {
+ posX += velX;
+ posY += velY;
+ velY += gravity;
+
+ if (posX + ballSize > window.innerWidth) {
+ posX = window.innerWidth - ballSize;
+ velX *= -1;
+ changeColor();
+ for (let i = 0; i < 5; i++) {
+ createFragment(posX + ballSize / 2, posY + ballSize / 2);
+ }
+ } else if (posX < 0) {
+ posX = 0;
+ velX *= -1;
+ changeColor();
+ for (let i = 0; i < 5; i++) {
+ createFragment(posX + ballSize / 2, posY + ballSize / 2);
+ }
+ }
+
+ if (posY + ballSize > window.innerHeight) {
+ posY = window.innerHeight - ballSize;
+ velY *= -1.1; // simulate bounce with increased height
+ changeColor();
+ for (let i = 0; i < 5; i++) {
+ createFragment(posX + ballSize / 2, posY + ballSize / 2);
+ }
+ } else if (posY < 0) {
+ posY = 0;
+ velY *= -0.9;
+ changeColor();
+ for (let i = 0; i < 5; i++) {
+ createFragment(posX + ballSize / 2, posY + ballSize / 2);
+ }
+ }
+
+ ball.style.transform = `translate(${posX}px, ${posY}px)`;
+ requestAnimationFrame(moveBall);
+ }
+
+ moveBall();
+ }
+
+ const preload = () => {
+
+ let manager = new THREE.LoadingManager();
+ manager.onLoad = function() {
+ const environment = new Environment( typo, particle );
+ }
+
+ var typo = null;
+ const loader = new THREE.FontLoader( manager );
+ const font = loader.load('https://res.cloudinary.com/dydre7amr/raw/upload/v1612950355/font_zsd4dr.json', function ( font ) { typo = font; });
+ const particle = new THREE.TextureLoader( manager ).load( 'https://res.cloudinary.com/dfvtkoboz/image/upload/v1605013866/particle_a64uzf.png');
+
+ }
+
+ class Environment {
+
+ constructor( font, particle ){
+
+ this.font = font;
+ this.particle = particle;
+ this.container = document.querySelector( '#magic' );
+ this.scene = new THREE.Scene();
+ this.createCamera();
+ this.createRenderer();
+ this.setup()
+ this.bindEvents();
+ }
+
+ bindEvents(){
+
+ window.addEventListener( 'resize', this.onWindowResize.bind( this ));
+
+ }
+
+ setup(){
+
+ this.createParticles = new CreateParticles( this.scene, this.font, this.particle, this.camera, this.renderer );
+ }
+
+ render() {
+
+ this.createParticles.render()
+ this.renderer.render( this.scene, this.camera )
+ }
+
+ createCamera() {
+
+ this.camera = new THREE.PerspectiveCamera( 65, this.container.clientWidth / this.container.clientHeight, 1, 10000 );
+ this.camera.position.set( 0,0, 100 );
+
+ }
+
+ createRenderer() {
+
+ this.renderer = new THREE.WebGLRenderer();
+ this.renderer.setSize( this.container.clientWidth, this.container.clientHeight );
+
+ this.renderer.setPixelRatio( Math.min( window.devicePixelRatio, 2));
+
+ this.renderer.outputEncoding = THREE.sRGBEncoding;
+ this.container.appendChild( this.renderer.domElement );
+
+ this.renderer.setAnimationLoop(() => { this.render() })
+
+ }
+
+ onWindowResize(){
+
+ this.camera.aspect = this.container.clientWidth / this.container.clientHeight;
+ this.camera.updateProjectionMatrix();
+ this.renderer.setSize( this.container.clientWidth, this.container.clientHeight );
+
+ }
+ }
+
+ class CreateParticles {
+
+ constructor( scene, font, particleImg, camera, renderer ) {
+
+ this.scene = scene;
+ this.font = font;
+ this.particleImg = particleImg;
+ this.camera = camera;
+ this.renderer = renderer;
+
+ this.raycaster = new THREE.Raycaster();
+ this.mouse = new THREE.Vector2(-200, 200);
+
+ this.colorChange = new THREE.Color();
+
+ this.buttom = false;
+
+ this.data = {
+
+ text: 'FUTURE\nIS NOW',
+ amount: 1500,
+ particleSize: 1,
+ particleColor: 0xffffff,
+ textSize: 16,
+ area: 250,
+ ease: .05,
+ }
+
+ this.setup();
+ this.bindEvents();
+
+ }
+
+
+ setup(){
+
+ const geometry = new THREE.PlaneGeometry( this.visibleWidthAtZDepth( 100, this.camera ), this.visibleHeightAtZDepth( 100, this.camera ));
+ const material = new THREE.MeshBasicMaterial( { color: 0x00ff00, transparent: true } );
+ this.planeArea = new THREE.Mesh( geometry, material );
+ this.planeArea.visible = false;
+ this.createText();
+
+ }
+
+ bindEvents() {
+
+ document.addEventListener( 'mousedown', this.onMouseDown.bind( this ));
+ document.addEventListener( 'mousemove', this.onMouseMove.bind( this ));
+ document.addEventListener( 'mouseup', this.onMouseUp.bind( this ));
+
+ }
+
+ onMouseDown(){
+
+ this.mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
+ this.mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
+
+ const vector = new THREE.Vector3( this.mouse.x, this.mouse.y, 0.5);
+ vector.unproject( this.camera );
+ const dir = vector.sub( this.camera.position ).normalize();
+ const distance = - this.camera.position.z / dir.z;
+ this.currenPosition = this.camera.position.clone().add( dir.multiplyScalar( distance ) );
+
+ const pos = this.particles.geometry.attributes.position;
+ this.buttom = true;
+ this.data.ease = .01;
+
+ }
+
+ onMouseUp(){
+
+ this.buttom = false;
+ this.data.ease = .05;
+ }
+
+ onMouseMove( ) {
+
+ this.mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
+ this.mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
+
+ }
+
+ render( level ){
+
+ const time = ((.001 * performance.now())%12)/12;
+ const zigzagTime = (1 + (Math.sin( time * 2 * Math.PI )))/6;
+
+ this.raycaster.setFromCamera( this.mouse, this.camera );
+
+ const intersects = this.raycaster.intersectObject( this.planeArea );
+
+ if ( intersects.length > 0 ) {
+
+ const pos = this.particles.geometry.attributes.position;
+ const copy = this.geometryCopy.attributes.position;
+ const coulors = this.particles.geometry.attributes.customColor;
+ const size = this.particles.geometry.attributes.size;
+
+ const mx = intersects[ 0 ].point.x;
+ const my = intersects[ 0 ].point.y;
+ const mz = intersects[ 0 ].point.z;
+
+ for ( var i = 0, l = pos.count; i < l; i++) {
+
+ const initX = copy.getX(i);
+ const initY = copy.getY(i);
+ const initZ = copy.getZ(i);
+
+ let px = pos.getX(i);
+ let py = pos.getY(i);
+ let pz = pos.getZ(i);
+
+ this.colorChange.setHSL( .5, 1 , 1 )
+ coulors.setXYZ( i, this.colorChange.r, this.colorChange.g, this.colorChange.b )
+ coulors.needsUpdate = true;
+
+ size.array[ i ] = this.data.particleSize;
+ size.needsUpdate = true;
+
+ let dx = mx - px;
+ let dy = my - py;
+ const dz = mz - pz;
+
+ const mouseDistance = this.distance( mx, my, px, py )
+ let d = ( dx = mx - px ) * dx + ( dy = my - py ) * dy;
+ const f = - this.data.area/d;
+
+ if( this.buttom ){
+
+ const t = Math.atan2( dy, dx );
+ px -= f * Math.cos( t );
+ py -= f * Math.sin( t );
+
+ this.colorChange.setHSL( .5 + zigzagTime, 1.0 , .5 )
+ coulors.setXYZ( i, this.colorChange.r, this.colorChange.g, this.colorChange.b )
+ coulors.needsUpdate = true;
+
+ if ((px > (initX + 70)) || ( px < (initX - 70)) || (py > (initY + 70) || ( py < (initY - 70)))){
+
+ this.colorChange.setHSL( .15, 1.0 , .5 )
+ coulors.setXYZ( i, this.colorChange.r, this.colorChange.g, this.colorChange.b )
+ coulors.needsUpdate = true;
+
+ }
+
+ }else{
+
+ if( mouseDistance < this.data.area ){
+
+ if(i%5==0){
+
+ const t = Math.atan2( dy, dx );
+ px -= .03 * Math.cos( t );
+ py -= .03 * Math.sin( t );
+
+ this.colorChange.setHSL( .15 , 1.0 , .5 )
+ coulors.setXYZ( i, this.colorChange.r, this.colorChange.g, this.colorChange.b )
+ coulors.needsUpdate = true;
+
+ size.array[ i ] = this.data.particleSize /1.2;
+ size.needsUpdate = true;
+
+ }else{
+
+ const t = Math.atan2( dy, dx );
+ px += f * Math.cos( t );
+ py += f * Math.sin( t );
+
+ pos.setXYZ( i, px, py, pz );
+ pos.needsUpdate = true;
+
+ size.array[ i ] = this.data.particleSize * 1.3 ;
+ size.needsUpdate = true;
+ }
+
+ if ((px > (initX + 10)) || ( px < (initX - 10)) || (py > (initY + 10) || ( py < (initY - 10)))){
+
+ this.colorChange.setHSL( .15, 1.0 , .5 )
+ coulors.setXYZ( i, this.colorChange.r, this.colorChange.g, this.colorChange.b )
+ coulors.needsUpdate = true;
+
+ size.array[ i ] = this.data.particleSize /1.8;
+ size.needsUpdate = true;
+
+ }
+ }
+
+ }
+
+ px += ( initX - px ) * this.data.ease;
+ py += ( initY - py ) * this.data.ease;
+ pz += ( initZ - pz ) * this.data.ease;
+
+ pos.setXYZ( i, px, py, pz );
+ pos.needsUpdate = true;
+
+ }
+ }
+ }
+
+ createText(){
+
+ let thePoints = [];
+
+ let shapes = this.font.generateShapes( this.data.text , this.data.textSize );
+ let geometry = new THREE.ShapeGeometry( shapes );
+ geometry.computeBoundingBox();
+
+ const xMid = - 0.5 * ( geometry.boundingBox.max.x - geometry.boundingBox.min.x );
+ const yMid = (geometry.boundingBox.max.y - geometry.boundingBox.min.y)/2.85;
+
+ geometry.center();
+
+ let holeShapes = [];
+
+ for ( let q = 0; q < shapes.length; q ++ ) {
+
+ let shape = shapes[ q ];
+
+ if ( shape.holes && shape.holes.length > 0 ) {
+
+ for ( let j = 0; j < shape.holes.length; j ++ ) {
+
+ let hole = shape.holes[ j ];
+ holeShapes.push( hole );
+ }
+ }
+
+ }
+ shapes.push.apply( shapes, holeShapes );
+
+ let colors = [];
+ let sizes = [];
+
+ for ( let x = 0; x < shapes.length; x ++ ) {
+
+ let shape = shapes[ x ];
+
+ const amountPoints = ( shape.type == 'Path') ? this.data.amount/2 : this.data.amount;
+
+ let points = shape.getSpacedPoints( amountPoints ) ;
+
+ points.forEach( ( element, z ) => {
+
+ const a = new THREE.Vector3( element.x, element.y, 0 );
+ thePoints.push( a );
+ colors.push( this.colorChange.r, this.colorChange.g, this.colorChange.b);
+ sizes.push( 1 )
+
+ });
+ }
+
+ let geoParticles = new THREE.BufferGeometry().setFromPoints( thePoints );
+ geoParticles.translate( xMid, yMid, 0 );
+
+ geoParticles.setAttribute( 'customColor', new THREE.Float32BufferAttribute( colors, 3 ) );
+ geoParticles.setAttribute( 'size', new THREE.Float32BufferAttribute( sizes, 1) );
+
+ const material = new THREE.ShaderMaterial( {
+
+ uniforms: {
+ color: { value: new THREE.Color( 0xffffff ) },
+ pointTexture: { value: this.particleImg }
+ },
+ vertexShader: document.getElementById( 'vertexshader' ).textContent,
+ fragmentShader: document.getElementById( 'fragmentshader' ).textContent,
+
+ blending: THREE.AdditiveBlending,
+ depthTest: false,
+ transparent: true,
+ } );
+
+ this.particles = new THREE.Points( geoParticles, material );
+ this.scene.add( this.particles );
+
+ this.geometryCopy = new THREE.BufferGeometry();
+ this.geometryCopy.copy( this.particles.geometry );
+
+ }
+
+ visibleHeightAtZDepth ( depth, camera ) {
+
+ const cameraOffset = camera.position.z;
+ if ( depth < cameraOffset ) depth -= cameraOffset;
+ else depth += cameraOffset;
+
+ const vFOV = camera.fov * Math.PI / 180;
+
+ return 2 * Math.tan( vFOV / 2 ) * Math.abs( depth );
+ }
+
+ visibleWidthAtZDepth( depth, camera ) {
+
+ const height = this.visibleHeightAtZDepth( depth, camera );
+ return height * camera.aspect;
+
+ }
+
+ distance (x1, y1, x2, y2){
+
+ return Math.sqrt(Math.pow((x1 - x2), 2) + Math.pow((y1 - y2), 2));
+ }
+ }
+