From ef473b313eb4c84fe5c783c487e329133b3f6f7b Mon Sep 17 00:00:00 2001 From: Rahul Gupta Date: Thu, 31 Oct 2024 11:01:51 -0700 Subject: [PATCH 01/15] wip --- package-lock.json | 31 +++++++++++++++++++++++++++- package.json | 3 ++- src/components/screentock.js | 14 ------------- src/json-utils_1.1.js | 40 ------------------------------------ src/store.js | 10 +++++++++ 5 files changed, 42 insertions(+), 56 deletions(-) create mode 100644 src/store.js diff --git a/package-lock.json b/package-lock.json index 0ce76434..4a9f1241 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,7 +33,8 @@ "react-select": "^5.4.0", "stripe": "^15.8.0", "three": "0.145.0", - "uuid": "^9.0.0" + "uuid": "^9.0.0", + "zustand": "^5.0.1" }, "devDependencies": { "@babel/eslint-parser": "^7.24.5", @@ -30861,6 +30862,34 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zustand": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.1.tgz", + "integrity": "sha512-pRET7Lao2z+n5R/HduXMio35TncTlSW68WsYBq2Lg1ASspsNGjpwLAsij3RpouyV6+kHMwwwzP0bZPD70/Jx/w==", + "engines": { + "node": ">=12.20.0" + }, + "peerDependencies": { + "@types/react": ">=18.0.0", + "immer": ">=9.0.6", + "react": ">=18.0.0", + "use-sync-external-store": ">=1.2.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + }, + "use-sync-external-store": { + "optional": true + } + } } } } diff --git a/package.json b/package.json index cec398ec..e2463e98 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,8 @@ "react-select": "^5.4.0", "stripe": "^15.8.0", "three": "0.145.0", - "uuid": "^9.0.0" + "uuid": "^9.0.0", + "zustand": "^5.0.1" }, "devDependencies": { "@babel/eslint-parser": "^7.24.5", diff --git a/src/components/screentock.js b/src/components/screentock.js index 2de07530..fa158b95 100644 --- a/src/components/screentock.js +++ b/src/components/screentock.js @@ -1,19 +1,5 @@ /* AFRAME */ -// function buttonScreenshotTock() { -// AFRAME.scenes[0].setAttribute('screentock', 'type', 'jpg'); -// AFRAME.scenes[0].setAttribute('screentock', 'takeScreenshot', true); -// } -// function buttonScreenshotTockPNG() { -// AFRAME.scenes[0].setAttribute('screentock', 'type', 'png'); -// AFRAME.scenes[0].setAttribute('screentock', 'takeScreenshot', true); -// } -// function buttonCaptureImage() { -// AFRAME.scenes[0].setAttribute('screentock', 'type', 'img'); -// AFRAME.scenes[0].setAttribute('screentock', 'imgElementSelector', '#captureImg'); -// AFRAME.scenes[0].setAttribute('screentock', 'takeScreenshot', true); -// } - AFRAME.registerComponent('screentock', { schema: { takeScreenshot: { type: 'boolean', default: false }, diff --git a/src/json-utils_1.1.js b/src/json-utils_1.1.js index 7ce33ade..17670d05 100644 --- a/src/json-utils_1.1.js +++ b/src/json-utils_1.1.js @@ -482,46 +482,6 @@ AFRAME.registerComponent('metadata', { } }); -AFRAME.registerComponent('scene-title', { - schema: { - titleText: { default: '' } - }, - init: function () { - this.titleElement = undefined; - this.el.addEventListener('newTitle', (evt) => { - this.el.setAttribute('scene-title', 'titleText', evt.detail.sceneTitle); - }); - }, - createTitleElement: function (titleText) { - const titleDiv = (this.titleElement = document.createElement('div')); - const newContent = document.createTextNode(titleText); - titleDiv.setAttribute('id', 'sceneTitle'); - titleDiv.appendChild(newContent); - document.body.append(titleDiv); - }, - updateTitleText: function (titleText) { - this.titleElement.textContent = titleText; - }, - update: function (oldData) { - // If `oldData` is empty, then this means we're in the initialization process. - // No need to update. - if (Object.keys(oldData).length === 0) { - return; - } - - const titleText = this.data.titleText; - const titleElement = this.titleElement; - - if (titleText !== oldData.titleText) { - if (!titleElement) { - this.createTitleElement(titleText); - } else { - this.updateTitleText(titleText); - } - } - } -}); - AFRAME.registerComponent('set-loader-from-hash', { schema: { defaultURL: { type: 'string' } diff --git a/src/store.js b/src/store.js new file mode 100644 index 00000000..59836937 --- /dev/null +++ b/src/store.js @@ -0,0 +1,10 @@ +import { create } from 'zustand'; + +const useStore = create((set) => ({ + sceneId: null, + setSceneId: (newSceneId) => set({ sceneId: newSceneId }), + authorId: null, + setAuthorId: (newAuthorId) => set({ authorId: newAuthorId }) +})); + +export default useStore; From ca8d719affe17f453c6155a0f18cbc15cb0a3704 Mon Sep 17 00:00:00 2001 From: Rahul Gupta Date: Thu, 7 Nov 2024 15:39:34 -0800 Subject: [PATCH 02/15] consolidate scripts --- index.html | 24 +----------- src/editor/components/Main.js | 3 +- .../SceneEditTitle.component.jsx | 39 +++++++++---------- src/editor/components/scenegraph/Toolbar.js | 1 - src/editor/index.js | 10 ++--- src/index.js | 27 ++++--------- src/store.js | 34 ++++++++++++---- webpack.config.js | 4 -- 8 files changed, 60 insertions(+), 82 deletions(-) diff --git a/index.html b/index.html index 3ef15ce4..7c6480de 100644 --- a/index.html +++ b/index.html @@ -76,7 +76,7 @@ @@ -129,27 +129,5 @@ }); }); - - \ No newline at end of file diff --git a/src/editor/components/Main.js b/src/editor/components/Main.js index b5a889af..d2d92139 100644 --- a/src/editor/components/Main.js +++ b/src/editor/components/Main.js @@ -237,7 +237,6 @@ export default class Main extends Component { render() { const scene = this.state.sceneEl; const isEditor = !!this.state.inspectorEnabled; - const sceneData = AFRAME.scenes[0].getAttribute('metadata', 'sceneTitle'); return (
@@ -315,7 +314,7 @@ export default class Main extends Component { )} {this.state.inspectorEnabled && (
- +
)} {this.state.inspectorEnabled && ( diff --git a/src/editor/components/components/SceneEditTitle/SceneEditTitle.component.jsx b/src/editor/components/components/SceneEditTitle/SceneEditTitle.component.jsx index 131416a1..d85e7182 100644 --- a/src/editor/components/components/SceneEditTitle/SceneEditTitle.component.jsx +++ b/src/editor/components/components/SceneEditTitle/SceneEditTitle.component.jsx @@ -1,25 +1,24 @@ -import { useEffect, useState } from 'react'; import styles from './SceneEditTitle.module.scss'; import { useAuthContext } from '../../../contexts/index.js'; import { updateSceneIdAndTitle } from '../../../api/scene'; +import useStore from '../../../../store.js'; const SceneEditTitle = ({ sceneData }) => { - const [title, setTitle] = useState(sceneData?.sceneTitle); + const title = useStore((state) => state.sceneTitle); + const setTitle = useStore((state) => state.setSceneTitle); const { currentUser } = useAuthContext(); - const sceneId = STREET.utils.getCurrentSceneId(); + // useEffect(() => { + // if (sceneData.sceneId === sceneId) { + // setTitle(sceneData.sceneTitle); + // } + // }, [sceneData?.sceneTitle, sceneData?.sceneId, sceneId]); - useEffect(() => { - if (sceneData.sceneId === sceneId) { - setTitle(sceneData.sceneTitle); - } - }, [sceneData?.sceneTitle, sceneData?.sceneId, sceneId]); - - useEffect(() => { - AFRAME.scenes[0].addEventListener('newTitle', (event) => { - setTitle(event.detail.sceneTitle ?? ''); - }); - }, []); + // useEffect(() => { + // AFRAME.scenes[0].addEventListener('newTitle', (event) => { + // setTitle(event.detail.sceneTitle ?? ''); + // }); + // }, []); const handleEditClick = () => { const newTitle = prompt('Edit the title:', title); @@ -50,13 +49,11 @@ const SceneEditTitle = ({ sceneData }) => { return (
- { -
-

- {title || 'Untitled'} -

-
- } +
+

+ {title || 'Untitled'} +

+
); }; diff --git a/src/editor/components/scenegraph/Toolbar.js b/src/editor/components/scenegraph/Toolbar.js index bb3b3478..c690ff9f 100644 --- a/src/editor/components/scenegraph/Toolbar.js +++ b/src/editor/components/scenegraph/Toolbar.js @@ -42,7 +42,6 @@ export default class Toolbar extends Component { document.addEventListener('click', this.handleClickOutsideSave); Events.on('historychanged', (cmd) => { if (cmd) { - console.log('historychanged', cmd); // Debounce the cloudSaveHandler call this.debouncedCloudSaveHandler(); } diff --git a/src/editor/index.js b/src/editor/index.js index a368689b..f5d6b5b5 100644 --- a/src/editor/index.js +++ b/src/editor/index.js @@ -10,12 +10,11 @@ import { Config } from './lib/config'; import { History } from './lib/history'; import { Shortcuts } from './lib/shortcuts'; import { Viewport } from './lib/viewport'; -import { firebaseConfig } from './services/firebase.js'; import './style/index.scss'; -import ReactGA from 'react-ga4'; import posthog from 'posthog-js'; import { commandsByType } from './lib/commands/index.js'; +console.log('editor'); function Inspector() { this.assetsLoader = new AssetsLoader(); this.exporters = { gltf: new GLTFExporter() }; @@ -24,7 +23,7 @@ function Inspector() { this.isFirstOpen = true; this.modules = {}; this.opened = false; - + console.log('Inspector'); // Wait for stuff. const doInit = () => { if (!AFRAME.scenes.length) { @@ -69,9 +68,11 @@ Inspector.prototype = { Shortcuts.init(this); this.initEvents(); + console.log('initUI'); this.selected = null; // Init React. + const div = document.createElement('div'); div.id = 'aframeInspector'; div.setAttribute('data-aframe-inspector', 'app'); @@ -358,9 +359,8 @@ Inspector.prototype = { } }; -ReactGA.initialize(firebaseConfig.measurementId); const inspector = (AFRAME.INSPECTOR = new Inspector()); - +console.log('inspector', inspector); posthog.init('phc_Yclai3qykyFi8AEFOrZsh6aS78SSooLzpDz9wQ9YAH9', { api_host: 'https://us.i.posthog.com', person_profiles: 'identified_only' // or 'always' to create profiles for anonymous users as well diff --git a/src/index.js b/src/index.js index de43a4a9..9e003511 100644 --- a/src/index.js +++ b/src/index.js @@ -1,6 +1,7 @@ /* global AFRAME, XMLHttpRequest, VERSION */ import 'aframe-cursor-teleport-component'; import 'aframe-extras/controls/index.js'; +import useStore from './store.js'; var streetmixParsers = require('./aframe-streetmix-parsers'); var streetmixUtils = require('./tested/streetmix-utils'); require('./json-utils_1.1.js'); @@ -20,6 +21,10 @@ require('./components/street-geo.js'); require('./components/street-environment.js'); require('./components/intersection.js'); require('./components/obb-clipping.js'); +require('./editor/index.js'); +// import { inspector } from './editor/index.js'; + +const state = useStore.getState(); if (typeof VERSION !== 'undefined') { console.log(`3DStreet Version: ${VERSION}`); @@ -192,30 +197,14 @@ AFRAME.registerComponent('streetmix-loader', { const streetmixSegments = streetData.segments; const streetmixName = streetmixResponseObject.name; - console.log('streetmixName', streetmixName); el.setAttribute('streetmix-loader', 'name', streetmixName); - - let currentSceneTitle; - if (AFRAME.scenes[0] && AFRAME.scenes[0].getAttribute('metadata')) { - currentSceneTitle = - AFRAME.scenes[0].getAttribute('metadata').sceneTitle; - } - if (!currentSceneTitle) { - // only set title from streetmix if none exists - AFRAME.scenes[0].setAttribute( - 'metadata', - 'sceneTitle', - streetmixName - ); - console.log( - 'therefore setting metadata sceneTitle as streetmixName', - streetmixName - ); - } + // console.log('useStore', useStore); + state.setSceneTitle(streetmixName); el.setAttribute('data-layer-name', 'Streetmix • ' + streetmixName); + console.log('Call stack:', new Error().stack); if (data.showBuildings) { el.setAttribute('street', 'right', streetData.rightBuildingVariant); el.setAttribute('street', 'left', streetData.leftBuildingVariant); diff --git a/src/store.js b/src/store.js index 59836937..8d41bd38 100644 --- a/src/store.js +++ b/src/store.js @@ -1,10 +1,30 @@ import { create } from 'zustand'; +import { devtools } from 'zustand/middleware'; -const useStore = create((set) => ({ - sceneId: null, - setSceneId: (newSceneId) => set({ sceneId: newSceneId }), - authorId: null, - setAuthorId: (newAuthorId) => set({ authorId: newAuthorId }) -})); +let store; -export default useStore; +const initializeStore = () => { + console.log('Store Call Stack:', new Error().stack); + return create( + devtools( + (set) => ({ + sceneId: null, + setSceneId: (newSceneId) => set({ sceneId: newSceneId }), + sceneTitle: null, + setSceneTitle: (newSceneTitle) => set({ sceneTitle: newSceneTitle }), + authorId: null, + setAuthorId: (newAuthorId) => set({ authorId: newAuthorId }) + }), + { name: 'MyZustandStore' } + ) + ); +}; + +const getStore = () => { + if (!store) { + store = initializeStore(); + } + return store; +}; + +export default getStore(); diff --git a/webpack.config.js b/webpack.config.js index 63eb4bc9..bc50c66c 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -17,10 +17,6 @@ module.exports = { }, devtool: 'source-map', entry: { - editor: { - import: ['./src/editor/index.js'], - filename: '3dstreet-editor.js' - }, core: { import: './src/index.js', filename: 'aframe-street-component.js' } }, output: { From 4bea55a7652ca9d686b18a57df5bb47741c74622 Mon Sep 17 00:00:00 2001 From: Rahul Gupta Date: Thu, 7 Nov 2024 15:45:29 -0800 Subject: [PATCH 03/15] more work --- src/components/screentock.js | 3 +- src/editor/components/scenegraph/Toolbar.js | 3 +- src/index.js | 1 - src/store.js | 40 ++++++++------------- 4 files changed, 18 insertions(+), 29 deletions(-) diff --git a/src/components/screentock.js b/src/components/screentock.js index fa158b95..ded69ace 100644 --- a/src/components/screentock.js +++ b/src/components/screentock.js @@ -1,4 +1,5 @@ /* AFRAME */ +import useStore from '../store'; AFRAME.registerComponent('screentock', { schema: { @@ -48,7 +49,7 @@ AFRAME.registerComponent('screentock', { ctx.textAlign = 'center'; ctx.fillStyle = '#FFF'; ctx.fillText( - STREET.utils.getCurrentSceneTitle(), + useStore.getState().sceneTitle, screenWidth - screenWidth / 2, screenHeight - 43 ); diff --git a/src/editor/components/scenegraph/Toolbar.js b/src/editor/components/scenegraph/Toolbar.js index c690ff9f..fbf111ed 100644 --- a/src/editor/components/scenegraph/Toolbar.js +++ b/src/editor/components/scenegraph/Toolbar.js @@ -19,6 +19,7 @@ import posthog from 'posthog-js'; import { UndoRedo } from '../components/UndoRedo'; import debounce from 'lodash-es/debounce'; import { CameraToolbar } from '../viewport/CameraToolbar'; +import useStore from '../../../store'; // const LOCALSTORAGE_MOCAP_UI = "aframeinspectormocapuienabled"; /** @@ -129,7 +130,7 @@ export default class Toolbar extends Component { } // if there is no current user, show sign in modal let currentSceneId = STREET.utils.getCurrentSceneId(); - let currentSceneTitle = STREET.utils.getCurrentSceneTitle(); + let currentSceneTitle = useStore.getState().sceneTitle; posthog.capture('save_scene_clicked', { save_as: doSaveAs, diff --git a/src/index.js b/src/index.js index 9e003511..8e8b9ca2 100644 --- a/src/index.js +++ b/src/index.js @@ -204,7 +204,6 @@ AFRAME.registerComponent('streetmix-loader', { el.setAttribute('data-layer-name', 'Streetmix • ' + streetmixName); - console.log('Call stack:', new Error().stack); if (data.showBuildings) { el.setAttribute('street', 'right', streetData.rightBuildingVariant); el.setAttribute('street', 'left', streetData.leftBuildingVariant); diff --git a/src/store.js b/src/store.js index 8d41bd38..99b34022 100644 --- a/src/store.js +++ b/src/store.js @@ -1,30 +1,18 @@ import { create } from 'zustand'; import { devtools } from 'zustand/middleware'; -let store; +const useStore = create( + devtools( + (set) => ({ + sceneId: null, + setSceneId: (newSceneId) => set({ sceneId: newSceneId }), + sceneTitle: null, + setSceneTitle: (newSceneTitle) => set({ sceneTitle: newSceneTitle }), + authorId: null, + setAuthorId: (newAuthorId) => set({ authorId: newAuthorId }) + }), + { name: 'MyZustandStore' } + ) +); -const initializeStore = () => { - console.log('Store Call Stack:', new Error().stack); - return create( - devtools( - (set) => ({ - sceneId: null, - setSceneId: (newSceneId) => set({ sceneId: newSceneId }), - sceneTitle: null, - setSceneTitle: (newSceneTitle) => set({ sceneTitle: newSceneTitle }), - authorId: null, - setAuthorId: (newAuthorId) => set({ authorId: newAuthorId }) - }), - { name: 'MyZustandStore' } - ) - ); -}; - -const getStore = () => { - if (!store) { - store = initializeStore(); - } - return store; -}; - -export default getStore(); +export default useStore; From be31a3c1a48be0665ec75e052d85edb1ad23af30 Mon Sep 17 00:00:00 2001 From: Rahul Gupta Date: Thu, 7 Nov 2024 15:58:59 -0800 Subject: [PATCH 04/15] add more scene title state --- src/components/streetplan-loader.js | 2 -- .../SceneEditTitle.component.jsx | 13 ---------- .../ScenesModal/ScenesModal.component.jsx | 4 ++-- src/json-utils_1.1.js | 24 ++++--------------- src/street-utils.js | 1 - 5 files changed, 7 insertions(+), 37 deletions(-) diff --git a/src/components/streetplan-loader.js b/src/components/streetplan-loader.js index 55666234..9ee95b70 100644 --- a/src/components/streetplan-loader.js +++ b/src/components/streetplan-loader.js @@ -25,8 +25,6 @@ AFRAME.registerComponent('streetplan-loader', { // streetplan alternative name // const streetplanAltName = streetData.altName; - console.log('streetplanName', streetplanName); - let currentSceneTitle; const sceneEl = this.el.sceneEl; if (sceneEl && sceneEl.getAttribute('metadata')) { diff --git a/src/editor/components/components/SceneEditTitle/SceneEditTitle.component.jsx b/src/editor/components/components/SceneEditTitle/SceneEditTitle.component.jsx index d85e7182..9650f859 100644 --- a/src/editor/components/components/SceneEditTitle/SceneEditTitle.component.jsx +++ b/src/editor/components/components/SceneEditTitle/SceneEditTitle.component.jsx @@ -8,18 +8,6 @@ const SceneEditTitle = ({ sceneData }) => { const setTitle = useStore((state) => state.setSceneTitle); const { currentUser } = useAuthContext(); - // useEffect(() => { - // if (sceneData.sceneId === sceneId) { - // setTitle(sceneData.sceneTitle); - // } - // }, [sceneData?.sceneTitle, sceneData?.sceneId, sceneId]); - - // useEffect(() => { - // AFRAME.scenes[0].addEventListener('newTitle', (event) => { - // setTitle(event.detail.sceneTitle ?? ''); - // }); - // }, []); - const handleEditClick = () => { const newTitle = prompt('Edit the title:', title); @@ -38,7 +26,6 @@ const SceneEditTitle = ({ sceneData }) => { await updateSceneIdAndTitle(sceneData?.sceneId, newTitle); } } - AFRAME.scenes[0].setAttribute('metadata', 'sceneTitle', newTitle); AFRAME.scenes[0].setAttribute('metadata', 'sceneId', sceneData?.sceneId); STREET.notify.successMessage(`New scene title saved: ${newTitle}`); } catch (error) { diff --git a/src/editor/components/modals/ScenesModal/ScenesModal.component.jsx b/src/editor/components/modals/ScenesModal/ScenesModal.component.jsx index b21045cf..f5433a3d 100644 --- a/src/editor/components/modals/ScenesModal/ScenesModal.component.jsx +++ b/src/editor/components/modals/ScenesModal/ScenesModal.component.jsx @@ -12,7 +12,7 @@ import { getCommunityScenes, getUserScenes } from '../../../api/scene'; import { Load24Icon, Loader, Upload24Icon } from '../../../icons'; import { signIn } from '../../../api'; import posthog from 'posthog-js'; - +import useStore from '../../../../store.js'; const SCENES_PER_PAGE = 20; const tabs = [ { @@ -65,7 +65,7 @@ const ScenesModal = ({ isOpen, onClose, initialTab = 'owner', delay }) => { const sceneId = scene.id; const sceneTitle = sceneData.title; AFRAME.scenes[0].setAttribute('metadata', 'sceneId', sceneId); - AFRAME.scenes[0].setAttribute('metadata', 'sceneTitle', sceneTitle); + useStore.setState({ sceneTitle: sceneTitle }); AFRAME.scenes[0].setAttribute('metadata', 'authorId', sceneData.author); STREET.notify.successMessage('Scene loaded from 3DStreet Cloud.'); onClose(); diff --git a/src/json-utils_1.1.js b/src/json-utils_1.1.js index 17670d05..c7dc6bc9 100644 --- a/src/json-utils_1.1.js +++ b/src/json-utils_1.1.js @@ -1,9 +1,10 @@ +import useStore from './store'; + /* global AFRAME, Node */ /* version: 1.0 */ window.STREET = {}; var assetsUrl; STREET.utils = {}; - function getSceneUuidFromURLHash() { const currentHash = window.location.hash; const match = currentHash.match(/#\/scenes\/([a-zA-Z0-9-]+)\.json/); @@ -32,14 +33,6 @@ function getAuthorId() { } STREET.utils.getAuthorId = getAuthorId; -const getCurrentSceneTitle = () => { - const currentSceneTitle = - AFRAME.scenes[0].getAttribute('metadata').sceneTitle; - console.log('currentSceneTitle', currentSceneTitle); - return currentSceneTitle; -}; -STREET.utils.getCurrentSceneTitle = getCurrentSceneTitle; - /* Takes one or more elements (from a DOM queryselector call) and returns a Javascript object @@ -61,7 +54,7 @@ function convertDOMElToObject(entity) { } return { - title: STREET.utils.getCurrentSceneTitle(), + title: useStore.getState().sceneTitle, version: '1.0', data: data }; @@ -469,17 +462,10 @@ function createEntityFromObj(entityData, parentEl) { AFRAME.registerComponent('metadata', { schema: { - sceneTitle: { default: '' }, sceneId: { default: '' }, authorId: { default: '' } }, - init: function () {}, - update: function (oldData) { - const sceneTitle = this.data.sceneTitle; - if (sceneTitle !== oldData.sceneTitle) { - this.el.emit('newTitle', { sceneTitle: sceneTitle }); - } - } + init: function () {} }); AFRAME.registerComponent('set-loader-from-hash', { @@ -651,7 +637,7 @@ function createElementsFromJSON(streetJSON, clearUrlHash) { const sceneTitle = streetObject.title; if (sceneTitle) { console.log('sceneTitle from createElementsFromJSON', sceneTitle); - AFRAME.scenes[0].setAttribute('metadata', 'sceneTitle', sceneTitle); + useStore.setState({ sceneTitle: sceneTitle }); } const streetContainerEl = document.getElementById('street-container'); diff --git a/src/street-utils.js b/src/street-utils.js index 872f52e6..300c0384 100644 --- a/src/street-utils.js +++ b/src/street-utils.js @@ -69,7 +69,6 @@ function newScene( // clear metadata if (clearMetaData) { AFRAME.scenes[0].setAttribute('metadata', 'sceneId', ''); - AFRAME.scenes[0].setAttribute('metadata', 'sceneTitle', ''); AFRAME.scenes[0].setAttribute('metadata', 'authorId', ''); } From a83eb239fd8aad4d8ff2ecbbedab0497e529ac84 Mon Sep 17 00:00:00 2001 From: Rahul Gupta Date: Thu, 7 Nov 2024 20:56:16 -0800 Subject: [PATCH 05/15] cleanup + streetplan support --- src/components/streetplan-loader.js | 17 +++++------------ .../SceneEditTitle/SceneEditTitle.component.jsx | 9 +++------ src/editor/index.js | 4 ---- src/index.js | 5 +++-- 4 files changed, 11 insertions(+), 24 deletions(-) diff --git a/src/components/streetplan-loader.js b/src/components/streetplan-loader.js index 9ee95b70..7e7a5dfc 100644 --- a/src/components/streetplan-loader.js +++ b/src/components/streetplan-loader.js @@ -1,6 +1,9 @@ /* global AFRAME, XMLHttpRequest */ +import useStore from '../store.js'; var streetplanUtils = require('../streetplan/streetplan-utils.js'); +const state = useStore.getState(); + AFRAME.registerComponent('streetplan-loader', { dependencies: ['street'], schema: { @@ -25,18 +28,8 @@ AFRAME.registerComponent('streetplan-loader', { // streetplan alternative name // const streetplanAltName = streetData.altName; - let currentSceneTitle; - const sceneEl = this.el.sceneEl; - if (sceneEl && sceneEl.getAttribute('metadata')) { - currentSceneTitle = sceneEl.getAttribute('metadata').sceneTitle; - } - if (!currentSceneTitle) { - // only set title from streetplan if none exists - sceneEl.setAttribute('metadata', 'sceneTitle', streetplanName); - console.log( - 'therefore setting metadata sceneTitle as streetplanName', - streetplanName - ); + if (!state.sceneTitle) { + state.setSceneTitle(streetplanName); } el.setAttribute('data-layer-name', 'StreetPlan • ' + streetplanName); diff --git a/src/editor/components/components/SceneEditTitle/SceneEditTitle.component.jsx b/src/editor/components/components/SceneEditTitle/SceneEditTitle.component.jsx index 9650f859..94970333 100644 --- a/src/editor/components/components/SceneEditTitle/SceneEditTitle.component.jsx +++ b/src/editor/components/components/SceneEditTitle/SceneEditTitle.component.jsx @@ -21,13 +21,10 @@ const SceneEditTitle = ({ sceneData }) => { const saveNewTitle = async (newTitle) => { try { - if (sceneData?.sceneId) { - if (currentUser.uid === STREET.utils.getAuthorId()) { - await updateSceneIdAndTitle(sceneData?.sceneId, newTitle); - } + if (currentUser.uid === STREET.utils.getAuthorId()) { + await updateSceneIdAndTitle(STREET.utils.getCurrentSceneId(), newTitle); + STREET.notify.successMessage(`New scene title saved: ${newTitle}`); } - AFRAME.scenes[0].setAttribute('metadata', 'sceneId', sceneData?.sceneId); - STREET.notify.successMessage(`New scene title saved: ${newTitle}`); } catch (error) { console.error('Error with update title', error); STREET.notify.errorMessage(`Error updating scene title: ${error}`); diff --git a/src/editor/index.js b/src/editor/index.js index f5d6b5b5..f58f3bab 100644 --- a/src/editor/index.js +++ b/src/editor/index.js @@ -14,7 +14,6 @@ import './style/index.scss'; import posthog from 'posthog-js'; import { commandsByType } from './lib/commands/index.js'; -console.log('editor'); function Inspector() { this.assetsLoader = new AssetsLoader(); this.exporters = { gltf: new GLTFExporter() }; @@ -23,7 +22,6 @@ function Inspector() { this.isFirstOpen = true; this.modules = {}; this.opened = false; - console.log('Inspector'); // Wait for stuff. const doInit = () => { if (!AFRAME.scenes.length) { @@ -68,7 +66,6 @@ Inspector.prototype = { Shortcuts.init(this); this.initEvents(); - console.log('initUI'); this.selected = null; // Init React. @@ -360,7 +357,6 @@ Inspector.prototype = { }; const inspector = (AFRAME.INSPECTOR = new Inspector()); -console.log('inspector', inspector); posthog.init('phc_Yclai3qykyFi8AEFOrZsh6aS78SSooLzpDz9wQ9YAH9', { api_host: 'https://us.i.posthog.com', person_profiles: 'identified_only' // or 'always' to create profiles for anonymous users as well diff --git a/src/index.js b/src/index.js index 8e8b9ca2..522594b8 100644 --- a/src/index.js +++ b/src/index.js @@ -199,8 +199,9 @@ AFRAME.registerComponent('streetmix-loader', { const streetmixName = streetmixResponseObject.name; el.setAttribute('streetmix-loader', 'name', streetmixName); - // console.log('useStore', useStore); - state.setSceneTitle(streetmixName); + if (!state.sceneTitle) { + state.setSceneTitle(streetmixName); + } el.setAttribute('data-layer-name', 'Streetmix • ' + streetmixName); From ca674de6c3e017bb076a2fba14ead1a2089096dc Mon Sep 17 00:00:00 2001 From: Kieran Farr Date: Thu, 7 Nov 2024 21:13:01 -0800 Subject: [PATCH 06/15] fix build error --- webpack.prod.config.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webpack.prod.config.js b/webpack.prod.config.js index 54325d7a..9b6be64c 100644 --- a/webpack.prod.config.js +++ b/webpack.prod.config.js @@ -7,8 +7,8 @@ const DEPLOY_ENV = process.env.DEPLOY_ENV ?? 'production'; module.exports = { performance: { - maxAssetSize: 2777777, // 2.4 MiB - maxEntrypointSize: 2777777, // 2.4 MiB + maxAssetSize: 2999999, // 2.8 MiB + maxEntrypointSize: 2999999, // 2.8 MiB hints: 'error' }, mode: 'production', From 4c8c81b20d541a0f1a3968aed777eec432967a91 Mon Sep 17 00:00:00 2001 From: Kieran Farr Date: Thu, 7 Nov 2024 21:19:55 -0800 Subject: [PATCH 07/15] remove deleted components --- index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index 7c6480de..012ff7aa 100644 --- a/index.html +++ b/index.html @@ -76,8 +76,8 @@ From f23a0d4bd5f4df79850914b53b2c356319e3b39f Mon Sep 17 00:00:00 2001 From: Rahul Gupta Date: Tue, 12 Nov 2024 15:10:22 -0500 Subject: [PATCH 08/15] respond to comments --- .../components/modals/ScenesModal/ScenesModal.component.jsx | 2 +- src/json-utils_1.1.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/editor/components/modals/ScenesModal/ScenesModal.component.jsx b/src/editor/components/modals/ScenesModal/ScenesModal.component.jsx index f5433a3d..4d647c1a 100644 --- a/src/editor/components/modals/ScenesModal/ScenesModal.component.jsx +++ b/src/editor/components/modals/ScenesModal/ScenesModal.component.jsx @@ -65,7 +65,7 @@ const ScenesModal = ({ isOpen, onClose, initialTab = 'owner', delay }) => { const sceneId = scene.id; const sceneTitle = sceneData.title; AFRAME.scenes[0].setAttribute('metadata', 'sceneId', sceneId); - useStore.setState({ sceneTitle: sceneTitle }); + useStore.getState().setSceneTitle(sceneTitle); AFRAME.scenes[0].setAttribute('metadata', 'authorId', sceneData.author); STREET.notify.successMessage('Scene loaded from 3DStreet Cloud.'); onClose(); diff --git a/src/json-utils_1.1.js b/src/json-utils_1.1.js index c7dc6bc9..f3e3bfd0 100644 --- a/src/json-utils_1.1.js +++ b/src/json-utils_1.1.js @@ -637,7 +637,7 @@ function createElementsFromJSON(streetJSON, clearUrlHash) { const sceneTitle = streetObject.title; if (sceneTitle) { console.log('sceneTitle from createElementsFromJSON', sceneTitle); - useStore.setState({ sceneTitle: sceneTitle }); + useStore.getState().setSceneTitle(sceneTitle); } const streetContainerEl = document.getElementById('street-container'); From b9864fb119371c16a952d8c733152a4f09c6cfa9 Mon Sep 17 00:00:00 2001 From: Rahul Gupta Date: Tue, 12 Nov 2024 15:15:42 -0500 Subject: [PATCH 09/15] missed one thing --- src/editor/components/scenegraph/Toolbar.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/editor/components/scenegraph/Toolbar.js b/src/editor/components/scenegraph/Toolbar.js index fbf111ed..168990a3 100644 --- a/src/editor/components/scenegraph/Toolbar.js +++ b/src/editor/components/scenegraph/Toolbar.js @@ -180,12 +180,8 @@ export default class Toolbar extends Component { if (newSceneTitle) { currentSceneTitle = newSceneTitle; } - AFRAME.scenes[0].setAttribute( - 'metadata', - 'sceneTitle', - currentSceneTitle - ); + useStore.getState().setSceneTitle(currentSceneTitle); console.log( 'no urlSceneId or doSaveAs is true, therefore generate new one' ); From 3761bacf081767734b2197ce58819611d383d1bd Mon Sep 17 00:00:00 2001 From: Kieran Farr Date: Wed, 13 Nov 2024 16:32:44 -0800 Subject: [PATCH 10/15] remove react-ga4 dependencies --- package-lock.json | 6 ------ package.json | 1 - src/editor/components/Collapsible.js | 2 -- src/editor/components/components/Component.js | 3 --- src/editor/components/components/Mixins.js | 3 --- src/editor/components/components/Sidebar.js | 2 -- src/editor/components/scenegraph/Toolbar.js | 2 -- src/editor/components/viewport/TransformToolbar.js | 2 -- src/editor/lib/viewport.js | 2 -- src/editor/services/ga.js | 11 ----------- 10 files changed, 34 deletions(-) delete mode 100644 src/editor/services/ga.js diff --git a/package-lock.json b/package-lock.json index 4a9f1241..c4323aa4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,7 +29,6 @@ "prop-types": "^15.8.1", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-ga4": "^2.1.0", "react-select": "^5.4.0", "stripe": "^15.8.0", "three": "0.145.0", @@ -25769,11 +25768,6 @@ "integrity": "sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg==", "dev": true }, - "node_modules/react-ga4": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/react-ga4/-/react-ga4-2.1.0.tgz", - "integrity": "sha512-ZKS7PGNFqqMd3PJ6+C2Jtz/o1iU9ggiy8Y8nUeksgVuvNISbmrQtJiZNvC/TjDsqD0QlU5Wkgs7i+w9+OjHhhQ==" - }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", diff --git a/package.json b/package.json index e2463e98..851aee95 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,6 @@ "prop-types": "^15.8.1", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-ga4": "^2.1.0", "react-select": "^5.4.0", "stripe": "^15.8.0", "three": "0.145.0", diff --git a/src/editor/components/Collapsible.js b/src/editor/components/Collapsible.js index 08743566..ce806fe1 100644 --- a/src/editor/components/Collapsible.js +++ b/src/editor/components/Collapsible.js @@ -1,7 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; -import { sendMetric } from '../services/ga'; export default class Collapsible extends React.Component { static propTypes = { @@ -27,7 +26,6 @@ export default class Collapsible extends React.Component { // Don't collapse if we click on actions like clipboard if (event.target.nodeName === 'A') return; this.setState({ collapsed: !this.state.collapsed }); - sendMetric('Components', 'collapse'); }; render() { diff --git a/src/editor/components/components/Component.js b/src/editor/components/components/Component.js index e919a724..1b6af765 100644 --- a/src/editor/components/components/Component.js +++ b/src/editor/components/components/Component.js @@ -5,7 +5,6 @@ import PropTypes from 'prop-types'; import PropertyRow from './PropertyRow'; import React from 'react'; import { getComponentClipboardRepresentation } from '../../lib/entity'; -import { sendMetric } from '../../services/ga'; const isSingleProperty = AFRAME.schema.isSingleProperty; @@ -45,7 +44,6 @@ export default class Component extends React.Component { var componentName = trigger .getAttribute('data-component') .toLowerCase(); - sendMetric('Components', 'copyComponentToClipboard', componentName); return getComponentClipboardRepresentation( this.state.entity, componentName @@ -85,7 +83,6 @@ export default class Component extends React.Component { entity: this.props.entity, component: componentName }); - sendMetric('Components', 'removeComponent', componentName); } }; diff --git a/src/editor/components/components/Mixins.js b/src/editor/components/components/Mixins.js index 8eb17b49..d3f95154 100644 --- a/src/editor/components/components/Mixins.js +++ b/src/editor/components/components/Mixins.js @@ -3,7 +3,6 @@ import PropTypes from 'prop-types'; import Select, { components } from 'react-select'; import Events from '../../lib/Events'; import { DropdownArrowIcon } from '../../icons'; -import { sendMetric } from '../../services/ga'; export default class Mixin extends React.Component { static propTypes = { @@ -80,7 +79,6 @@ export default class Mixin extends React.Component { entity: entity, value: mixinStr }); - sendMetric('Components', 'addMixin'); }; updateMixinSingle = (value) => { @@ -92,7 +90,6 @@ export default class Mixin extends React.Component { entity: entity, value: mixinStr }); - sendMetric('Components', 'addMixin'); }; render() { diff --git a/src/editor/components/components/Sidebar.js b/src/editor/components/components/Sidebar.js index 364fc906..6b26627a 100644 --- a/src/editor/components/components/Sidebar.js +++ b/src/editor/components/components/Sidebar.js @@ -8,7 +8,6 @@ import React from 'react'; import capitalize from 'lodash-es/capitalize'; import classnames from 'classnames'; import { ArrowRightIcon, LayersIcon } from '../../icons'; -import { sendMetric } from '../../services/ga'; import GeoSidebar from './GeoSidebar'; // Make sure to create and import this new component export default class Sidebar extends React.Component { @@ -62,7 +61,6 @@ export default class Sidebar extends React.Component { // additional toggle for hide/show panel by clicking the button toggleRightBar = () => { this.setState({ rightBarHide: !this.state.rightBarHide }); - sendMetric('Components', 'toggleSidebar'); }; render() { diff --git a/src/editor/components/scenegraph/Toolbar.js b/src/editor/components/scenegraph/Toolbar.js index 168990a3..12336ba0 100644 --- a/src/editor/components/scenegraph/Toolbar.js +++ b/src/editor/components/scenegraph/Toolbar.js @@ -14,7 +14,6 @@ import { } from '../../icons'; import Events from '../../lib/Events'; import { Button, ProfileButton, Logo } from '../components'; -import { sendMetric } from '../../services/ga.js'; import posthog from 'posthog-js'; import { UndoRedo } from '../components/UndoRedo'; import debounce from 'lodash-es/debounce'; @@ -219,7 +218,6 @@ export default class Toolbar extends Component { const notification = STREET.notify.successMessage('Scene saved'); this.setState({ notification }); - sendMetric('SaveSceneAction', doSaveAs ? 'saveAs' : 'save'); return currentSceneId; } catch (error) { STREET.notify.errorMessage( diff --git a/src/editor/components/viewport/TransformToolbar.js b/src/editor/components/viewport/TransformToolbar.js index 795135ff..dc71174b 100644 --- a/src/editor/components/viewport/TransformToolbar.js +++ b/src/editor/components/viewport/TransformToolbar.js @@ -1,7 +1,6 @@ import React from 'react'; import classNames from 'classnames'; import Events from '../../lib/Events'; -import { sendMetric } from '../../services/ga'; var TransformButtons = [ { value: 'translate', icon: 'fa-arrows-alt' }, @@ -43,7 +42,6 @@ export default class TransformToolbar extends React.Component { changeTransformMode = (mode) => { this.setState({ selectedTransform: mode }); Events.emit('transformmodechange', mode); - sendMetric('Toolbar', 'selectHelper', mode); }; onLocalChange = (e) => { diff --git a/src/editor/lib/viewport.js b/src/editor/lib/viewport.js index 0c1d503c..6e6b4137 100644 --- a/src/editor/lib/viewport.js +++ b/src/editor/lib/viewport.js @@ -4,7 +4,6 @@ import EditorControls from './EditorControls.js'; import { initRaycaster } from './raycaster'; import Events from './Events'; -import { sendMetric } from '../services/ga.js'; // variables used by OrientedBoxHelper const auxEuler = new THREE.Euler(); @@ -382,6 +381,5 @@ export function Viewport(inspector) { element.style.display = 'block'; }); } - sendMetric('Viewport', 'toggleEditor', active); }); } diff --git a/src/editor/services/ga.js b/src/editor/services/ga.js deleted file mode 100644 index 2b5de4a7..00000000 --- a/src/editor/services/ga.js +++ /dev/null @@ -1,11 +0,0 @@ -import ReactGA from 'react-ga4'; - -const sendMetric = (category, action, label) => { - ReactGA.event({ - category, - action, - label: label - }); -}; - -export { sendMetric }; From 94ffe84fa8fdb8ef6477951cedbf3a75cd519d16 Mon Sep 17 00:00:00 2001 From: Vincent Fretin Date: Thu, 14 Nov 2024 11:27:44 +0100 Subject: [PATCH 11/15] remove automatically injected inspector component to fix shortcut conflict --- src/index.js | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index 522594b8..8612af55 100644 --- a/src/index.js +++ b/src/index.js @@ -22,7 +22,30 @@ require('./components/street-environment.js'); require('./components/intersection.js'); require('./components/obb-clipping.js'); require('./editor/index.js'); -// import { inspector } from './editor/index.js'; + +// Remove automatically injected inspector component to fix shortcut conflict. +function removeInspectorComponent() { + setTimeout(() => { + document.querySelector('a-scene')?.removeAttribute('inspector'); + }, 0); +} + +function waitForDocumentReadyStateToRemoveInspectorComponent() { + if (document.readyState === 'complete') { + removeInspectorComponent(); + return; + } + + document.addEventListener('readystatechange', function onReadyStateChange() { + if (document.readyState !== 'complete') { + return; + } + document.removeEventListener('readystatechange', onReadyStateChange); + removeInspectorComponent(); + }); +} + +waitForDocumentReadyStateToRemoveInspectorComponent(); const state = useStore.getState(); From ed75ec87dc906f3541e5cbfda16810a610c2cee6 Mon Sep 17 00:00:00 2001 From: Vincent Fretin Date: Thu, 14 Nov 2024 13:26:42 +0100 Subject: [PATCH 12/15] Revert "remove automatically injected inspector component to fix shortcut conflict" This reverts commit 94ffe84fa8fdb8ef6477951cedbf3a75cd519d16. --- src/index.js | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/src/index.js b/src/index.js index 8612af55..522594b8 100644 --- a/src/index.js +++ b/src/index.js @@ -22,30 +22,7 @@ require('./components/street-environment.js'); require('./components/intersection.js'); require('./components/obb-clipping.js'); require('./editor/index.js'); - -// Remove automatically injected inspector component to fix shortcut conflict. -function removeInspectorComponent() { - setTimeout(() => { - document.querySelector('a-scene')?.removeAttribute('inspector'); - }, 0); -} - -function waitForDocumentReadyStateToRemoveInspectorComponent() { - if (document.readyState === 'complete') { - removeInspectorComponent(); - return; - } - - document.addEventListener('readystatechange', function onReadyStateChange() { - if (document.readyState !== 'complete') { - return; - } - document.removeEventListener('readystatechange', onReadyStateChange); - removeInspectorComponent(); - }); -} - -waitForDocumentReadyStateToRemoveInspectorComponent(); +// import { inspector } from './editor/index.js'; const state = useStore.getState(); From 8906f235266d2f48a0f6d0d19cbff87eb797425c Mon Sep 17 00:00:00 2001 From: Vincent Fretin Date: Thu, 14 Nov 2024 13:27:08 +0100 Subject: [PATCH 13/15] remove commented import --- src/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/index.js b/src/index.js index 522594b8..b8817c5e 100644 --- a/src/index.js +++ b/src/index.js @@ -22,7 +22,6 @@ require('./components/street-environment.js'); require('./components/intersection.js'); require('./components/obb-clipping.js'); require('./editor/index.js'); -// import { inspector } from './editor/index.js'; const state = useStore.getState(); From b70cb13eef0fcc89330c1e0e5e188bce96db4815 Mon Sep 17 00:00:00 2001 From: Vincent Fretin Date: Thu, 14 Nov 2024 13:28:34 +0100 Subject: [PATCH 14/15] remove inspector component to unregister the keydown listener --- src/editor/index.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/editor/index.js b/src/editor/index.js index f58f3bab..28ba866e 100644 --- a/src/editor/index.js +++ b/src/editor/index.js @@ -178,6 +178,9 @@ Inspector.prototype = { }, initEvents: function () { + // Remove inspector component to properly unregister keydown listener when the inspector is loaded via a script tag, + // otherwise the listener will be registered twice and we can't toggle the inspector from viewer mode with the shortcut. + this.sceneEl.removeAttribute('inspector'); window.addEventListener('keydown', (evt) => { // Alt + Ctrl + i: Shorcut to toggle the inspector const shortcutPressed = From e58cfc263147495488b353b226dfc15091d13749 Mon Sep 17 00:00:00 2001 From: Kieran Farr Date: Thu, 14 Nov 2024 09:01:34 -0800 Subject: [PATCH 15/15] fix and simplify loading animation --- index.html | 10 --- src/viewer-styles.css | 177 ++++-------------------------------------- 2 files changed, 16 insertions(+), 171 deletions(-) diff --git a/index.html b/index.html index 012ff7aa..7704f842 100644 --- a/index.html +++ b/index.html @@ -35,16 +35,6 @@
-
- entities -
-
-
- car - bus - bike -
-
Loading 3DStreet
diff --git a/src/viewer-styles.css b/src/viewer-styles.css index 12243190..32e1315c 100644 --- a/src/viewer-styles.css +++ b/src/viewer-styles.css @@ -222,188 +222,43 @@ body.aframe-inspector-opened #sceneTitle { .loader__wrapper { width: 100vw; height: 100vh; - background: rgba(14, 14, 14, 0.69); - display: flex; justify-content: center; align-items: center; } .loader { - display: flex; - align-items: center; - flex-direction: column; position: relative; z-index: 999999; - } - .road { width: 320px; - display: flex; align-items: center; justify-content: center; padding-top: 12px; - - border-top: 4px solid #fff; - + /* Remove the solid border and replace with animated background */ + border-top: none; + background: repeating-linear-gradient( + 90deg, + #6100FF 0px, + #ae7cff 320px, + transparent 0px, + transparent 320px + ); + background-size: 200% 4px; + background-repeat: repeat-x; + background-position: top; + animation: moveStripes 1s linear infinite; color: #fff; font-weight: normal; } -/* ENTITIES */ - -/* - entities width = 1050px - loader width = 320px - animation-duration = 5840ms - */ -.entities { - position: absolute; - bottom: 40px; - right: 0; - - /* 730px = 1050px - 320px */ - clip-path: inset(0 0px 0 730px); - transform: translateX(0px); - animation: topMoving 5840ms linear infinite; -} - -@keyframes topMoving { - 0% { - clip-path: inset(0 0px 0 730px); - transform: translateX(0px); - } - - 100% { - clip-path: inset(0 730px 0 0px); - transform: translateX(730px); - } -} - -/* TRANSPORT */ -.transport { - position: absolute; - left: 0; - top: 2px; -} - -.wrapper__transport { - display: flex; - align-items: flex-end; - position: relative; -} - -.wrapper__transport img { - position: absolute; -} - -/* BIKE */ -.transport .bike { - position: absolute; - animation: bike 5840ms linear infinite; -} - -@keyframes bike { - 0% { - left: -27px; - clip-path: inset(0 0 0 100%); - } - - 4% { - left: 0px; - clip-path: inset(0 0 0 0); - } - - 32% { - left: 294px; - clip-path: inset(0 0 0 0); - } - - 36% { - clip-path: inset(0 100% 0 0); - left: 320px; - } - - 100% { - clip-path: inset(0 100% 0 0); - left: 320px; - } -} - -/* BUS */ -.transport .bus { - position: absolute; - animation: bus 5840ms linear infinite; -} - -@keyframes bus { +@keyframes moveStripes { 0% { - left: -36px; - clip-path: inset(0 0 0 100%); - } - - 8% { - left: -36px; - clip-path: inset(0 0 0 100%); - } - - 12% { - left: 0px; - clip-path: inset(0 0 0 0); - } - - 44% { - left: 284px; - clip-path: inset(0 0 0 0); - } - - 48% { - clip-path: inset(0 100% 0 0); - left: 320px; + background-position: 0 0; } - - 100% { - clip-path: inset(0 100% 0 0); - left: 320px; - } -} - -/* CAR */ -.transport .car { - position: absolute; - animation: car 5840ms linear infinite; -} - -@keyframes car { - 0% { - left: -30px; - clip-path: inset(0 0 0 100%); - } - - 20% { - left: -30px; - clip-path: inset(0 0 0 100%); - } - - 24% { - left: 0px; - clip-path: inset(0 0 0 0); - } - - 76% { - left: 290px; - clip-path: inset(0 0 0 0); - } - - 80% { - clip-path: inset(0 100% 0 0); - left: 320px; - } - 100% { - clip-path: inset(0 100% 0 0); - left: 320px; + background-position: 320px 0; } } \ No newline at end of file