/
RaskolnickOFF
/
3D
Обзор
Документация
Войти
/
RaskolnickOFF
/
3D
Код
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
viewer.html
203 строки
7 KB
RaskolnickOFF
added heartbeat
11 июн 2026, 03:33
11 июн 2026, 03:33
92192be
Код
Авторство
О чём код?
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Survival 2.5D — Object Viewer</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { background: #000; overflow: hidden; } canvas { display: none; } /* pulse */ body { background-color: #212121; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; } .pulse-container { position: relative; width: 200px; height: 100px; } /* Общие стили для SVG-линий */ .pulse-base, .pulse-glow { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } .pulse-base polyline, .pulse-glow polyline { fill: none; stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; } /* Статичный серый фон */ .pulse-base polyline { stroke: #444; } /* Анимированная светящаяся линия */ .pulse-glow polyline { stroke: #fff; /* Эффект неонового свечения */ filter: drop-shadow(0 0 3px rgba(255, 255, 255, 0.8)); /* Длина пунктира (задаем длину всей линии и отступа) */ stroke-dasharray: 240; /* Запускаем бесконечную анимацию смещения линии */ animation: pulse-run 1s steps(200, end) infinite; } svg.pulse-glow polyline { stroke-linejoin: round; /* Сглаживает острые углы */ stroke-linecap: round; /* Сглаживает концы линии */ } @keyframes pulse-run { 0% { stroke-dashoffset: 240; /* Линия полностью скрыта в начале */ } 100% { stroke-dashoffset: -240; /* Линия полностью пробегает до конца */ } } </style> </head> <body> <!-- <script type="importmap"> { "imports": { "three": "./js/dependencies/three.webgpu.min.js", "three/webgpu": "./js/dependencies/three.webgpu.min.js", "three/tsl": "./js/dependencies/three.tsl.min.js", "three/addons/": "./js/dependencies/addons/", "SETTINGS": "./js/source/settings/Settings.js", "FLORA": "./js/source/scene/flora/FloraGenerator.js" } } </script> <script type="module"> import * as THREE from 'three'; import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; // import { createBerryBush } from './js/source/scene/BerryBush.js'; import SETTINGS from 'SETTINGS'; import { FloraGenerator } from 'FLORA'; // --- Scene setup --- const scene = new THREE.Scene(); scene.background = new THREE.Color('#1a1a2e'); // --- Camera --- const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 100); camera.position.set(2, 1.5, 3); camera.lookAt(0, 0.4, 0); // --- Renderer --- const renderer = new THREE.WebGPURenderer(); renderer.setPixelRatio(window.devicePixelRatio); renderer.setSize(window.innerWidth, window.innerHeight); renderer.toneMapping = THREE.ACESFilmicToneMapping; renderer.toneMappingExposure = 1.0; document.body.appendChild(renderer.domElement); // --- Controls --- const controls = new OrbitControls(camera, renderer.domElement); controls.target.set(0, 0.4, 0); controls.enableDamping = true; controls.dampingFactor = 0.1; // --- Lights --- const sun = new THREE.DirectionalLight('#ffffff', 3); sun.position.set(5, 10, 5); scene.add(sun); const ambient = new THREE.AmbientLight('#4466ff', 0.6); scene.add(ambient); // --- Ground --- const groundGeo = new THREE.PlaneGeometry(10, 10); const groundMat = new THREE.MeshStandardMaterial({ color: '#3a5a2a', roughness: 0.9 }); const ground = new THREE.Mesh(groundGeo, groundMat); ground.rotation.x = -Math.PI / 2; ground.receiveShadow = true; scene.add(ground); // --- Grid helper --- const grid = new THREE.GridHelper(10, 20, '#444444', '#222222'); scene.add(grid); // Создаём флору const flora = new FloraGenerator({ stump: { sides: 6, roots: { count: 4 } }, trunk: { height: 1.8 }, animation: { fallDelay: 3, // упадёт через 3 секунды fallDuration: 1.5, fallDirection: Math.PI / 4 // падает по диагонали } }); scene.add(flora.group); // --- Resize --- window.addEventListener('resize', () => { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); }); // --- Loop --- async function init() { await renderer.init(); const startTime = performance.now() / 1000; renderer.setAnimationLoop(() => { const time = performance.now() / 1000 - startTime; flora.update(time); // обновляем анимацию controls.update(); renderer.render(scene, camera); }); } init(); </script> --> <div class="pulse-container"> <!-- Фоновая серая линия --> <svg class="pulse-base" viewBox="0 0 200 100" xmlns="http://www.w3.org/2000/svg"> <polyline points="0,50 200,50"/> </svg> <!-- Анимированная белая линия пульса --> <svg class="pulse-glow" viewBox="0 0 200 100" xmlns="http://www.w3.org/2000/svg"> <!-- animation: 1s --> <polyline points="0,50 65,50 70,40 75,50 82,50 86,60 92,20 98,80 103,50 112,50 120,43 130,53 138,50 200,50"/> <!-- animation: 0.52s --> <!-- <polyline points="0,50 25,50 29,42 33,50 38,50 41,58 46,25 51,75 54,50 60,50 65,45 71,52 76,50 110,50 114,42 118,50 123,50 126,58 131,25 136,75 139,50 145,50 150,45 156,52 161,50 200,50"/> --> <!-- animation: 0.3s --> <!-- <polyline points="0,50 15,30 25,70 35,40 45,60 52,20 60,85 70,35 80,55 92,15 100,75 110,40 120,65 128,30 138,50 148,35 155,70 165,45 175,55 183,25 190,65 200,50"/> --> </svg> </div> </body> </html>