mirror of
https://github.com/kremalicious/blog.git
synced 2024-12-22 17:23:50 +01:00
exif map component
This commit is contained in:
parent
6a1c6f5770
commit
94eabe953b
@ -5,6 +5,7 @@ const { createFilePath } = require('gatsby-source-filesystem')
|
|||||||
const { paginate } = require('gatsby-awesome-pagination')
|
const { paginate } = require('gatsby-awesome-pagination')
|
||||||
const fastExif = require('fast-exif')
|
const fastExif = require('fast-exif')
|
||||||
const Fraction = require('fraction.js')
|
const Fraction = require('fraction.js')
|
||||||
|
const dms2dec = require('dms2dec')
|
||||||
|
|
||||||
const meta = yaml.load(fs.readFileSync('./content/meta.yml', 'utf8'))
|
const meta = yaml.load(fs.readFileSync('./content/meta.yml', 'utf8'))
|
||||||
const { itemsPerPage } = meta
|
const { itemsPerPage } = meta
|
||||||
@ -79,6 +80,12 @@ const createExifFields = (exifData, createNodeField, node) => {
|
|||||||
FocalLength,
|
FocalLength,
|
||||||
ExposureBiasValue
|
ExposureBiasValue
|
||||||
} = exifData.exif
|
} = exifData.exif
|
||||||
|
const {
|
||||||
|
GPSLatitudeRef,
|
||||||
|
GPSLatitude,
|
||||||
|
GPSLongitudeRef,
|
||||||
|
GPSLongitude
|
||||||
|
} = exifData.gps
|
||||||
|
|
||||||
const { n, d } = new Fraction(ExposureTime)
|
const { n, d } = new Fraction(ExposureTime)
|
||||||
const exposureShortened = parseFloat(ExposureBiasValue.toFixed(2))
|
const exposureShortened = parseFloat(ExposureBiasValue.toFixed(2))
|
||||||
@ -89,6 +96,16 @@ const createExifFields = (exifData, createNodeField, node) => {
|
|||||||
const shutterspeed = `${n}/${d}s`
|
const shutterspeed = `${n}/${d}s`
|
||||||
const focalLength = `${FocalLength}mm`
|
const focalLength = `${FocalLength}mm`
|
||||||
|
|
||||||
|
const GPSdec = dms2dec(
|
||||||
|
GPSLatitude,
|
||||||
|
GPSLatitudeRef,
|
||||||
|
GPSLongitude,
|
||||||
|
GPSLongitudeRef
|
||||||
|
)
|
||||||
|
|
||||||
|
const latitude = GPSdec[0]
|
||||||
|
const longitude = GPSdec[1]
|
||||||
|
|
||||||
let exposure
|
let exposure
|
||||||
|
|
||||||
if (ExposureBiasValue === 0) {
|
if (ExposureBiasValue === 0) {
|
||||||
@ -109,7 +126,11 @@ const createExifFields = (exifData, createNodeField, node) => {
|
|||||||
fstop,
|
fstop,
|
||||||
shutterspeed,
|
shutterspeed,
|
||||||
focalLength,
|
focalLength,
|
||||||
exposure
|
exposure,
|
||||||
|
gps: {
|
||||||
|
latitude,
|
||||||
|
longitude
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
"last 3 versions"
|
"last 3 versions"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"dms2dec": "^1.1.0",
|
||||||
"fast-exif": "^1.0.1",
|
"fast-exif": "^1.0.1",
|
||||||
"fraction.js": "^4.0.9",
|
"fraction.js": "^4.0.9",
|
||||||
"gatsby": "^2.0.0-rc.21",
|
"gatsby": "^2.0.0-rc.21",
|
||||||
@ -49,6 +50,8 @@
|
|||||||
"intersection-observer": "^0.5.0",
|
"intersection-observer": "^0.5.0",
|
||||||
"node-sass": "^4.9.3",
|
"node-sass": "^4.9.3",
|
||||||
"nord": "^0.2.1",
|
"nord": "^0.2.1",
|
||||||
|
"pigeon-maps": "^0.10.4",
|
||||||
|
"pigeon-marker": "^0.3.4",
|
||||||
"prismjs": "^1.15.0",
|
"prismjs": "^1.15.0",
|
||||||
"react": "^16.5.0",
|
"react": "^16.5.0",
|
||||||
"react-clipboard.js": "^2.0.0",
|
"react-clipboard.js": "^2.0.0",
|
||||||
|
@ -1,24 +1,92 @@
|
|||||||
import React from 'react'
|
import React, { Fragment, PureComponent } from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
import Map from 'pigeon-maps'
|
||||||
|
import Marker from 'pigeon-marker/react'
|
||||||
import styles from './Exif.module.scss'
|
import styles from './Exif.module.scss'
|
||||||
|
|
||||||
const Exif = ({ exif }) => {
|
const MAPBOX_ACCESS_TOKEN =
|
||||||
const { iso, model, fstop, shutterspeed, focalLength, exposure } = exif
|
'pk.eyJ1Ijoia3JlbWFsaWNpb3VzIiwiYSI6ImNqbTE2NHpkYjJmNm8zcHF4eDVqZzk3ejEifQ.1uwPzM6MSTgL2e1Hxcmuqw'
|
||||||
|
|
||||||
return (
|
const mapbox = (mapboxId, accessToken) => (x, y, z) => {
|
||||||
<aside className={styles.exif}>
|
const retina =
|
||||||
{model && <span title="Camera model">{model}</span>}
|
typeof window !== 'undefined' && window.devicePixelRatio >= 2 ? '@2x' : ''
|
||||||
{fstop && <span title="Aperture">{fstop}</span>}
|
return `https://api.mapbox.com/styles/v1/mapbox/${mapboxId}/tiles/256/${z}/${x}/${y}${retina}?access_token=${accessToken}`
|
||||||
{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>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Exif.propTypes = {
|
const providers = {
|
||||||
exif: PropTypes.object
|
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>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -2,10 +2,13 @@
|
|||||||
@import 'mixins';
|
@import 'mixins';
|
||||||
|
|
||||||
.exif {
|
.exif {
|
||||||
|
margin-top: -($spacer);
|
||||||
|
margin-bottom: $spacer * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data {
|
||||||
font-size: $font-size-mini;
|
font-size: $font-size-mini;
|
||||||
color: $brand-grey-light;
|
color: $brand-grey-light;
|
||||||
margin-top: -($spacer * 1.25);
|
|
||||||
margin-bottom: $spacer * 2;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
text-align: center;
|
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;
|
||||||
|
}
|
||||||
|
@ -81,6 +81,10 @@ export const pageQuery = graphql`
|
|||||||
shutterspeed
|
shutterspeed
|
||||||
focalLength
|
focalLength
|
||||||
exposure
|
exposure
|
||||||
|
gps {
|
||||||
|
latitude
|
||||||
|
longitude
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user