1
0
mirror of https://github.com/kremalicious/blog.git synced 2024-12-22 09:13:35 +01:00

exif map component

This commit is contained in:
Matthias Kretschmann 2018-09-14 00:35:40 +02:00
parent 6a1c6f5770
commit 94eabe953b
Signed by: m
GPG Key ID: 606EEEF3C479A91F
5 changed files with 128 additions and 19 deletions

View File

@ -5,6 +5,7 @@ const { createFilePath } = require('gatsby-source-filesystem')
const { paginate } = require('gatsby-awesome-pagination')
const fastExif = require('fast-exif')
const Fraction = require('fraction.js')
const dms2dec = require('dms2dec')
const meta = yaml.load(fs.readFileSync('./content/meta.yml', 'utf8'))
const { itemsPerPage } = meta
@ -79,6 +80,12 @@ const createExifFields = (exifData, createNodeField, node) => {
FocalLength,
ExposureBiasValue
} = exifData.exif
const {
GPSLatitudeRef,
GPSLatitude,
GPSLongitudeRef,
GPSLongitude
} = exifData.gps
const { n, d } = new Fraction(ExposureTime)
const exposureShortened = parseFloat(ExposureBiasValue.toFixed(2))
@ -89,6 +96,16 @@ const createExifFields = (exifData, createNodeField, node) => {
const shutterspeed = `${n}/${d}s`
const focalLength = `${FocalLength}mm`
const GPSdec = dms2dec(
GPSLatitude,
GPSLatitudeRef,
GPSLongitude,
GPSLongitudeRef
)
const latitude = GPSdec[0]
const longitude = GPSdec[1]
let exposure
if (ExposureBiasValue === 0) {
@ -109,7 +126,11 @@ const createExifFields = (exifData, createNodeField, node) => {
fstop,
shutterspeed,
focalLength,
exposure
exposure,
gps: {
latitude,
longitude
}
}
})
}

View File

@ -22,6 +22,7 @@
"last 3 versions"
],
"dependencies": {
"dms2dec": "^1.1.0",
"fast-exif": "^1.0.1",
"fraction.js": "^4.0.9",
"gatsby": "^2.0.0-rc.21",
@ -49,6 +50,8 @@
"intersection-observer": "^0.5.0",
"node-sass": "^4.9.3",
"nord": "^0.2.1",
"pigeon-maps": "^0.10.4",
"pigeon-marker": "^0.3.4",
"prismjs": "^1.15.0",
"react": "^16.5.0",
"react-clipboard.js": "^2.0.0",

View File

@ -1,24 +1,92 @@
import React from 'react'
import React, { Fragment, PureComponent } from 'react'
import PropTypes from 'prop-types'
import Map from 'pigeon-maps'
import Marker from 'pigeon-marker/react'
import styles from './Exif.module.scss'
const Exif = ({ exif }) => {
const { iso, model, fstop, shutterspeed, focalLength, exposure } = exif
const MAPBOX_ACCESS_TOKEN =
'pk.eyJ1Ijoia3JlbWFsaWNpb3VzIiwiYSI6ImNqbTE2NHpkYjJmNm8zcHF4eDVqZzk3ejEifQ.1uwPzM6MSTgL2e1Hxcmuqw'
return (
<aside className={styles.exif}>
{model && <span title="Camera model">{model}</span>}
{fstop && <span title="Aperture">{fstop}</span>}
{shutterspeed && <span title="Shutter speed">{shutterspeed}</span>}
{exposure && <span title="Exposure">{exposure}</span>}
{iso && <span title="ISO">{iso}</span>}
{focalLength && <span title="Focal length">{focalLength}</span>}
</aside>
)
const mapbox = (mapboxId, accessToken) => (x, y, z) => {
const retina =
typeof window !== 'undefined' && window.devicePixelRatio >= 2 ? '@2x' : ''
return `https://api.mapbox.com/styles/v1/mapbox/${mapboxId}/tiles/256/${z}/${x}/${y}${retina}?access_token=${accessToken}`
}
Exif.propTypes = {
exif: PropTypes.object
const providers = {
osm: (x, y, z) => {
const s = String.fromCharCode(97 + ((x + y + z) % 3))
return `https://${s}.tile.openstreetmap.org/${z}/${x}/${y}.png`
},
wikimedia: (x, y, z) => {
const retina =
typeof window !== 'undefined' && window.devicePixelRatio >= 2 ? '@2x' : ''
return `https://maps.wikimedia.org/osm-intl/${z}/${x}/${y}${retina}.png`
},
stamen: (x, y, z) => {
const retina =
typeof window !== 'undefined' && window.devicePixelRatio >= 2 ? '@2x' : ''
return `https://stamen-tiles.a.ssl.fastly.net/terrain/${z}/${x}/${y}${retina}.jpg`
},
streets: mapbox('streets-v10', MAPBOX_ACCESS_TOKEN),
satellite: mapbox('satellite-streets-v10', MAPBOX_ACCESS_TOKEN),
outdoors: mapbox('outdoors-v10', MAPBOX_ACCESS_TOKEN),
light: mapbox('light-v9', MAPBOX_ACCESS_TOKEN),
dark: mapbox('dark-v9', MAPBOX_ACCESS_TOKEN)
}
export default Exif
class MapExif extends PureComponent {
static propTypes = {
gps: PropTypes.object
}
render() {
const { latitude, longitude } = this.props.gps
return (
<Map
center={[latitude, longitude]}
zoom={12}
height={160}
attribution={false}
provider={providers['light']}
>
<Marker anchor={[latitude, longitude]} payload={1} onClick={() => {}} />
</Map>
)
}
}
export default class Exif extends PureComponent {
static propTypes = {
exif: PropTypes.object
}
render() {
const {
iso,
model,
fstop,
shutterspeed,
focalLength,
exposure,
gps
} = this.props.exif
return (
<Fragment>
<aside className={styles.exif}>
<div className={styles.data}>
{model && <span title="Camera model">{model}</span>}
{fstop && <span title="Aperture">{fstop}</span>}
{shutterspeed && <span title="Shutter speed">{shutterspeed}</span>}
{exposure && <span title="Exposure">{exposure}</span>}
{iso && <span title="ISO">{iso}</span>}
{focalLength && <span title="Focal length">{focalLength}</span>}
</div>
<div className={styles.map}>{gps && <MapExif gps={gps} />}</div>
</aside>
</Fragment>
)
}
}

View File

@ -2,10 +2,13 @@
@import 'mixins';
.exif {
margin-top: -($spacer);
margin-bottom: $spacer * 2;
}
.data {
font-size: $font-size-mini;
color: $brand-grey-light;
margin-top: -($spacer * 1.25);
margin-bottom: $spacer * 2;
display: flex;
flex-wrap: wrap;
text-align: center;
@ -30,3 +33,13 @@
}
}
}
.map {
@include breakoutviewport;
border-radius: $border-radius;
overflow: hidden;
margin-top: $spacer / 2;
border: 1px solid $brand-grey-dimmed;
height: 160px;
}

View File

@ -81,6 +81,10 @@ export const pageQuery = graphql`
shutterspeed
focalLength
exposure
gps {
latitude
longitude
}
}
}
}