mirror of
https://github.com/mickael-kerjean/filestash.git
synced 2025-10-30 01:26:43 +08:00
127 lines
5.6 KiB
JavaScript
127 lines
5.6 KiB
JavaScript
import React from 'react';
|
|
import { debounce } from '../helpers/';
|
|
import { Icon, Loader, NgIf } from './';
|
|
import './mapshot.scss';
|
|
|
|
export class MapShot extends React.Component {
|
|
constructor(props){
|
|
super(props);
|
|
this.state = {
|
|
tile_size: 0,
|
|
tile_loaded: 0,
|
|
error: false
|
|
};
|
|
this.onRefresh = this.onRefresh.bind(this);
|
|
}
|
|
|
|
onRefresh(){
|
|
requestAnimationFrame(() => {
|
|
if(this.refs.$wrapper){
|
|
this.setState({
|
|
tile_size: this.calculateSize()
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
calculateSize(){
|
|
if(!this.refs.$wrapper) return 0;
|
|
return parseInt(this.refs.$wrapper.clientWidth / 3 * 100) / 100;
|
|
}
|
|
|
|
|
|
componentDidMount(){
|
|
this.onRefresh();
|
|
window.addEventListener("resize", this.onRefresh);
|
|
}
|
|
|
|
componentWillUnmount(){
|
|
window.removeEventListener("resize", this.onRefresh);
|
|
}
|
|
|
|
insert_marker(position){
|
|
if(!(this.state.tile_size > 0)) return null;
|
|
return (
|
|
<div className="marker" style={{
|
|
left: this.state.tile_size * (1 + position[0]) - 15,
|
|
top: this.state.tile_size * (1 + position[1]) - 30 }}>
|
|
<Icon name="location"/>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
onLoad(){
|
|
this.setState({tile_loaded: this.state.tile_loaded + 1});
|
|
}
|
|
onError(){
|
|
this.setState({error: true});
|
|
}
|
|
|
|
render(){
|
|
if(this.calculateSize() !== this.state.tile_size && this.calculateSize() !== 0){
|
|
this.onRefresh();
|
|
}
|
|
const tile_server = this.props.tile || "https://maps.wikimedia.org/osm-intl/${z}/${x}/${y}.png";
|
|
function map_url(lat, lng, zoom){
|
|
// https://wiki.openstreetmap.org/wiki/Slippy_map_tilenamse
|
|
const n = Math.pow(2, zoom);
|
|
const tile_numbers = [
|
|
(lng+180)/360*n,
|
|
(1-Math.log(Math.tan(lat*Math.PI/180) + 1/Math.cos(lat*Math.PI/180))/Math.PI)/2*n,
|
|
zoom
|
|
];
|
|
return {
|
|
tile: function(tile_server, x = 0, y = 0){
|
|
return tile_server
|
|
.replace("${x}", Math.floor(tile_numbers[0])+x)
|
|
.replace("${y}", Math.floor(tile_numbers[1])+y)
|
|
.replace("${z}", Math.floor(zoom));
|
|
},
|
|
position: function(){
|
|
return [
|
|
tile_numbers[0] - Math.floor(tile_numbers[0]),
|
|
tile_numbers[1] - Math.floor(tile_numbers[1]),
|
|
];
|
|
}
|
|
};
|
|
}
|
|
const mapper = map_url(this.props.lat, this.props.lng, 11);
|
|
const center= (position, i) => {
|
|
return parseInt(this.state.tile_size * (1 + position[i]) * 1000)/1000;
|
|
};
|
|
return (
|
|
<div ref="$wrapper" className={"component_mapshot"+(this.state.tile_loaded === 9 ? " loaded" : "")+(this.state.error === true ? " error": "")} style={{height: (this.state.tile_size*3)+"px"}}>
|
|
<div className="wrapper">
|
|
<div className="mapshot_placeholder error">
|
|
<span><div>ERROR</div></span>
|
|
</div>
|
|
<div className="mapshot_placeholder loading">
|
|
<Loader/>
|
|
</div>
|
|
<a href={"https://www.google.com/maps/search/?api=1&query="+this.props.lat+","+this.props.lng}>
|
|
{this.insert_marker(mapper.position())}
|
|
<div className="bigpicture" style={{transformOrigin: center(mapper.position(), 0)+"px "+center(mapper.position(), 1)+"px"}}>
|
|
<div className="line">
|
|
<img onLoad={this.onLoad.bind(this)} onError={this.onError.bind(this)} src={mapper.tile(tile_server, -1, -1)} ref="$tile" style={{height: this.state.tile_size+"px"}} className="btl"/>
|
|
<img onLoad={this.onLoad.bind(this)} onError={this.onError.bind(this)} src={mapper.tile(tile_server, 0, -1)} style={{height: this.state.tile_size+"px"}}/>
|
|
<img onLoad={this.onLoad.bind(this)} onError={this.onError.bind(this)} src={mapper.tile(tile_server, 1, -1)} style={{height: this.state.tile_size+"px"}} className="btr"/>
|
|
</div>
|
|
<div className="line">
|
|
<img onLoad={this.onLoad.bind(this)} onError={this.onError.bind(this)} src={mapper.tile(tile_server, -1, 0)} style={{height: this.state.tile_size+"px"}}/>
|
|
<img onLoad={this.onLoad.bind(this)} onError={this.onError.bind(this)} src={mapper.tile(tile_server, 0, 0)} style={{height: this.state.tile_size+"px"}}/>
|
|
<img onLoad={this.onLoad.bind(this)} onError={this.onError.bind(this)} src={mapper.tile(tile_server, 1, 0)} style={{height: this.state.tile_size+"px"}}/>
|
|
</div>
|
|
<div className="line">
|
|
<img onLoad={this.onLoad.bind(this)} onError={this.onError.bind(this)} src={mapper.tile(tile_server, -1, 1)} style={{height: this.state.tile_size+"px"}} className="bbl"/>
|
|
<img onLoad={this.onLoad.bind(this)} onError={this.onError.bind(this)} src={mapper.tile(tile_server, 0, 1)} style={{height: this.state.tile_size+"px"}}/>
|
|
<img onLoad={this.onLoad.bind(this)} onError={this.onError.bind(this)} src={mapper.tile(tile_server, 1, 1)} style={{height: this.state.tile_size+"px"}} className="bbr"/>
|
|
</div>
|
|
</div>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
}
|