feat: Stage
This commit is contained in:
parent
d6bb894f49
commit
bbe609800b
|
@ -15,8 +15,11 @@
|
|||
"test.js.map"
|
||||
],
|
||||
"dependencies": {
|
||||
"@avocado/graphics": "^2.0.0",
|
||||
"@avocado/math": "^2.0.0",
|
||||
"@latus/core": "^2.0.0",
|
||||
"@latus/react": "^2.0.0"
|
||||
"@latus/react": "^2.0.0",
|
||||
"rc-slider": "^9.7.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@latus/build": "1.x"
|
||||
|
|
101
packages/react/src/components/stage/index.jsx
Normal file
101
packages/react/src/components/stage/index.jsx
Normal file
|
@ -0,0 +1,101 @@
|
|||
import {Renderer} from '@avocado/graphics';
|
||||
import {Vector} from '@avocado/math';
|
||||
import {
|
||||
memo,
|
||||
PropTypes,
|
||||
React,
|
||||
useEffect,
|
||||
useRef,
|
||||
useState,
|
||||
} from '@latus/react';
|
||||
import Slider from 'rc-slider';
|
||||
|
||||
const marks = {
|
||||
1: '1x',
|
||||
2: '2x',
|
||||
4: '4x',
|
||||
8: '8x',
|
||||
};
|
||||
|
||||
const Stage = memo(({
|
||||
centered,
|
||||
renderable,
|
||||
scalable,
|
||||
size,
|
||||
ticker,
|
||||
}) => {
|
||||
const ref = useRef();
|
||||
const [renderer, setRenderer] = useState();
|
||||
const [scale, setScale] = useState(1);
|
||||
useEffect(() => {
|
||||
setRenderer(new Renderer([0, 0]));
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
if (!renderable) {
|
||||
return;
|
||||
}
|
||||
/* eslint-disable no-param-reassign */
|
||||
renderable.scale = [scale, scale];
|
||||
if (centered) {
|
||||
renderable.position = Vector.scale(size, 0.5);
|
||||
}
|
||||
/* eslint-enable no-param-reassign */
|
||||
}, [centered, renderable, scale, size]);
|
||||
useEffect(() => {
|
||||
if (!ref.current || !renderable || !renderer) {
|
||||
return undefined;
|
||||
}
|
||||
renderer.resize(size);
|
||||
const container = ref.current;
|
||||
ref.current.appendChild(renderer.element);
|
||||
let handle;
|
||||
const tick = (elapsed) => {
|
||||
ticker(elapsed);
|
||||
renderer.render(renderable);
|
||||
handle = requestAnimationFrame(tick);
|
||||
};
|
||||
tick(0);
|
||||
return () => {
|
||||
if (renderer) {
|
||||
container.removeChild(renderer.element);
|
||||
}
|
||||
if (handle) {
|
||||
cancelAnimationFrame(handle);
|
||||
}
|
||||
};
|
||||
}, [ref, renderable, renderer, size, ticker]);
|
||||
return (
|
||||
<div className="stage">
|
||||
{scalable && (
|
||||
<Slider
|
||||
min={1}
|
||||
max={8}
|
||||
marks={marks}
|
||||
step={null}
|
||||
onChange={(scale) => {
|
||||
setScale(scale);
|
||||
}}
|
||||
defaultValue={1}
|
||||
/>
|
||||
)}
|
||||
<div className="canvas-host" ref={ref} />
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
Stage.defaultProps = {
|
||||
centered: true,
|
||||
scalable: true,
|
||||
};
|
||||
|
||||
Stage.displayName = 'Stage';
|
||||
|
||||
Stage.propTypes = {
|
||||
centered: PropTypes.bool,
|
||||
renderable: PropTypes.shape({}).isRequired,
|
||||
scalable: PropTypes.bool,
|
||||
size: PropTypes.arrayOf(PropTypes.number).isRequired,
|
||||
ticker: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default Stage;
|
31
packages/react/src/components/stage/index.scss
Normal file
31
packages/react/src/components/stage/index.scss
Normal file
|
@ -0,0 +1,31 @@
|
|||
.stage {
|
||||
align-items: center;
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
min-height: 200px;
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
.stage > .canvas-host {
|
||||
align-items: center;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
height: 100%;
|
||||
justify-content: space-around;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.stage > .rc-slider {
|
||||
margin: 0.5em 0 1.25em;
|
||||
width: calc(100% - 2em);
|
||||
.rc-slider-handle {
|
||||
border: 1px solid rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
.rc-slider-track {
|
||||
background-color: #d60000;
|
||||
}
|
||||
}
|
|
@ -1,2 +1,3 @@
|
|||
// eslint-disable-next-line import/prefer-default-export
|
||||
export {default as Stage} from './components/stage';
|
||||
|
||||
export {default as usePropertyChange} from './hooks/use-property-change';
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user