Skip to content

Commit

Permalink
Merge pull request #626 from 3DStreet/action-bar
Browse files Browse the repository at this point in the history
[wip] Action bar
  • Loading branch information
kfarr authored Jun 14, 2024
2 parents b2be856 + f2dd0d6 commit d007458
Show file tree
Hide file tree
Showing 15 changed files with 194 additions and 72 deletions.
24 changes: 24 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"homepage": "https://github.com/3dstreet/3dstreet/",
"license": "AGPLv3",
"dependencies": {
"@fortawesome/free-regular-svg-icons": "^6.5.2",
"@react-google-maps/api": "^2.19.3",
"aframe-atlas-uvs-component": "^3.0.0",
"classnames": "^2.3.2",
Expand Down
20 changes: 9 additions & 11 deletions src/editor/components/Main.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,16 @@ import SceneGraph from './scenegraph/SceneGraph';
import { ScreenshotModal } from './modals/ScreenshotModal';
import TransformToolbar from './viewport/TransformToolbar';
// import ViewportHUD from "./viewport/ViewportHUD";
import { injectCSS } from '../lib/utils';
import { SignInModal } from './modals/SignInModal';
import { ProfileModal } from './modals/ProfileModal';
import { firebaseConfig } from '../services/firebase.js';
import { LoadScript } from '@react-google-maps/api';
import { GeoModal } from './modals/GeoModal';
import { ActionBar } from './components/ActionBar';
import { ScenesModal } from './modals/ScenesModal';
import { SceneEditTitle } from './components/SceneEditTitle';
import { AddLayerButton } from './components/AddLayerButton';
import { AddLayerPanel } from './components/AddLayerPanel';
THREE.ImageUtils.crossOrigin = '';
// Megahack to include font-awesome.
injectCSS(
'https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css'
);

const isStreetLoaded = window.location.hash.length;

Expand Down Expand Up @@ -282,6 +277,14 @@ export default class Main extends Component {
<GeoPanel />
</div>
)}
{this.state.inspectorEnabled && (
<div id="action-bar">
<ActionBar
handleAddClick={this.toggleAddLayerPanel}
isAddLayerPanelOpen={this.state.isAddLayerPanelOpen}
/>
</div>
)}
{this.state.inspectorEnabled && (
<div id="scene-title">
<SceneEditTitle sceneData={sceneData} />
Expand All @@ -297,11 +300,6 @@ export default class Main extends Component {
<Compass32Icon />
</Button>
)}
{this.state.inspectorEnabled && (
<div id="layerWithCategory">
<AddLayerButton onClick={this.toggleAddLayerPanel} />
</div>
)}
{this.state.inspectorEnabled && this.state.isAddLayerPanelOpen && (
<AddLayerPanel
onClose={this.toggleAddLayerPanel}
Expand Down
55 changes: 55 additions & 0 deletions src/editor/components/components/ActionBar/ActionBar.component.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import {
faHand,
faHandPointer,
faPlusSquare
} from '@fortawesome/free-regular-svg-icons';
import { AwesomeIcon } from '../AwesomeIcon';
import classNames from 'classnames';
import Events from '../../../lib/Events';
import styles from './ActionBar.module.scss';
import { Button } from '../Button';
import { useState } from 'react';

const ActionBar = ({ handleAddClick, isAddLayerPanelOpen }) => {
const [cursorEnabled, setCursorEnabled] = useState(
AFRAME.INSPECTOR.cursor.isPlaying
);

const handleHandClick = () => {
Events.emit('hidecursor');
setCursorEnabled(false);
};

const handleSelectClick = () => {
Events.emit('showcursor');
setCursorEnabled(true);
};

return (
<div>
{!isAddLayerPanelOpen && (
<div className={styles.wrapper}>
<Button
variant="toolbtn"
className={classNames({ [styles.active]: cursorEnabled })}
onClick={handleSelectClick}
>
<AwesomeIcon icon={faHandPointer} />
</Button>
<Button
variant="toolbtn"
className={classNames({ [styles.active]: !cursorEnabled })}
onClick={handleHandClick}
>
<AwesomeIcon icon={faHand} />
</Button>
<Button variant="toolbtn" onClick={handleAddClick}>
<AwesomeIcon icon={faPlusSquare} />
</Button>
</div>
)}
</div>
);
};

export { ActionBar };
26 changes: 26 additions & 0 deletions src/editor/components/components/ActionBar/ActionBar.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
@use '../../../style/variables.scss';

.wrapper {
position: absolute;
transform: translateX(-50%);
bottom: 15%;
left: 50%;
border: unset;
height: 40px;
border-radius: 16px;
align-items: center;
display: flex;
column-gap: 8px;
padding: 8px 12px;
transition: 0.2s ease-in-out;

button {
border-radius: 50%;
width: 43px;
height: 43px;

&.active {
border: 1px solid variables.$white;
}
}
}
1 change: 1 addition & 0 deletions src/editor/components/components/ActionBar/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { ActionBar } from './ActionBar.component.jsx';

This file was deleted.

This file was deleted.

1 change: 0 additions & 1 deletion src/editor/components/components/AddLayerButton/index.js

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
Use <AwesomeIcon icon={faEye} /> instead of <FontAwesomeIcon icon={faEye} /> from @fortawesome/react-fontawesome
Using FontAwesomeIcon component adds 66 kB minified to the bundle.
Our AwesomeIcon does the same but less than 2 kB minified.
svg-inline--fa class has been added to AwesomeIcon.scss
*/
import React from 'react';
import PropTypes from 'prop-types';
import './AwesomeIcon.scss';

function asIcon(icon) {
const width = icon[0];
const height = icon[1];
const vectorData = icon[4];
let element;

if (Array.isArray(vectorData)) {
element = (
<g>
{vectorData.map((pathData, index) => (
<path key={index} fill="currentColor" d={pathData} />
))}
</g>
);
} else {
element = <path fill="currentColor" d={vectorData} />;
}

return {
width: width,
height: height,
icon: element
};
}

export class AwesomeIcon extends React.Component {
static propTypes = {
icon: PropTypes.object.isRequired,
size: PropTypes.number
};

render() {
const { width, height, icon } = asIcon(this.props.icon.icon);
return (
<svg
role="img"
className={`svg-inline--fa fa-${this.props.icon.iconName}`}
xmlns="http://www.w3.org/2000/svg"
viewBox={`0 0 ${width} ${height}`}
width={this.props.size ?? 20}
height={this.props.size ?? 20}
>
{icon}
</svg>
);
}
}
12 changes: 12 additions & 0 deletions src/editor/components/components/AwesomeIcon/AwesomeIcon.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/* CSS rules from the original FontAwesomeIcon component */
svg:not(:root).svg-inline--fa,
svg:not(:host).svg-inline--fa {
overflow: visible;
box-sizing: content-box;
}

.svg-inline--fa {
display: inline-block;
overflow: visible;
vertical-align: -0.125em;
}
1 change: 1 addition & 0 deletions src/editor/components/components/AwesomeIcon/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { AwesomeIcon } from './AwesomeIcon.component.js';
25 changes: 0 additions & 25 deletions src/editor/icons/icons.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -447,30 +447,6 @@ const GoogleSignInButtonSVG = ({ className }) => (
</svg>
);

const Circle20Icon = ({ className }) => (
<svg
width="21"
height="20"
viewBox="0 0 21 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={className}
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M10.5 3.5C6.91015 3.5 4 6.41015 4 10C4 13.5898 6.91015 16.5 10.5 16.5C14.0899 16.5 17 13.5899 17 10C17 6.41015 14.0899 3.5 10.5 3.5ZM10.5 2C6.08172 2 2.5 5.58172 2.5 10C2.5 14.4183 6.08172 18 10.5 18C14.9183 18 18.5 14.4183 18.5 10C18.5 5.58172 14.9183 2 10.5 2Z"
fill="white"
/>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M10.5 14.25C10.0858 14.25 9.75 13.9142 9.75 13.5L9.75 10.75L7 10.75C6.58579 10.75 6.25 10.4142 6.25 10C6.25 9.58579 6.58579 9.25 7 9.25L9.75 9.25L9.75 6.5C9.75 6.08579 10.0858 5.75 10.5 5.75C10.9142 5.75 11.25 6.08579 11.25 6.5L11.25 9.25L14 9.25C14.4142 9.25 14.75 9.58579 14.75 10C14.75 10.4142 14.4142 10.75 14 10.75L11.25 10.75L11.25 13.5C11.25 13.9142 10.9142 14.25 10.5 14.25Z"
fill="#DBDBDB"
/>
</svg>
);

const Chevron24Down = ({ className }) => (
<svg
xmlns="http://www.w3.org/2000/svg"
Expand Down Expand Up @@ -550,7 +526,6 @@ export {
ArrowRightIcon,
LayersIcon,
GoogleSignInButtonSVG,
Circle20Icon,
Chevron24Down,
Plus20Circle,
QR32Icon
Expand Down
1 change: 0 additions & 1 deletion src/editor/icons/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ export {
LayersIcon,
GoogleSignInButtonSVG,
Chevron24Down,
Circle20Icon,
Plus20Circle,
QR32Icon
} from './icons.jsx';
8 changes: 8 additions & 0 deletions src/editor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,14 @@ Inspector.prototype = {
this.selectEntity(entity, false);
});

Events.on('hidecursor', () => {
this.cursor.pause();
this.selectEntity(null);
});
Events.on('showcursor', () => {
this.cursor.play();
});

Events.on('inspectortoggle', (active) => {
this.inspectorActive = active;
this.sceneHelpers.visible = this.inspectorActive;
Expand Down

0 comments on commit d007458

Please sign in to comment.