Add about, game, with feather-icons and leafletjs
This commit is contained in:
parent
daaf8524d7
commit
f1f87afbae
15
.editorconfig
Normal file
15
.editorconfig
Normal file
@ -0,0 +1,15 @@
|
||||
# EditorConfig is awesome: https://EditorConfig.org
|
||||
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = false
|
||||
insert_final_newline = false
|
||||
|
||||
[pug]
|
||||
indent_size = 2
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -59,3 +59,7 @@ typings/
|
||||
|
||||
# next.js build output
|
||||
.next
|
||||
|
||||
# IDE junks
|
||||
.vscode
|
||||
.ideas
|
4
app.js
4
app.js
@ -25,6 +25,10 @@ i18n.expressBind(app, {
|
||||
cookieName: 'locale'
|
||||
});
|
||||
|
||||
app.use('/dist/leaflet', express.static('node_modules/leaflet/dist'));
|
||||
app.use('/dist/feather', express.static('node_modules/feather-icons/dist'));
|
||||
|
||||
|
||||
app.use(function(req, res, next) {
|
||||
req.i18n.setLocaleFromQuery();
|
||||
req.i18n.setLocaleFromCookie();
|
||||
|
3
controllers/api.js
Normal file
3
controllers/api.js
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
function getRecord(req, res) {
|
||||
}
|
@ -1,8 +1,13 @@
|
||||
|
||||
function getIndex(req, res, next) {
|
||||
function getIndex(req, res) {
|
||||
res.render('index', { title: 'SoundBirder' });
|
||||
}
|
||||
|
||||
function getAbout(req, res) {
|
||||
res.render('about', { title: 'About SoundBirder' });
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getIndex,
|
||||
getAbout
|
||||
}
|
@ -1,4 +1,11 @@
|
||||
{
|
||||
"Home": "Home",
|
||||
"About": "About"
|
||||
"About": "About",
|
||||
"Game": "Game",
|
||||
"Contact": "Contact",
|
||||
"SoundBirder is an open-source web application to learn bird song identification. It is based on bird records from Xeno-Canto and data from eBird": "SoundBirder is an open-source web application to learn bird song identification. It is based on bird records from Xeno-Canto and data from eBird",
|
||||
"Author": "Author",
|
||||
"The project is made with ♥ by Samuel ORTION": "The project is made with ♥ by Samuel ORTION",
|
||||
"SoundBirder is an open-source web application to learn bird song identification. It is based on bird records from Xeno-Canto and data from eBird.": "SoundBirder is an open-source web application to learn bird song identification. It is based on bird records from Xeno-Canto and data from eBird.",
|
||||
"The project is made with ♥ by Samuel ORTION.": "The project is made with ♥ by Samuel ORTION."
|
||||
}
|
@ -1 +1,8 @@
|
||||
{}
|
||||
{
|
||||
"Game": "Jeu",
|
||||
"About": "À propos",
|
||||
"Contact": "Contact",
|
||||
"SoundBirder is an open-source web application to learn bird song identification. It is based on bird records from Xeno-Canto and data from eBird": "SoundBirder est une application web open-source qui permet d'apprendre à reconnaitre les chants d'oiseaux. Elle se base sur les enregistrements audio de Xeno-Canto est sur les données de répartitions d'eBird",
|
||||
"Author": "Auteur",
|
||||
"The project is made with ♥ by Samuel ORTION": "Ce projet est fait avec ♥ par Samuel ORTION"
|
||||
}
|
55
package-lock.json
generated
55
package-lock.json
generated
@ -12,8 +12,10 @@
|
||||
"cookie-parser": "~1.4.4",
|
||||
"debug": "~2.6.9",
|
||||
"express": "~4.16.1",
|
||||
"feather-icons": "^4.29.0",
|
||||
"http-errors": "~1.6.3",
|
||||
"i18n-2": "^0.7.3",
|
||||
"leaflet": "^1.8.0",
|
||||
"morgan": "~1.9.1",
|
||||
"pug": "^3.0.2"
|
||||
}
|
||||
@ -180,6 +182,11 @@
|
||||
"is-regex": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/classnames": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz",
|
||||
"integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA=="
|
||||
},
|
||||
"node_modules/combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
@ -241,6 +248,16 @@
|
||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
|
||||
},
|
||||
"node_modules/core-js": {
|
||||
"version": "3.24.1",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.24.1.tgz",
|
||||
"integrity": "sha512-0QTBSYSUZ6Gq21utGzkfITDylE8jWC9Ne1D2MrhvlsZBI1x39OdDIVbzSqtgMndIy6BlHxBXpMGqzZmnztg2rg==",
|
||||
"hasInstallScript": true,
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/core-js"
|
||||
}
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
@ -349,6 +366,15 @@
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/feather-icons": {
|
||||
"version": "4.29.0",
|
||||
"resolved": "https://registry.npmjs.org/feather-icons/-/feather-icons-4.29.0.tgz",
|
||||
"integrity": "sha512-Y7VqN9FYb8KdaSF0qD1081HCkm0v4Eq/fpfQYQnubpqi0hXx14k+gF9iqtRys1SIcTEi97xDi/fmsPFZ8xo0GQ==",
|
||||
"dependencies": {
|
||||
"classnames": "^2.2.5",
|
||||
"core-js": "^3.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/finalhandler": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz",
|
||||
@ -585,6 +611,11 @@
|
||||
"promise": "^7.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/leaflet": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.8.0.tgz",
|
||||
"integrity": "sha512-gwhMjFCQiYs3x/Sf+d49f10ERXaEFCPr+nVTryhAW8DWbMGqJqt9G4XuIaHmFW08zYvhgdzqXGr8AlW8v8dQkA=="
|
||||
},
|
||||
"node_modules/media-typer": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||
@ -1156,6 +1187,11 @@
|
||||
"is-regex": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"classnames": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz",
|
||||
"integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA=="
|
||||
},
|
||||
"combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
@ -1202,6 +1238,11 @@
|
||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
|
||||
},
|
||||
"core-js": {
|
||||
"version": "3.24.1",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.24.1.tgz",
|
||||
"integrity": "sha512-0QTBSYSUZ6Gq21utGzkfITDylE8jWC9Ne1D2MrhvlsZBI1x39OdDIVbzSqtgMndIy6BlHxBXpMGqzZmnztg2rg=="
|
||||
},
|
||||
"debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
@ -1294,6 +1335,15 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"feather-icons": {
|
||||
"version": "4.29.0",
|
||||
"resolved": "https://registry.npmjs.org/feather-icons/-/feather-icons-4.29.0.tgz",
|
||||
"integrity": "sha512-Y7VqN9FYb8KdaSF0qD1081HCkm0v4Eq/fpfQYQnubpqi0hXx14k+gF9iqtRys1SIcTEi97xDi/fmsPFZ8xo0GQ==",
|
||||
"requires": {
|
||||
"classnames": "^2.2.5",
|
||||
"core-js": "^3.1.3"
|
||||
}
|
||||
},
|
||||
"finalhandler": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz",
|
||||
@ -1467,6 +1517,11 @@
|
||||
"promise": "^7.0.1"
|
||||
}
|
||||
},
|
||||
"leaflet": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.8.0.tgz",
|
||||
"integrity": "sha512-gwhMjFCQiYs3x/Sf+d49f10ERXaEFCPr+nVTryhAW8DWbMGqJqt9G4XuIaHmFW08zYvhgdzqXGr8AlW8v8dQkA=="
|
||||
},
|
||||
"media-typer": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||
|
@ -10,8 +10,10 @@
|
||||
"cookie-parser": "~1.4.4",
|
||||
"debug": "~2.6.9",
|
||||
"express": "~4.16.1",
|
||||
"feather-icons": "^4.29.0",
|
||||
"http-errors": "~1.6.3",
|
||||
"i18n-2": "^0.7.3",
|
||||
"leaflet": "^1.8.0",
|
||||
"morgan": "~1.9.1",
|
||||
"pug": "^3.0.2"
|
||||
}
|
||||
|
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 41 KiB |
46
public/images/black-bird.svg
Normal file
46
public/images/black-bird.svg
Normal file
@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:cc="http://creativecommons.org/ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" id="svg39145" sodipodi:docname="_svgclean2.svg" viewBox="0 0 475.28 396.78" version="1.1" inkscape:version="0.48.5 r10040">
|
||||
<sodipodi:namedview id="namedview23" bordercolor="#666666" inkscape:pageshadow="2" guidetolerance="10" pagecolor="#ffffff" gridtolerance="10" inkscape:window-maximized="0" inkscape:zoom="0.22425739" objecttolerance="10" borderopacity="1" inkscape:current-layer="svg39145" inkscape:cx="38.071362" inkscape:cy="-15.497501" inkscape:window-y="0" inkscape:window-x="683" inkscape:window-width="681" showgrid="false" inkscape:pageopacity="0" inkscape:window-height="766"/>
|
||||
<defs id="defs39147">
|
||||
<linearGradient id="linearGradient39245" y2="428.08" gradientUnits="userSpaceOnUse" x2="-788.21" y1="428.08" x1="-897.51">
|
||||
<stop id="stop38892-5-5-7" style="stop-color:#000000;stop-opacity:.91373" offset="0"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="layer1" transform="translate(-333.98 -113.9)">
|
||||
<g id="g39232" transform="matrix(.58448 0 0 .58448 297.22 109.18)">
|
||||
<path id="path31178" style="stroke-opacity:.093567;fill-opacity:.74405;stroke-dashoffset:64.401;stroke:#000000;stroke-linecap:square;stroke-width:5.5533;fill:#1a1a1a" inkscape:connector-curvature="0" d="m320.34 624.59c11.023-14.204 19.973-30.2 30.528-44.804 9.5553-13.221 11.331-14.474 22.408-26.72 17.398-19.47 36.589-36.67 56.716-52.48 19.042-13.146 38.193-30.251 61.537-30.641 2.9729-0.0503 5.9362 0.38952 8.9043 0.58451 24.501 3.749 45.957 17.67 66.837 31.527 10.085 7.6291 20.822 14.287 30.664 22.318 4.3336 3.5359 7.7072 6.985 11.74 10.909 11.092 10.96 20.146 24.207 28.037 38.111 1.5411 2.6562 3.0823 5.3123 4.6234 7.9684l-28.837 18.735c-1.5295-2.6652-3.059-5.3301-4.5885-7.9953-7.8924-13.505-17.163-26.064-27.759-37.066-12.876-12.488-27.175-22.73-41.42-33.169-20.415-14.044-41.929-27.293-66.313-29.617-8.0656 0.0397-14.804 0.3999-22.559 3.0777-2.1695 0.74913-8.2722 4.0449-6.3934 2.6241 5.3274-4.0284 36.284-23.818 16.618-10.971-20.799 15.63-40.59 32.91-58.455 52.58-10.477 11.404-13.17 13.664-22.252 26.077-10.247 14.004-18.55 29.589-28.558 43.791l-31.478 15.16z"/>
|
||||
<path id="path28681-5" style="stroke-opacity:.093567;fill-opacity:.74405;stroke-dashoffset:64.401;stroke:#000000;stroke-linecap:square;stroke-width:6.44;fill:#ff6600" inkscape:connector-curvature="0" d="m-51.304 455.49c-1.1634-6.4894 84.495-43.289 86.064-48.204 1.5683-4.9151 14.551-144.39 19.628-143.92 5.0768 0.47402 97.709 145.05 100.71 150.01 2.999 4.9656-2.0368 55.225-5.7355 59.234-3.6988 4.0096-89.287-11.271-94.577-10.612-5.2901 0.65934-104.92-0.0215-106.09-6.5109z" transform="matrix(1.4496 -.47604 .47604 1.4496 -74.5 -284.99)"/>
|
||||
<path id="path28681-8-1" style="stroke-opacity:.093567;fill-opacity:.74405;stroke-dashoffset:64.401;stroke:#000000;stroke-linecap:square;stroke-width:6.44;fill:#ff6600" inkscape:connector-curvature="0" d="m-51.304 455.49c-1.1634-6.4894 84.495-43.289 86.064-48.204 1.5683-4.9151 14.551-144.39 19.628-143.92 5.0768 0.47402 97.709 145.05 100.71 150.01 2.999 4.9656-2.0368 55.225-5.7355 59.234-3.6988 4.0096-89.287-11.271-94.577-10.612-5.2901 0.65934-104.92-0.0215-106.09-6.5109z" transform="matrix(-.14358 -0.26 .57358 -.24637 104.25 764.53)"/>
|
||||
<path id="path39021-5" style="stroke-opacity:.94086;fill-opacity:.96237;stroke-dashoffset:64.401;stroke:#000000;stroke-linecap:square;stroke-width:6.44;fill:#0c000c" inkscape:connector-curvature="0" d="m-665.71 1049.5a171.43 177.14 0 1 1 -342.86 0 171.43 177.14 0 1 1 342.86 0z" transform="matrix(1.5257 0 0 1.5257 1745.5 -1318)"/>
|
||||
<path id="path39023-2" style="stroke-opacity:.94086;fill-opacity:.96237;stroke-dashoffset:64.401;stroke:#000000;stroke-linecap:square;stroke-width:6.44;fill:#0c000c" inkscape:connector-curvature="0" d="m-681.57 118.54c-8.746 19.054-421.55-32.079-426.48-48.481-4.9277-16.402 215.86-219.89 232.59-211.99 16.733 7.9016 202.64 241.41 193.89 260.47z" transform="matrix(-.13076 -.89838 1.023 -.11483 645.52 -494.19)"/>
|
||||
<g id="g38937-6-7" transform="matrix(.52159 0 0 .52976 -78.953 80.604)">
|
||||
<path id="path31180-4-2" style="stroke-opacity:.093567;fill-opacity:.74405;stroke-dashoffset:64.401;stroke:#000000;stroke-linecap:square;stroke-width:6.44;fill:#1a1a1a" inkscape:connector-curvature="0" d="m1408.6 683.79a248.57 220 0 1 1 -497.14 0 248.57 220 0 1 1 497.14 0z" transform="translate(-202.86 -400)"/>
|
||||
<g id="g38896-0-1-9" transform="matrix(1.1321 0 0 1.0127 1880.7 -117.02)">
|
||||
<path id="path38820-7-7-7" style="stroke-opacity:.94086;fill-opacity:.74405;stroke-dashoffset:64.401;stroke:#000000;stroke-linecap:square;stroke-width:6.44;fill:#ff6600" inkscape:connector-curvature="0" d="m-742.86 419.51a105.71 118.57 0 1 1 -211.43 0 105.71 118.57 0 1 1 211.43 0z" transform="matrix(1 0 0 .92637 0 39.617)"/>
|
||||
<path id="path38822-3-0-6" style="stroke-opacity:.96774;fill-opacity:.96237;stroke-dashoffset:64.401;stroke:url(#linearGradient39245);stroke-linecap:square;stroke-width:6.44;fill:#0c000c" inkscape:connector-curvature="0" d="m-791.43 428.08a51.429 44.286 0 1 1 -102.86 0 51.429 44.286 0 1 1 102.86 0z" transform="matrix(1.2045 0 0 1.3665 169.51 -154.04)"/>
|
||||
</g>
|
||||
</g>
|
||||
<path id="path28681-8-3" style="stroke-opacity:.093567;fill-opacity:.74405;stroke-dashoffset:64.401;stroke:#000000;stroke-linecap:square;stroke-width:6.44;fill:#ff6600" inkscape:connector-curvature="0" d="m-51.304 455.49c-1.1634-6.4894 84.495-43.289 86.064-48.204 1.5683-4.9151 14.551-144.39 19.628-143.92 5.0768 0.47402 97.709 145.05 100.71 150.01 2.999 4.9656-2.0368 55.225-5.7355 59.234-3.6988 4.0096-89.287-11.271-94.577-10.612-5.2901 0.65934-104.92-0.0215-106.09-6.5109z" transform="matrix(-.16872 -.24443 .54625 -.30218 412.36 758.51)"/>
|
||||
</g>
|
||||
</g>
|
||||
<metadata id="metadata21">
|
||||
<rdf:RDF>
|
||||
<cc:Work>
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<cc:license rdf:resource="http://creativecommons.org/licenses/publicdomain/"/>
|
||||
<dc:publisher>
|
||||
<cc:Agent rdf:about="http://openclipart.org/">
|
||||
<dc:title>Openclipart</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:publisher>
|
||||
</cc:Work>
|
||||
<cc:License rdf:about="http://creativecommons.org/licenses/publicdomain/">
|
||||
<cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction"/>
|
||||
<cc:permits rdf:resource="http://creativecommons.org/ns#Distribution"/>
|
||||
<cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks"/>
|
||||
</cc:License>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
</svg>
|
After Width: | Height: | Size: 6.8 KiB |
BIN
public/images/logo.png
Normal file
BIN
public/images/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.9 KiB |
162
public/images/logo.svg
Normal file
162
public/images/logo.svg
Normal file
@ -0,0 +1,162 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
id="svg39145"
|
||||
sodipodi:docname="logo.svg"
|
||||
viewBox="0 0 100 100"
|
||||
version="1.1"
|
||||
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
|
||||
width="100"
|
||||
height="100"
|
||||
inkscape:export-filename="logo.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<sodipodi:namedview
|
||||
id="namedview23"
|
||||
bordercolor="#666666"
|
||||
inkscape:pageshadow="2"
|
||||
guidetolerance="10"
|
||||
pagecolor="#ffffff"
|
||||
gridtolerance="10"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:zoom="8.1139514"
|
||||
objecttolerance="10"
|
||||
borderopacity="1"
|
||||
inkscape:current-layer="svg39145"
|
||||
inkscape:cx="24.83377"
|
||||
inkscape:cy="42.889091"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-width="1920"
|
||||
showgrid="false"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:window-height="1011"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1" />
|
||||
<defs
|
||||
id="defs39147">
|
||||
<linearGradient
|
||||
id="linearGradient39245"
|
||||
y2="428.07999"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x2="-788.21002"
|
||||
y1="428.07999"
|
||||
x1="-897.51001">
|
||||
<stop
|
||||
id="stop38892-5-5-7"
|
||||
style="stop-color:#000000;stop-opacity:.91373"
|
||||
offset="0" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<circle
|
||||
style="fill:#ffffff;stroke:none;stroke-width:1.60237"
|
||||
id="path300"
|
||||
cx="50.076645"
|
||||
cy="49.982933"
|
||||
r="48.902069" />
|
||||
<g
|
||||
id="layer1"
|
||||
transform="matrix(0.17366504,0,0,0.17366504,-45.733241,2.1385579)">
|
||||
<g
|
||||
id="g39232"
|
||||
transform="matrix(0.58448,0,0,0.58448,297.22,109.18)">
|
||||
<path
|
||||
id="path31178"
|
||||
style="fill:#1a1a1a;fill-opacity:0.74405;stroke:#000000;stroke-width:5.5533;stroke-linecap:square;stroke-dashoffset:64.401;stroke-opacity:0.093567"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 320.34,624.59 c 11.023,-14.204 19.973,-30.2 30.528,-44.804 9.5553,-13.221 11.331,-14.474 22.408,-26.72 17.398,-19.47 36.589,-36.67 56.716,-52.48 19.042,-13.146 38.193,-30.251 61.537,-30.641 2.9729,-0.0503 5.9362,0.38952 8.9043,0.58451 24.501,3.749 45.957,17.67 66.837,31.527 10.085,7.6291 20.822,14.287 30.664,22.318 4.3336,3.5359 7.7072,6.985 11.74,10.909 11.092,10.96 20.146,24.207 28.037,38.111 1.5411,2.6562 3.0823,5.3123 4.6234,7.9684 l -28.837,18.735 c -1.5295,-2.6652 -3.059,-5.3301 -4.5885,-7.9953 -7.8924,-13.505 -17.163,-26.064 -27.759,-37.066 -12.876,-12.488 -27.175,-22.73 -41.42,-33.169 -20.415,-14.044 -41.929,-27.293 -66.313,-29.617 -8.0656,0.0397 -14.804,0.3999 -22.559,3.0777 -2.1695,0.74913 -8.2722,4.0449 -6.3934,2.6241 5.3274,-4.0284 36.284,-23.818 16.618,-10.971 -20.799,15.63 -40.59,32.91 -58.455,52.58 -10.477,11.404 -13.17,13.664 -22.252,26.077 -10.247,14.004 -18.55,29.589 -28.558,43.791 l -31.478,15.16 z" />
|
||||
<path
|
||||
id="path28681-5"
|
||||
style="fill:#ff6600;fill-opacity:0.74405;stroke:#000000;stroke-width:6.44;stroke-linecap:square;stroke-dashoffset:64.401;stroke-opacity:0.093567"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m -51.304,455.49 c -1.1634,-6.4894 84.495,-43.289 86.064,-48.204 1.5683,-4.9151 14.551,-144.39 19.628,-143.92 5.0768,0.47402 97.709,145.05 100.71,150.01 2.999,4.9656 -2.0368,55.225 -5.7355,59.234 -3.6988,4.0096 -89.287,-11.271 -94.577,-10.612 -5.2901,0.65934 -104.92,-0.0215 -106.09,-6.5109 z"
|
||||
transform="matrix(1.4496,-0.47604,0.47604,1.4496,-74.5,-284.99)" />
|
||||
<path
|
||||
id="path28681-8-1"
|
||||
style="fill:#ff6600;fill-opacity:0.74405;stroke:#000000;stroke-width:6.44;stroke-linecap:square;stroke-dashoffset:64.401;stroke-opacity:0.093567"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m -51.304,455.49 c -1.1634,-6.4894 84.495,-43.289 86.064,-48.204 1.5683,-4.9151 14.551,-144.39 19.628,-143.92 5.0768,0.47402 97.709,145.05 100.71,150.01 2.999,4.9656 -2.0368,55.225 -5.7355,59.234 -3.6988,4.0096 -89.287,-11.271 -94.577,-10.612 -5.2901,0.65934 -104.92,-0.0215 -106.09,-6.5109 z"
|
||||
transform="matrix(-0.14358,-0.26,0.57358,-0.24637,104.25,764.53)" />
|
||||
<path
|
||||
id="path39021-5"
|
||||
style="fill:#0c000c;fill-opacity:0.96237;stroke:#000000;stroke-width:6.44;stroke-linecap:square;stroke-dashoffset:64.401;stroke-opacity:0.94086"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m -665.71,1049.5 a 171.43,177.14 0 1 1 -342.86,0 171.43,177.14 0 1 1 342.86,0 z"
|
||||
transform="matrix(1.5257,0,0,1.5257,1745.5,-1318)" />
|
||||
<path
|
||||
id="path39023-2"
|
||||
style="fill:#0c000c;fill-opacity:0.96237;stroke:#000000;stroke-width:6.44;stroke-linecap:square;stroke-dashoffset:64.401;stroke-opacity:0.94086"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m -681.57,118.54 c -8.746,19.054 -421.55,-32.079 -426.48,-48.481 -4.9277,-16.402 215.86,-219.89 232.59,-211.99 16.733,7.9016 202.64,241.41 193.89,260.47 z"
|
||||
transform="matrix(-0.13076,-0.89838,1.023,-0.11483,645.52,-494.19)" />
|
||||
<g
|
||||
id="g38937-6-7"
|
||||
transform="matrix(0.52159,0,0,0.52976,-78.953,80.604)">
|
||||
<path
|
||||
id="path31180-4-2"
|
||||
style="fill:#1a1a1a;fill-opacity:0.74405;stroke:#000000;stroke-width:6.44;stroke-linecap:square;stroke-dashoffset:64.401;stroke-opacity:0.093567"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 1408.6,683.79 a 248.57,220 0 1 1 -497.14,0 248.57,220 0 1 1 497.14,0 z"
|
||||
transform="translate(-202.86,-400)" />
|
||||
<g
|
||||
id="g38896-0-1-9"
|
||||
transform="matrix(1.1321,0,0,1.0127,1880.7,-117.02)">
|
||||
<path
|
||||
id="path38820-7-7-7"
|
||||
style="fill:#ff6600;fill-opacity:0.74405;stroke:#000000;stroke-width:6.44;stroke-linecap:square;stroke-dashoffset:64.401;stroke-opacity:0.94086"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m -742.86,419.51 a 105.715,118.57561 0 1 1 -211.43,0 105.715,118.57561 0 1 1 211.43,0 z"
|
||||
transform="matrix(1,0,0,0.92637,0,39.617)" />
|
||||
<path
|
||||
id="path38822-3-0-6"
|
||||
style="fill:#0c000c;fill-opacity:0.96237;stroke:url(#linearGradient39245);stroke-width:6.44;stroke-linecap:square;stroke-dashoffset:64.401;stroke-opacity:0.96774"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m -791.43,428.08 a 51.43,44.286861 0 1 1 -102.86,0 51.43,44.286861 0 1 1 102.86,0 z"
|
||||
transform="matrix(1.2045,0,0,1.3665,169.51,-154.04)" />
|
||||
</g>
|
||||
</g>
|
||||
<path
|
||||
id="path28681-8-3"
|
||||
style="fill:#ff6600;fill-opacity:0.74405;stroke:#000000;stroke-width:6.44;stroke-linecap:square;stroke-dashoffset:64.401;stroke-opacity:0.093567"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m -51.304,455.49 c -1.1634,-6.4894 84.495,-43.289 86.064,-48.204 1.5683,-4.9151 14.551,-144.39 19.628,-143.92 5.0768,0.47402 97.709,145.05 100.71,150.01 2.999,4.9656 -2.0368,55.225 -5.7355,59.234 -3.6988,4.0096 -89.287,-11.271 -94.577,-10.612 -5.2901,0.65934 -104.92,-0.0215 -106.09,-6.5109 z"
|
||||
transform="matrix(-0.16872,-0.24443,0.54625,-0.30218,412.36,758.51)" />
|
||||
</g>
|
||||
</g>
|
||||
<metadata
|
||||
id="metadata21">
|
||||
<rdf:RDF>
|
||||
<cc:Work>
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<cc:license
|
||||
rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
|
||||
<dc:publisher>
|
||||
<cc:Agent
|
||||
rdf:about="http://openclipart.org/">
|
||||
<dc:title>Openclipart</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:publisher>
|
||||
</cc:Work>
|
||||
<cc:License
|
||||
rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#Reproduction" />
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#Distribution" />
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
|
||||
</cc:License>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
</svg>
|
After Width: | Height: | Size: 8.2 KiB |
13
public/javascripts/app.js
Normal file
13
public/javascripts/app.js
Normal file
@ -0,0 +1,13 @@
|
||||
|
||||
import { geoLocationHandler } from './map.js';
|
||||
import './game.js';
|
||||
|
||||
feather.replace();
|
||||
|
||||
(function () {
|
||||
if (document.getElementById('map') != undefined)
|
||||
geoLocationHandler();
|
||||
let start_button = document.querySelector('.game .start-button');
|
||||
if (start_button != undefined)
|
||||
start_button.addEventListener('click', launchGame);
|
||||
}());
|
15
public/javascripts/game.js
Normal file
15
public/javascripts/game.js
Normal file
@ -0,0 +1,15 @@
|
||||
const API_VERSION = "1";
|
||||
|
||||
function launch() {
|
||||
|
||||
}
|
||||
|
||||
function get_new_record() {
|
||||
const endpoint = `/api/${API_VERSION}/record`;
|
||||
}
|
||||
|
||||
const Game = {
|
||||
launch
|
||||
}
|
||||
|
||||
export default Game;
|
44
public/javascripts/map.js
Normal file
44
public/javascripts/map.js
Normal file
@ -0,0 +1,44 @@
|
||||
import { getCookie, setCookie } from './utils.js'
|
||||
|
||||
function geoLocationHandler() {
|
||||
let location = [51.505, -0.09]; // London by default on leaflet
|
||||
let lat = getCookie("lat");
|
||||
let lng = getCookie("lng");
|
||||
if (lat != undefined && lng != undefined) {
|
||||
location = [lat, lng];
|
||||
console.log(`Got a previous geolocation cookie at ${location[0]}, ${location[1]}`)
|
||||
}
|
||||
let message = document.querySelector('.message');
|
||||
// Init map
|
||||
let map = L.map('map').setView(location, 15);
|
||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'
|
||||
}).addTo(map);
|
||||
// Init marker
|
||||
let marker = L.marker(location).addTo(map);
|
||||
|
||||
// Get geolocation
|
||||
function getLocation() {
|
||||
if (navigator.geolocation) {
|
||||
navigator.geolocation.getCurrentPosition(setLocation);
|
||||
} else {
|
||||
message.innerHTML = "Geolocation is not supported by this browser.";
|
||||
}
|
||||
}
|
||||
|
||||
function setLocation(position) {
|
||||
location = [position.coords.latitude, position.coords.longitude];
|
||||
marker.setLatLng(location);
|
||||
map.setView(location, 15);
|
||||
setCookie("lat", position.coords.latitude, 10);
|
||||
setCookie("lng", position.coords.longitude, 10);
|
||||
console.log("Geolocation cookie saved for future games");
|
||||
}
|
||||
|
||||
document.querySelector('.geolocation-button')
|
||||
.addEventListener('click', getLocation);
|
||||
}
|
||||
|
||||
export {
|
||||
geoLocationHandler
|
||||
}
|
27
public/javascripts/utils.js
Normal file
27
public/javascripts/utils.js
Normal file
@ -0,0 +1,27 @@
|
||||
function setCookie(cname, cvalue, exdays) {
|
||||
const d = new Date();
|
||||
d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
|
||||
let expires = "expires=" + d.toUTCString();
|
||||
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
|
||||
}
|
||||
|
||||
function getCookie(cname) {
|
||||
let name = cname + "=";
|
||||
let decodedCookie = decodeURIComponent(document.cookie);
|
||||
let ca = decodedCookie.split(';');
|
||||
for (let i = 0; i < ca.length; i++) {
|
||||
let c = ca[i];
|
||||
while (c.charAt(0) == ' ') {
|
||||
c = c.substring(1);
|
||||
}
|
||||
if (c.indexOf(name) == 0) {
|
||||
return c.substring(name.length, c.length);
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export {
|
||||
getCookie,
|
||||
setCookie
|
||||
}
|
@ -7,6 +7,10 @@ body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
body > * {
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
.link {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
@ -37,9 +41,7 @@ body {
|
||||
footer {
|
||||
color: white;
|
||||
background-color: black;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
bottom: 0;
|
||||
width: 100vw;
|
||||
padding: 2rem;
|
||||
}
|
||||
@ -47,3 +49,23 @@ footer {
|
||||
footer .link:after {
|
||||
border-bottom: 2px dotted white;
|
||||
}
|
||||
|
||||
main {
|
||||
min-height: calc(100vh - 15em);
|
||||
}
|
||||
|
||||
#map { height: 50vh; }
|
||||
|
||||
nav {
|
||||
|
||||
}
|
||||
|
||||
nav li {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
nav ul {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
@ -3,6 +3,10 @@ var router = express.Router();
|
||||
var homeController = require('../controllers/home');
|
||||
/* GET home page. */
|
||||
router.route('/')
|
||||
.get(homeController.getIndex);
|
||||
.get(homeController.getIndex);
|
||||
|
||||
router.route('/about')
|
||||
.get(homeController.getAbout);
|
||||
|
||||
|
||||
module.exports = router;
|
||||
|
8
views/about.pug
Normal file
8
views/about.pug
Normal file
@ -0,0 +1,8 @@
|
||||
extends layout.pug
|
||||
|
||||
block content
|
||||
p #{ __("SoundBirder is an open-source web application to learn bird song identification. It is based on bird records from Xeno-Canto and data from eBird.") }
|
||||
|
||||
h2 #{ __("Author") }
|
||||
p #{ __("The project is made with ♥ by Samuel ORTION.") }
|
||||
|
8
views/game.pug
Normal file
8
views/game.pug
Normal file
@ -0,0 +1,8 @@
|
||||
.game
|
||||
#map
|
||||
button.button.geolocation-button
|
||||
i(data-feather="map-pin")
|
||||
button.button.start-button
|
||||
i(data-feather="play")
|
||||
link(rel="stylesheet", href="/dist/leaflet/leaflet.css")
|
||||
script(src="/dist/leaflet/leaflet.js")
|
@ -1,4 +1,4 @@
|
||||
extends layout
|
||||
|
||||
block content
|
||||
|
||||
include game
|
||||
|
@ -2,23 +2,25 @@ doctype html
|
||||
html
|
||||
head
|
||||
title= title
|
||||
meta(name="viewport", content="width=device-width, initial-scale=1.0")
|
||||
link(rel='stylesheet', href='/stylesheets/style.css')
|
||||
meta(name="iewport", content="width=device-width, initial-scale=1.0")
|
||||
link(rel="stylesheet", href="/stylesheets/style.css")
|
||||
body
|
||||
header
|
||||
h1= title
|
||||
nav
|
||||
ul
|
||||
li
|
||||
a(href='/') #{ __('Home') }
|
||||
a(href="/") #{ __("Game") }
|
||||
li
|
||||
a(href='/about') #{ __('About') }
|
||||
a(href="/about") #{ __("About") }
|
||||
li
|
||||
a(href='/contact') Contact
|
||||
block content
|
||||
a(href="/contact") #{ __("Contact") }
|
||||
main
|
||||
block content
|
||||
footer
|
||||
.description
|
||||
|
||||
.copyright Copyright © 2022 -
|
||||
span.author
|
||||
a(href="//samuel.ortion.fr", class="link") Samuel ORTION
|
||||
a(href="https://samuel.ortion.fr", class="link") Samuel ORTION
|
||||
script(src="/javascripts/app.js" type="module")
|
||||
script(src="/dist/feather/feather.min.js")
|
Loading…
Reference in New Issue
Block a user