mirror of
https://github.com/muerwre/orchidmap-front.git
synced 2025-04-25 19:16:41 +07:00
render: map composing (working)
This commit is contained in:
parent
2eb398ef6b
commit
4747c918e2
9 changed files with 122 additions and 7 deletions
|
@ -9,7 +9,7 @@ import { EditorDialog } from '$components/panels/EditorDialog';
|
||||||
import { LogoPreview } from '$components/logo/LogoPreview';
|
import { LogoPreview } from '$components/logo/LogoPreview';
|
||||||
import { bindActionCreators } from 'redux';
|
import { bindActionCreators } from 'redux';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { setMode, startEditing, stopEditing, setLogo } from '$redux/user/actions';
|
import { setMode, startEditing, stopEditing, setLogo, showRenderer } from '$redux/user/actions';
|
||||||
import type { UserType } from '$constants/types';
|
import type { UserType } from '$constants/types';
|
||||||
import { editor } from '$modules/Editor';
|
import { editor } from '$modules/Editor';
|
||||||
import { getTilePlacement } from '$utils/renderer';
|
import { getTilePlacement } from '$utils/renderer';
|
||||||
|
@ -31,6 +31,7 @@ type Props = {
|
||||||
startEditing: Function,
|
startEditing: Function,
|
||||||
stopEditing: Function,
|
stopEditing: Function,
|
||||||
setLogo: Function,
|
setLogo: Function,
|
||||||
|
showRenderer: Function,
|
||||||
}
|
}
|
||||||
|
|
||||||
class Component extends React.PureComponent<Props, void> {
|
class Component extends React.PureComponent<Props, void> {
|
||||||
|
@ -108,8 +109,8 @@ class Component extends React.PureComponent<Props, void> {
|
||||||
|
|
||||||
<button
|
<button
|
||||||
className={classnames('disabled', { active: mode === MODES.SHOTTER })}
|
className={classnames('disabled', { active: mode === MODES.SHOTTER })}
|
||||||
// onClick={this.startShotterMode}
|
onClick={this.props.showRenderer}
|
||||||
onClick={getTilePlacement}
|
// onClick={getTilePlacement}
|
||||||
>
|
>
|
||||||
<Icon icon="icon-shot-3" />
|
<Icon icon="icon-shot-3" />
|
||||||
</button>
|
</button>
|
||||||
|
@ -220,6 +221,7 @@ const mapDispatchToProps = dispatch => bindActionCreators({
|
||||||
setLogo,
|
setLogo,
|
||||||
startEditing,
|
startEditing,
|
||||||
stopEditing,
|
stopEditing,
|
||||||
|
showRenderer,
|
||||||
}, dispatch);
|
}, dispatch);
|
||||||
|
|
||||||
export const EditorPanel = connect(
|
export const EditorPanel = connect(
|
||||||
|
|
71
src/components/renderer/Renderer.jsx
Normal file
71
src/components/renderer/Renderer.jsx
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { getTilePlacement } from '$utils/renderer';
|
||||||
|
|
||||||
|
export class Renderer extends React.Component {
|
||||||
|
componentDidMount() {
|
||||||
|
if (this.canvas) this.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
const ctx = this.canvas.getContext('2d');
|
||||||
|
const geometry = getTilePlacement();
|
||||||
|
|
||||||
|
this.fetchImages(ctx, geometry)
|
||||||
|
.then(images => this.composeImages({ geometry, images, ctx }));
|
||||||
|
|
||||||
|
// myimage = new Image();
|
||||||
|
// myimage.onload = function() {
|
||||||
|
// ctx.drawImage(myimage, x, y);
|
||||||
|
// }
|
||||||
|
// myimage.src = 'http://myserver/nextimage.cgi';
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchImages = (ctx, geometry) => {
|
||||||
|
const {
|
||||||
|
minX, maxX, minY, maxY, zoom
|
||||||
|
} = geometry;
|
||||||
|
|
||||||
|
const images = [];
|
||||||
|
for (let x = minX; x <= maxX; x += 1) {
|
||||||
|
for (let y = minY; y <= maxY; y += 1) {
|
||||||
|
images.push({ x, y, source: this.getImageSource({ x, y, zoom }) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.all(images.map(({ x, y, source }) => (
|
||||||
|
this.imageFetcher(source).then(image => ({ x, y, image }))
|
||||||
|
)));
|
||||||
|
};
|
||||||
|
|
||||||
|
imageFetcher = source => new Promise((resolve, reject) => {
|
||||||
|
const img = new Image();
|
||||||
|
img.onload = () => resolve(img);
|
||||||
|
img.onerror = () => reject(img);
|
||||||
|
|
||||||
|
img.src = source;
|
||||||
|
});
|
||||||
|
|
||||||
|
getImageSource = ({ x, y, zoom }) => (`http://b.basemaps.cartocdn.com/light_all/${zoom}/${x}/${y}.png`);
|
||||||
|
|
||||||
|
composeImages = ({ images, geometry, ctx }) => {
|
||||||
|
const {
|
||||||
|
minX, minY, shiftX, shiftY, size
|
||||||
|
} = geometry;
|
||||||
|
|
||||||
|
images.map(({ x, y, image }) => {
|
||||||
|
const posX = ((x - minX) * size) + shiftX;
|
||||||
|
const posY = ((y - minY) * size) + (window.innerHeight - shiftY - size);
|
||||||
|
|
||||||
|
return ctx.drawImage(image, posX, posY, 256, 256);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className="renderer-shade" onClick={this.props.onClick}>
|
||||||
|
<canvas width={window.innerWidth} height={window.innerWidth} ref={el => { this.canvas = el; }} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -9,17 +9,30 @@ import { connect } from 'react-redux';
|
||||||
import { bindActionCreators } from 'redux';
|
import { bindActionCreators } from 'redux';
|
||||||
|
|
||||||
import { hot } from 'react-hot-loader';
|
import { hot } from 'react-hot-loader';
|
||||||
|
import { Renderer } from '$components/renderer/Renderer';
|
||||||
|
import { hideRenderer } from '$redux/user/actions';
|
||||||
|
|
||||||
const Component = () => (
|
type Props = {
|
||||||
|
renderer_active: Boolean,
|
||||||
|
hideRenderer: Function,
|
||||||
|
}
|
||||||
|
|
||||||
|
const Component = (props: Props) => (
|
||||||
<div>
|
<div>
|
||||||
<Fills />
|
<Fills />
|
||||||
<UserLocation />
|
<UserLocation />
|
||||||
<UserPanel />
|
<UserPanel />
|
||||||
<EditorPanel />
|
<EditorPanel />
|
||||||
|
{
|
||||||
|
props.renderer_active &&
|
||||||
|
<Renderer onClick={props.hideRenderer} />
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
const mapStateToProps = () => ({});
|
const mapStateToProps = ({ user }) => ({
|
||||||
const mapDispatchToProps = dispatch => bindActionCreators({}, dispatch);
|
renderer_active: user.renderer_active
|
||||||
|
});
|
||||||
|
const mapDispatchToProps = dispatch => bindActionCreators({ hideRenderer }, dispatch);
|
||||||
export const App = connect(mapStateToProps, mapDispatchToProps)(hot(module)(Component));
|
export const App = connect(mapStateToProps, mapDispatchToProps)(hot(module)(Component));
|
||||||
|
|
|
@ -32,3 +32,5 @@ export const setSaveSuccess = payload => ({ type: ACTIONS.SET_SAVE_SUCCESS, ...p
|
||||||
export const setSaveError = save_error => ({ type: ACTIONS.SET_SAVE_ERROR, save_error });
|
export const setSaveError = save_error => ({ type: ACTIONS.SET_SAVE_ERROR, save_error });
|
||||||
export const setSaveOverwrite = () => ({ type: ACTIONS.SET_SAVE_OVERWRITE });
|
export const setSaveOverwrite = () => ({ type: ACTIONS.SET_SAVE_OVERWRITE });
|
||||||
|
|
||||||
|
export const showRenderer = () => ({ type: ACTIONS.SHOW_RENDERER });
|
||||||
|
export const hideRenderer = () => ({ type: ACTIONS.HIDE_RENDERER });
|
||||||
|
|
|
@ -30,4 +30,7 @@ export const ACTIONS = {
|
||||||
SET_SAVE_SUCCESS: 'SET_SAVE_SUCCESS',
|
SET_SAVE_SUCCESS: 'SET_SAVE_SUCCESS',
|
||||||
SET_SAVE_ERROR: 'SET_SAVE_ERROR',
|
SET_SAVE_ERROR: 'SET_SAVE_ERROR',
|
||||||
SET_SAVE_OVERWRITE: 'SET_SAVE_OVERWRITE',
|
SET_SAVE_OVERWRITE: 'SET_SAVE_OVERWRITE',
|
||||||
|
|
||||||
|
SHOW_RENDERER: 'SHOW_RENDERER',
|
||||||
|
HIDE_RENDERER: 'HIDE_RENDERER',
|
||||||
};
|
};
|
||||||
|
|
|
@ -51,6 +51,9 @@ const resetSaveDialog = state => ({
|
||||||
...state, save_overwriting: false, save_finished: false, save_processing: false, save_error: '',
|
...state, save_overwriting: false, save_finished: false, save_processing: false, save_error: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const showRenderer = state => ({ ...state, renderer_active: true });
|
||||||
|
const hideRenderer = state => ({ ...state, renderer_active: false });
|
||||||
|
|
||||||
const HANDLERS = {
|
const HANDLERS = {
|
||||||
[ACTIONS.SET_USER]: setUser,
|
[ACTIONS.SET_USER]: setUser,
|
||||||
[ACTIONS.SET_EDITING]: setEditing,
|
[ACTIONS.SET_EDITING]: setEditing,
|
||||||
|
@ -68,6 +71,9 @@ const HANDLERS = {
|
||||||
[ACTIONS.SET_SAVE_SUCCESS]: setSaveSuccess,
|
[ACTIONS.SET_SAVE_SUCCESS]: setSaveSuccess,
|
||||||
[ACTIONS.SEND_SAVE_REQUEST]: sendSaveRequest,
|
[ACTIONS.SEND_SAVE_REQUEST]: sendSaveRequest,
|
||||||
[ACTIONS.RESET_SAVE_DIALOG]: resetSaveDialog,
|
[ACTIONS.RESET_SAVE_DIALOG]: resetSaveDialog,
|
||||||
|
|
||||||
|
[ACTIONS.SHOW_RENDERER]: showRenderer,
|
||||||
|
[ACTIONS.HIDE_RENDERER]: hideRenderer,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const INITIAL_STATE = {
|
export const INITIAL_STATE = {
|
||||||
|
@ -87,6 +93,8 @@ export const INITIAL_STATE = {
|
||||||
save_finished: false,
|
save_finished: false,
|
||||||
save_overwriting: false,
|
save_overwriting: false,
|
||||||
save_processing: false,
|
save_processing: false,
|
||||||
|
|
||||||
|
renderer_active: false
|
||||||
};
|
};
|
||||||
|
|
||||||
export const userReducer = createReducer(INITIAL_STATE, HANDLERS);
|
export const userReducer = createReducer(INITIAL_STATE, HANDLERS);
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
@import 'logo.less';
|
@import 'logo.less';
|
||||||
@import 'user-button.less';
|
@import 'user-button.less';
|
||||||
@import 'save.less';
|
@import 'save.less';
|
||||||
|
@import 'renderer.less';
|
||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: 'Rubik', sans-serif;
|
font-family: 'Rubik', sans-serif;
|
||||||
|
|
15
src/styles/renderer.less
Normal file
15
src/styles/renderer.less
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
.renderer-shade {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 1000;
|
||||||
|
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
|
||||||
|
//canvas {
|
||||||
|
// width: 50vw;
|
||||||
|
// height: 50vh;
|
||||||
|
//}
|
||||||
|
}
|
|
@ -55,7 +55,7 @@ export const getTilePlacement = () => {
|
||||||
maxY,
|
maxY,
|
||||||
|
|
||||||
shiftX: (rsw.x - msw.x),
|
shiftX: (rsw.x - msw.x),
|
||||||
shiftY: (height + (rsw.y - msw.y)),
|
shiftY: (height + (rsw.y - msw.y)) + 3,
|
||||||
|
|
||||||
size: 256,
|
size: 256,
|
||||||
width,
|
width,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue