new version
@@ -3,23 +3,25 @@
|
||||
<h1>Geschenkeliste</h1>
|
||||
<p>
|
||||
Ihr macht uns die größte Freude, wenn ihr mit uns feiert und den Tag verbringt. Wenn ihr uns gerne etwas
|
||||
schenken möchtet, haben wir eine Liste zusammengestellt, worüber wir uns für den Start ins gemeinsame Leben
|
||||
sehr freuen. Außerdem lieben wir es zu reisen und freuen uns immer über Geld für unsere Reisekasse. Falls
|
||||
ihr euch unten in der Liste etwas ausgesucht habt, dann setzt dort gerne einen Haken. Wenn ihr auf ein Bild
|
||||
klickt, öffnet sich direkt der passende Link dazu.
|
||||
schenken möchtet, haben wir eine Liste zusammengestellt, worüber wir uns sehr freuen. Außerdem lieben wir es
|
||||
zu reisen und freuen uns immer über Geld für unsere Reisekasse. Falls ihr euch unten in der Liste etwas
|
||||
ausgesucht habt, dann setzt dort gerne einen Haken. Wenn ihr auf ein Bild klickt, öffnet sich direkt der
|
||||
passende Link dazu.
|
||||
</p>
|
||||
<!-- <p>-->
|
||||
<!-- Diese Liste wird sich in den nächsten Wochen noch füllen. Schaut gerne noch mal vorbei!-->
|
||||
<!-- </p>-->
|
||||
<!-- <p>-->
|
||||
<!-- Diese Liste wird sich in den nächsten Wochen noch füllen. Schaut gerne noch mal vorbei!-->
|
||||
<!-- </p>-->
|
||||
<div id="present-container">
|
||||
<a id="present-template" class="flex-container present" target="_blank">
|
||||
<div class="present-checkbox">
|
||||
<div></div>
|
||||
</div>
|
||||
<img class="present-image">
|
||||
<div class="grow">
|
||||
<div class="present-name"></div>
|
||||
<div class="present-description"></div>
|
||||
<div class="grow present-info">
|
||||
<div>
|
||||
<div class="present-name"></div>
|
||||
<div class="present-description"></div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
<div class="site-content grid-container">
|
||||
<h1>Herzlich Willkommen</h1>
|
||||
<p>Wir heiraten! Und das möchten wir mit euch gemeinsam in Aachen feiern.
|
||||
Leider müssen wir jedoch wegen der Corona Pandemie unsere kirchliche
|
||||
Hochzeit um ein Jahr auf den <b>07.05.22</b> verschieben. Standesamtlich haben wir natürlich
|
||||
trotzdem am 24. April in Betzdorf (Sieg) geheiratet und sind glücklich darüber
|
||||
gemeinsam in die Ehe zu starten. Wir freuen uns schon sehr darauf, nächstes Jahr
|
||||
unseren Hochzeitsgottesdienst und eine große Party mit euch am 07.05.22 zu feiern.
|
||||
</p>
|
||||
<p>Der Termin für unsere kirchliche Hochzeit steht fest. <b>Wir feiern am 07. Mai '22!</b></p>
|
||||
|
||||
<p>Falls ihr Fragen habt, meldet euch gerne unter <a href = 'mailto:hochzeit-js@gmx.net'>hochzeit-js@gmx.net</a></p>
|
||||
<p>Wir freuen uns, mit Euch unsere Hochzeit in Aachen zu feiern! Nach unserer wunderschönen standesamtlichen Trauung
|
||||
am 24. April letztes Jahr, freuen wir uns auf unsere kirchliche Hochzeit am 7. Mai dieses Jahr. Bitte sagt uns
|
||||
doch bis zum 15. März, ob ihr dabei sein könnt! Schreibt uns dazu gerne eine Mail an <a
|
||||
href='mailto:hochzeit-js@gmx.net'>hochzeit-js@gmx.net</a>.
|
||||
</p>
|
||||
<p>Nach den neusten Lockerungen sind wir sehr zuversichtlich, dass unsere Hochzeit dieses Jahr trotz Corona
|
||||
stattfinden kann. Wir gehen davon aus, dass wir unter 2G- oder 2G-plus-Regeln feiern werden, aber mit genaueren
|
||||
Infos dazu melden wir uns nochmal rechtzeitig vorher.</p>
|
||||
<p>Falls ihr Fragen habt, meldet euch gerne bei uns :)</p>
|
||||
</div>
|
||||
|
||||
6
src/client/html/standesamt.html
Normal file
@@ -0,0 +1,6 @@
|
||||
<div class="site-content grid-container">
|
||||
<h1>Standesamtliche Trauung</h1>
|
||||
<p>Hier findet ihr ein paar Impressionen zu unserer standesamtlichen Trauung letztes Jahr. Wir haben trotz Start des
|
||||
bundesweiten Lockdowns einen wunderschönen Tag im kleinen Familienkreis verbracht.</p><br/>
|
||||
<div id="gallery"></div>
|
||||
</div>
|
||||
@@ -1,6 +1,7 @@
|
||||
<div class="flex-container fill-height-medium-up">
|
||||
<div class="height-100" id="info-image-container" data-state="godi">
|
||||
<img src="../img/tagesablauf.jpg" class="height-100">
|
||||
<img src="../img/tagesablauf_neu.jpg" class="height-100">
|
||||
<img src="../img/einkreiser.png" class="circler visible">
|
||||
<img src="../img/einkreiser.png" class="circler godi" data-state="godi">
|
||||
<img src="../img/einkreiser.png" class="circler fingerfood" data-state="fingerfood">
|
||||
<img src="../img/einkreiser.png" class="circler foto" data-state="foto">
|
||||
@@ -13,50 +14,53 @@
|
||||
<div class="anchor" data-state="godi">
|
||||
<h1>Traugottesdienst</h1>
|
||||
<p>
|
||||
Um 14:00 Uhr möchten wir gemeinsam mit euch unseren Traugottesdienst in der Annakirche feiern
|
||||
(Annastraße
|
||||
35, 52062 Aachen). Wenn ihr mit dem Auto anreist könnt ihr im Parkhaus am Dom (Jesuitenstraße 12, 52062
|
||||
Aachen) parken, das ist direkt neben der Kirche.
|
||||
Um 12:00 Uhr möchten wir gemeinsam mit euch unseren Traugottesdienst in der Annakirche feiern
|
||||
(Annastraße 35, 52062 Aachen). Wenn ihr mit dem Auto anreist könnt ihr im Parkhaus am Dom
|
||||
(Jesuitenstraße 12, 52062 Aachen) parken, das ist direkt neben der Kirche. <br/>Kleiner fun fact: Es
|
||||
lohnt
|
||||
sich auf der obersten Etage zu parken, dort gibt es eine tolle Aussicht auf den Dom und da haben wir uns
|
||||
verlobt.
|
||||
</p>
|
||||
</div>
|
||||
<div class="anchor" data-state="fingerfood">
|
||||
<h1>Fingerfood</h1>
|
||||
<p>
|
||||
Nach dem Gottesdienst gehen wir zusammen zu Fuß ins Aachener Fenster (Buchkremerstraße 2). Dort gibt es
|
||||
dann
|
||||
süßes und salziges Fingerfood und ganz viel Zeit zum Gratulieren. Wenn ihr etwas zum Buffet beisteuern
|
||||
möchtet, dann meldet euch gerne bei <a href='mailto:sinah.stinner@googlemail.com'>Sinah Stinner
|
||||
Nach dem Gottesdienst gibt es süßes und salziges Fingerfood und ganz viel Zeit zum Gratulieren. Wenn ihr
|
||||
etwas zum Buffet beisteuern möchtet, dann meldet euch gerne bei <a
|
||||
href='mailto:sinah.stinner@googlemail.com'>Sinah Stinner
|
||||
(sinah.stinner@googlemail.com)</a>.
|
||||
</p></div>
|
||||
</p>
|
||||
</div>
|
||||
<div class="anchor" data-state="foto">
|
||||
<h1>Gruppenfotos</h1>
|
||||
<p>
|
||||
Um ganz viele wundervolle Erinnerungen an unsere Hochzeit, die wir mit euch feiern, zu haben, gehen wir
|
||||
um
|
||||
17:00 Uhr auf den Katschhof und machen dort Gruppenfotos.
|
||||
</p></div>
|
||||
Um ganz viele wundervolle Erinnerungen an den besonderen Tag zu haben, gehen wir gegen 15:30 Uhr auf den
|
||||
Katschhof, zwischen dem Aachener Dom und Rathaus, und machen dort Gruppenfotos.
|
||||
</p>
|
||||
</div>
|
||||
<div class="anchor" data-state="sekt">
|
||||
<h1>Sektempfang</h1>
|
||||
<p>
|
||||
Wir feiern unsere Hochzeit im Forum M über der Aachener Mayerschen mit einem wundervollen Blick über die
|
||||
Aachener Innenstadt. Nach den Fotos werden wir dort gemeinsam anstoßen.
|
||||
</p></div>
|
||||
Aachener Innenstadt. Gegen 17h wollen wir dort gemeinsam anstoßen.
|
||||
</p>
|
||||
</div>
|
||||
<div class="anchor" data-state="essen">
|
||||
<h1>Festessen</h1>
|
||||
<p>
|
||||
Nach vielen wundervollen Bildern, freuen wir uns alle auf unser leckeres Hochzeitsbuffet, das es um halb
|
||||
acht gibt.
|
||||
</p></div>
|
||||
Um halb acht starten wir den Abend mit dem leckeren Hochzeitsbuffet.
|
||||
</p>
|
||||
</div>
|
||||
<div class="anchor" data-state="spiel">
|
||||
<h1>Spiel und Spass</h1>
|
||||
<p>
|
||||
Wir freuen uns auf richtige viele einzigartige, lustige und spaßige Programmbeiträge von euch. Wenn ihr
|
||||
es
|
||||
schon gar nicht erwarten könnt uns eine Freude zu machen und einen Beiträg beizusteuern, dann meldet
|
||||
euch
|
||||
gerne bei <a href = 'mailto:seitz-miriam@web.de'>Miriam Seitz (seitz.miriam@web.de)</a>. Und keine Sorge, Miriam behält alle Beiträge und
|
||||
Wir freuen uns auf viele einzigartige, lustige und spaßige Programmbeiträge von euch. Wenn ihr es schon
|
||||
gar nicht erwarten könnt uns eine Freude zu machen und einen Beitrag beizusteuern, dann meldet euch
|
||||
gerne bei <a
|
||||
href='mailto:seitz-miriam@web.de'>Miriam Seitz (seitz-miriam@web.de)</a>. Und keine Sorge, Miriam behält alle Beiträge und
|
||||
Überraschungen für sich, aber sagt ihr bitte bei allem Bescheid, was ihr planen wollt.
|
||||
</p></div>
|
||||
</p>
|
||||
</div>
|
||||
<div class="anchor" data-state="dance">
|
||||
<h1>Let's Dance</h1>
|
||||
<p>
|
||||
@@ -65,4 +69,4 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id = "modal"></div>
|
||||
<div id="modal"></div>
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
<div class="flex-container fill-height-medium-up">
|
||||
<!-- <div class="height-100 show-for-small-only">-->
|
||||
<!-- <img src="../img/unterkunft.jpg">-->
|
||||
<!-- </div>-->
|
||||
<div class="grow height-100 overflow-auto site-content hide-scrollbar">
|
||||
<h1>Unterkunft</h1>
|
||||
<p>
|
||||
@@ -9,19 +6,13 @@
|
||||
verbringen!
|
||||
</p>
|
||||
<p>
|
||||
Unten stehend findet ihr Vorschläge für Übernachtungsmöglichkeiten in Aachen. Wahrscheinlich macht es auf
|
||||
Grund der aktuellen Corona-Lage noch keinen Sinn, dass ihr etwas bucht, weil wir erst abwarten müssen,
|
||||
inwiefern wir unsere Hochzeit feiern können.
|
||||
</p>
|
||||
<p>
|
||||
Das B&B Hotel Aachen City (Großkölnstraße 57-63) ist fußläufig von unserer Location in fünf Minuten zu
|
||||
erreichen. Da wir von der Kirche zu Fuß ins Forum M gehen können, könnt ihr das Auto im Parkhaus am Dom über
|
||||
Nacht stehen lassen.
|
||||
Untenstehend findet ihr Vorschläge für Übernachtungsmöglichkeiten in Aachen. Das B&B Hotel Aachen City
|
||||
(Großkölnstraße 57-63) ist fußläufig von unserer Location in fünf Minuten zu erreichen. Da wir von der
|
||||
Kirche zu Fuß ins Forum M gehen können, könnt ihr das Auto im Parkhaus am Dom über Nacht stehen lassen.
|
||||
</p>
|
||||
<p>
|
||||
Alle, die eher eine studentische Übernachtungsmöglichkeit suchen, können sich gerne bei uns melden. Ihr
|
||||
werdet
|
||||
dann bei Freunden aus Aachen in WGs mituntergebracht. Sagt uns da bitte bis spätestens zum 15.April
|
||||
werdet dann bei Freunden von uns in WGs übernachten. Sagt uns da bitte auch spätestens bis zum 15. März
|
||||
Bescheid.
|
||||
</p>
|
||||
|
||||
@@ -33,12 +24,13 @@
|
||||
</a>
|
||||
</div>
|
||||
<div class="small-8">
|
||||
<!-- <iframe id="map_unterkunft" src="https://maps.google.com/maps?width=520&height=395&hl=de&q=IBIS%20budget%20Hotel+Schumacherstr%2012%20Aachen&t=&z=14&ie=UTF8&iwloc=B&output=embed"></iframe>-->
|
||||
<iframe id="map_unterkunft" src="https://maps.google.com/maps?width=520&height=395&hl=de&q=B%26B+Hotel+Aachen-City,+Großkölnstraße+57-63,+52062+Aachen&t=&z=14&ie=UTF8&iwloc=B&output=embed"></iframe>
|
||||
<!-- <iframe id="map_unterkunft" src="https://maps.google.com/maps?width=520&height=395&hl=de&q=IBIS%20budget%20Hotel+Schumacherstr%2012%20Aachen&t=&z=14&ie=UTF8&iwloc=B&output=embed"></iframe>-->
|
||||
<iframe id="map_unterkunft"
|
||||
src="https://maps.google.com/maps?width=520&height=395&hl=de&q=B%26B+Hotel+Aachen-City,+Großkölnstraße+57-63,+52062+Aachen&t=&z=14&ie=UTF8&iwloc=B&output=embed"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="height-100 hide-for-small-only img-column">
|
||||
<img src="../img/unterkunft.jpg" class="height-100">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
Before Width: | Height: | Size: 79 KiB |
|
Before Width: | Height: | Size: 50 KiB |
BIN
src/client/img/geschenke/Backpapier.png
Normal file
|
After Width: | Height: | Size: 214 KiB |
BIN
src/client/img/geschenke/Bang.png
Normal file
|
After Width: | Height: | Size: 100 KiB |
BIN
src/client/img/geschenke/Bienenwachstuch.jpeg
Normal file
|
After Width: | Height: | Size: 985 KiB |
BIN
src/client/img/geschenke/Blumenstrauss.png
Normal file
|
After Width: | Height: | Size: 294 KiB |
BIN
src/client/img/geschenke/Buch.jpeg
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
src/client/img/geschenke/Codenames.png
Normal file
|
After Width: | Height: | Size: 240 KiB |
BIN
src/client/img/geschenke/Eisportionierer.png
Normal file
|
After Width: | Height: | Size: 128 KiB |
BIN
src/client/img/geschenke/Gießkanne.png
Normal file
|
After Width: | Height: | Size: 142 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 159 KiB |
|
Before Width: | Height: | Size: 155 KiB |
BIN
src/client/img/geschenke/Korkplatte.png
Normal file
|
After Width: | Height: | Size: 222 KiB |
|
Before Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 144 KiB |
|
Before Width: | Height: | Size: 242 KiB After Width: | Height: | Size: 144 KiB |
BIN
src/client/img/geschenke/Nudelzange.png
Normal file
|
After Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 48 KiB |
BIN
src/client/img/geschenke/Saftpresse.png
Normal file
|
After Width: | Height: | Size: 105 KiB |
BIN
src/client/img/geschenke/Sitzkissen.png
Normal file
|
After Width: | Height: | Size: 145 KiB |
|
Before Width: | Height: | Size: 98 KiB |
BIN
src/client/img/geschenke/Staubsaugerroboter.png
Normal file
|
After Width: | Height: | Size: 131 KiB |
BIN
src/client/img/geschenke/Stoffservietten.png
Normal file
|
After Width: | Height: | Size: 175 KiB |
BIN
src/client/img/geschenke/Weltkarte.jpg
Normal file
|
After Width: | Height: | Size: 319 KiB |
|
Before Width: | Height: | Size: 109 KiB |
|
Before Width: | Height: | Size: 37 KiB |
BIN
src/client/img/standesamt/1.jpg
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
src/client/img/standesamt/10.jpg
Normal file
|
After Width: | Height: | Size: 4.9 MiB |
BIN
src/client/img/standesamt/11.jpg
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
src/client/img/standesamt/12.jpg
Normal file
|
After Width: | Height: | Size: 738 KiB |
BIN
src/client/img/standesamt/13.jpg
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
src/client/img/standesamt/14.jpg
Normal file
|
After Width: | Height: | Size: 684 KiB |
BIN
src/client/img/standesamt/15.jpg
Normal file
|
After Width: | Height: | Size: 414 KiB |
BIN
src/client/img/standesamt/16.jpg
Normal file
|
After Width: | Height: | Size: 789 KiB |
BIN
src/client/img/standesamt/2.jpg
Normal file
|
After Width: | Height: | Size: 8.2 MiB |
BIN
src/client/img/standesamt/3.jpg
Normal file
|
After Width: | Height: | Size: 8.6 MiB |
BIN
src/client/img/standesamt/4.jpg
Normal file
|
After Width: | Height: | Size: 8.5 MiB |
BIN
src/client/img/standesamt/5.jpg
Normal file
|
After Width: | Height: | Size: 9.2 MiB |
BIN
src/client/img/standesamt/6.jpg
Normal file
|
After Width: | Height: | Size: 8.2 MiB |
BIN
src/client/img/standesamt/7.jpg
Normal file
|
After Width: | Height: | Size: 8.7 MiB |
BIN
src/client/img/standesamt/8.jpg
Normal file
|
After Width: | Height: | Size: 8.0 MiB |
BIN
src/client/img/standesamt/9.jpg
Normal file
|
After Width: | Height: | Size: 5.3 MiB |
BIN
src/client/img/tagesablauf_neu.jpg
Normal file
|
After Width: | Height: | Size: 378 KiB |
@@ -29,7 +29,7 @@
|
||||
<li data-site="tagesablauf"><a>Tagesablauf</a></li>
|
||||
<li data-site="unterkunft"><a>Unterkunft</a></li>
|
||||
<li data-site="geschenke"><a>Geschenke</a></li>
|
||||
<!-- <li><a href="#">Galerie</a></li>-->
|
||||
<li data-site="standesamt"><a>Standesamt</a></li>
|
||||
</ul>
|
||||
<ul class="menu align-center-middle medium-horizontal hide-for-small-only">
|
||||
<li><img class="logo-img" src="img/logo.png" alt="J&S"></li>
|
||||
@@ -37,7 +37,7 @@
|
||||
<li data-site="tagesablauf"><a>Tagesablauf</a></li>
|
||||
<li data-site="unterkunft"><a>Unterkunft</a></li>
|
||||
<li data-site="geschenke"><a>Geschenke</a></li>
|
||||
<!-- <li><a href="#">Galerie</a></li>-->
|
||||
<li data-site="standesamt"><a>Standesamt</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="top-bar-right">
|
||||
@@ -67,4 +67,4 @@
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
133
src/client/js/ImageGallery/Gallery/Gallery.jsx
Normal file
@@ -0,0 +1,133 @@
|
||||
import React, { useState, useLayoutEffect, useRef, useMemo } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import ResizeObserver from 'resize-observer-polyfill';
|
||||
import Photo, { photoPropType } from './Photo';
|
||||
import { computeColumnLayout } from './layouts/columns';
|
||||
import { computeRowLayout } from './layouts/justified';
|
||||
import { findIdealNodeSearch } from './utils/findIdealNodeSearch';
|
||||
|
||||
const Gallery = React.memo(function Gallery({
|
||||
photos,
|
||||
onClick,
|
||||
direction,
|
||||
margin,
|
||||
limitNodeSearch,
|
||||
targetRowHeight,
|
||||
columns,
|
||||
renderImage,
|
||||
}) {
|
||||
const [containerWidth, setContainerWidth] = useState(0);
|
||||
const galleryEl = useRef(null);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
let animationFrameID = null;
|
||||
const observer = new ResizeObserver(entries => {
|
||||
// only do something if width changes
|
||||
const newWidth = entries[0].contentRect.width;
|
||||
if (containerWidth !== newWidth) {
|
||||
// put in an animation frame to stop "benign errors" from
|
||||
// ResizObserver https://stackoverflow.com/questions/49384120/resizeobserver-loop-limit-exceeded
|
||||
animationFrameID = window.requestAnimationFrame(() => {
|
||||
setContainerWidth(Math.floor(newWidth));
|
||||
});
|
||||
}
|
||||
});
|
||||
observer.observe(galleryEl.current);
|
||||
return () => {
|
||||
observer.disconnect();
|
||||
window.cancelAnimationFrame(animationFrameID);
|
||||
};
|
||||
});
|
||||
|
||||
const handleClick = (event, { index }) => {
|
||||
onClick(event, {
|
||||
index,
|
||||
photo: photos[index],
|
||||
previous: photos[index - 1] || null,
|
||||
next: photos[index + 1] || null,
|
||||
});
|
||||
};
|
||||
|
||||
// no containerWidth until after first render with refs, skip calculations and render nothing
|
||||
if (!containerWidth) return <div ref={galleryEl}> </div>;
|
||||
// subtract 1 pixel because the browser may round up a pixel
|
||||
const width = containerWidth - 1;
|
||||
let galleryStyle, thumbs;
|
||||
|
||||
if (direction === 'row') {
|
||||
// allow user to calculate limitNodeSearch from containerWidth
|
||||
if (typeof limitNodeSearch === 'function') {
|
||||
limitNodeSearch = limitNodeSearch(containerWidth);
|
||||
}
|
||||
if (typeof targetRowHeight === 'function') {
|
||||
targetRowHeight = targetRowHeight(containerWidth);
|
||||
}
|
||||
// set how many neighboring nodes the graph will visit
|
||||
if (limitNodeSearch === undefined) {
|
||||
limitNodeSearch = 2;
|
||||
if (containerWidth >= 450) {
|
||||
limitNodeSearch = findIdealNodeSearch({ containerWidth, targetRowHeight });
|
||||
}
|
||||
}
|
||||
|
||||
galleryStyle = { display: 'flex', flexWrap: 'wrap', flexDirection: 'row' };
|
||||
thumbs = computeRowLayout({ containerWidth: width, limitNodeSearch, targetRowHeight, margin, photos });
|
||||
}
|
||||
if (direction === 'column') {
|
||||
// allow user to calculate columns from containerWidth
|
||||
if (typeof columns === 'function') {
|
||||
columns = columns(containerWidth);
|
||||
}
|
||||
// set default breakpoints if user doesn't specify columns prop
|
||||
if (columns === undefined) {
|
||||
columns = 1;
|
||||
if (containerWidth >= 500) columns = 2;
|
||||
if (containerWidth >= 900) columns = 3;
|
||||
if (containerWidth >= 1500) columns = 4;
|
||||
}
|
||||
galleryStyle = { position: 'relative' };
|
||||
thumbs = computeColumnLayout({ containerWidth: width, columns, margin, photos });
|
||||
galleryStyle.height = thumbs[thumbs.length - 1].containerHeight;
|
||||
}
|
||||
|
||||
const renderComponent = renderImage || Photo;
|
||||
return (
|
||||
<div className="react-photo-gallery--gallery">
|
||||
<div ref={galleryEl} style={galleryStyle}>
|
||||
{thumbs.map((thumb, index) => {
|
||||
const { left, top, containerHeight, ...photo } = thumb;
|
||||
return renderComponent({
|
||||
left,
|
||||
top,
|
||||
key: thumb.key || thumb.src,
|
||||
containerHeight,
|
||||
index,
|
||||
margin,
|
||||
direction,
|
||||
onClick: onClick ? handleClick : null,
|
||||
photo,
|
||||
});
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
Gallery.propTypes = {
|
||||
photos: PropTypes.arrayOf(photoPropType).isRequired,
|
||||
direction: PropTypes.string,
|
||||
onClick: PropTypes.func,
|
||||
columns: PropTypes.oneOfType([PropTypes.func, PropTypes.number]),
|
||||
targetRowHeight: PropTypes.oneOfType([PropTypes.func, PropTypes.number]),
|
||||
limitNodeSearch: PropTypes.oneOfType([PropTypes.func, PropTypes.number]),
|
||||
margin: PropTypes.number,
|
||||
renderImage: PropTypes.func,
|
||||
};
|
||||
|
||||
Gallery.defaultProps = {
|
||||
margin: 2,
|
||||
direction: 'row',
|
||||
targetRowHeight: 300,
|
||||
};
|
||||
export { Photo };
|
||||
export default Gallery;
|
||||
59
src/client/js/ImageGallery/Gallery/Photo.jsx
Normal file
@@ -0,0 +1,59 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const imgWithClick = { cursor: 'pointer' };
|
||||
|
||||
const Photo = ({ index, onClick, photo, margin, direction, top, left, key }) => {
|
||||
const imgStyle = { margin: margin, display: 'block' };
|
||||
imgStyle.width = photo.width+"px";
|
||||
imgStyle.height=photo.height+"px";
|
||||
if (direction === 'column') {
|
||||
imgStyle.position = 'absolute';
|
||||
imgStyle.left = left;
|
||||
imgStyle.top = top;
|
||||
}
|
||||
|
||||
const handleClick = event => {
|
||||
onClick(event, { photo, index });
|
||||
};
|
||||
|
||||
return (
|
||||
<img
|
||||
key={key}
|
||||
style={onClick ? { ...imgStyle, ...imgWithClick } : imgStyle}
|
||||
{...photo}
|
||||
onClick={onClick ? handleClick : null}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const photoPropType = PropTypes.shape({
|
||||
key: PropTypes.string,
|
||||
src: PropTypes.string.isRequired,
|
||||
width: PropTypes.number.isRequired,
|
||||
height: PropTypes.number.isRequired,
|
||||
alt: PropTypes.string,
|
||||
title: PropTypes.string,
|
||||
srcSet: PropTypes.oneOfType([PropTypes.string, PropTypes.array]),
|
||||
sizes: PropTypes.oneOfType([PropTypes.string, PropTypes.array]),
|
||||
});
|
||||
|
||||
Photo.propTypes = {
|
||||
index: PropTypes.number.isRequired,
|
||||
onClick: PropTypes.func,
|
||||
photo: photoPropType.isRequired,
|
||||
margin: PropTypes.number,
|
||||
top: props => {
|
||||
if (props.direction === 'column' && typeof props.top !== 'number') {
|
||||
return new Error('top is a required number when direction is set to `column`');
|
||||
}
|
||||
},
|
||||
left: props => {
|
||||
if (props.direction === 'column' && typeof props.left !== 'number') {
|
||||
return new Error('left is a required number when direction is set to `column`');
|
||||
}
|
||||
},
|
||||
direction: PropTypes.string,
|
||||
};
|
||||
|
||||
export default Photo;
|
||||
49
src/client/js/ImageGallery/Gallery/layouts/columns.js
Normal file
@@ -0,0 +1,49 @@
|
||||
import { round } from '../utils/round';
|
||||
|
||||
// compute sizes for column directed layouts
|
||||
export const computeColumnLayout = ({ photos, columns, containerWidth, margin }) => {
|
||||
// calculate each colWidth based on total width and column amount
|
||||
let colWidth = (containerWidth - margin * 2 * columns) / columns;
|
||||
|
||||
// map through each photo to assign adjusted height and width based on colWidth
|
||||
const photosWithSizes = photos.map(photo => {
|
||||
const newHeight = photo.height / photo.width * colWidth;
|
||||
return {
|
||||
...photo,
|
||||
width: round(colWidth, 1),
|
||||
height: round(newHeight, 1),
|
||||
};
|
||||
});
|
||||
|
||||
// store all possible left positions
|
||||
// and current top positions for each column
|
||||
const colLeftPositions = [];
|
||||
const colCurrTopPositions = [];
|
||||
for (var i = 0; i < columns; i++) {
|
||||
colLeftPositions[i] = round(i * (colWidth + margin * 2), 1);
|
||||
colCurrTopPositions[i] = 0;
|
||||
}
|
||||
|
||||
// map through each photo, then reduce thru each "column"
|
||||
// find column with the smallest height and assign to photo's 'top'
|
||||
// update that column's height with this photo's height
|
||||
const photosPositioned = photosWithSizes.map(photo => {
|
||||
const smallestCol = colCurrTopPositions.reduce((acc, item, i) => {
|
||||
acc = item < colCurrTopPositions[acc] ? i : acc;
|
||||
return acc;
|
||||
}, 0);
|
||||
|
||||
photo.top = colCurrTopPositions[smallestCol];
|
||||
photo.left = colLeftPositions[smallestCol];
|
||||
colCurrTopPositions[smallestCol] = colCurrTopPositions[smallestCol] + photo.height + margin * 2;
|
||||
|
||||
// store the tallest col to use for gallery height because of abs positioned elements
|
||||
const tallestCol = colCurrTopPositions.reduce((acc, item, i) => {
|
||||
acc = item > colCurrTopPositions[acc] ? i : acc;
|
||||
return acc;
|
||||
}, 0);
|
||||
photo.containerHeight = colCurrTopPositions[tallestCol];
|
||||
return photo;
|
||||
});
|
||||
return photosPositioned;
|
||||
};
|
||||
49
src/client/js/ImageGallery/Gallery/layouts/justified.js
Normal file
@@ -0,0 +1,49 @@
|
||||
import { ratio } from '../utils/ratio';
|
||||
import { round } from '../utils/round';
|
||||
import { findShortestPath } from '../utils/dijkstra';
|
||||
|
||||
// compute sizes by creating a graph with rows as edges and photo to break on as nodes
|
||||
// to calculate the single best layout using Dijkstra's findShortestPat
|
||||
|
||||
// get the height for a set of photos in a potential row
|
||||
const getCommonHeight = (row, containerWidth, margin) => {
|
||||
const rowWidth = containerWidth - row.length * (margin * 2);
|
||||
const totalAspectRatio = row.reduce((acc, photo) => acc + ratio(photo), 0);
|
||||
return rowWidth / totalAspectRatio;
|
||||
};
|
||||
|
||||
// calculate the cost of breaking at this node (edge weight)
|
||||
const cost = (photos, i, j, width, targetHeight, margin) => {
|
||||
const row = photos.slice(i, j);
|
||||
const commonHeight = getCommonHeight(row, width, margin);
|
||||
return Math.pow(Math.abs(commonHeight - targetHeight), 2);
|
||||
};
|
||||
|
||||
// return function that gets the neighboring nodes of node and returns costs
|
||||
const makeGetNeighbors = (targetHeight, containerWidth, photos, limitNodeSearch, margin) => start => {
|
||||
const results = {};
|
||||
start = +start;
|
||||
results[+start] = 0;
|
||||
for (let i = start + 1; i < photos.length + 1; ++i) {
|
||||
if (i - start > limitNodeSearch) break;
|
||||
results[i.toString()] = cost(photos, start, i, containerWidth, targetHeight, margin);
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
export const computeRowLayout = ({ containerWidth, limitNodeSearch, targetRowHeight, margin, photos }) => {
|
||||
// const t = +new Date();
|
||||
const getNeighbors = makeGetNeighbors(targetRowHeight, containerWidth, photos, limitNodeSearch, margin);
|
||||
let path = findShortestPath(getNeighbors, '0', photos.length);
|
||||
path = path.map(node => +node);
|
||||
// console.log(`time to find the shortest path: ${(+new Date() - t)} ms`);
|
||||
for (let i = 1; i < path.length; ++i) {
|
||||
const row = photos.slice(path[i - 1], path[i]);
|
||||
const height = getCommonHeight(row, containerWidth, margin);
|
||||
for (let j = path[i - 1]; j < path[i]; ++j) {
|
||||
photos[j].width = round(height * ratio(photos[j]), 1);
|
||||
photos[j].height = height;
|
||||
}
|
||||
}
|
||||
return photos;
|
||||
};
|
||||
123
src/client/js/ImageGallery/Gallery/utils/binary-heap.js
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
Copyright 2007-2013 Marijn Haverbeke frin "Eloquent Javascript, 1st Edition"
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
export function BinaryHeap(scoreFunction) {
|
||||
this.content = [];
|
||||
this.scoreFunction = scoreFunction;
|
||||
}
|
||||
|
||||
BinaryHeap.prototype = {
|
||||
push: function(element) {
|
||||
// Add the new element to the end of the array.
|
||||
this.content.push(element);
|
||||
// Allow it to bubble up.
|
||||
this.bubbleUp(this.content.length - 1);
|
||||
},
|
||||
|
||||
pop: function() {
|
||||
// Store the first element so we can return it later.
|
||||
var result = this.content[0];
|
||||
// Get the element at the end of the array.
|
||||
var end = this.content.pop();
|
||||
// If there are any elements left, put the end element at the
|
||||
// start, and let it sink down.
|
||||
if (this.content.length > 0) {
|
||||
this.content[0] = end;
|
||||
this.sinkDown(0);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
remove: function(node) {
|
||||
var length = this.content.length;
|
||||
// To remove a value, we must search through the array to find
|
||||
// it.
|
||||
for (var i = 0; i < length; i++) {
|
||||
if (this.content[i] != node) continue;
|
||||
// When it is found, the process seen in 'pop' is repeated
|
||||
// to fill up the hole.
|
||||
var end = this.content.pop();
|
||||
// If the element we popped was the one we needed to remove,
|
||||
// we're done.
|
||||
if (i == length - 1) break;
|
||||
// Otherwise, we replace the removed element with the popped
|
||||
// one, and allow it to float up or sink down as appropriate.
|
||||
this.content[i] = end;
|
||||
this.bubbleUp(i);
|
||||
this.sinkDown(i);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
size: function() {
|
||||
return this.content.length;
|
||||
},
|
||||
|
||||
bubbleUp: function(n) {
|
||||
// Fetch the element that has to be moved.
|
||||
var element = this.content[n],
|
||||
score = this.scoreFunction(element);
|
||||
// When at 0, an element can not go up any further.
|
||||
while (n > 0) {
|
||||
// Compute the parent element's index, and fetch it.
|
||||
var parentN = Math.floor((n + 1) / 2) - 1,
|
||||
parent = this.content[parentN];
|
||||
// If the parent has a lesser score, things are in order and we
|
||||
// are done.
|
||||
if (score >= this.scoreFunction(parent)) break;
|
||||
|
||||
// Otherwise, swap the parent with the current element and
|
||||
// continue.
|
||||
this.content[parentN] = element;
|
||||
this.content[n] = parent;
|
||||
n = parentN;
|
||||
}
|
||||
},
|
||||
|
||||
sinkDown: function(n) {
|
||||
// Look up the target element and its score.
|
||||
var length = this.content.length,
|
||||
element = this.content[n],
|
||||
elemScore = this.scoreFunction(element);
|
||||
|
||||
while (true) {
|
||||
// Compute the indices of the child elements.
|
||||
var child2N = (n + 1) * 2,
|
||||
child1N = child2N - 1;
|
||||
// This is used to store the new position of the element,
|
||||
// if any.
|
||||
var swap = null;
|
||||
// If the first child exists (is inside the array)...
|
||||
if (child1N < length) {
|
||||
// Look it up and compute its score.
|
||||
var child1 = this.content[child1N],
|
||||
child1Score = this.scoreFunction(child1);
|
||||
// If the score is less than our element's, we need to swap.
|
||||
if (child1Score < elemScore) swap = child1N;
|
||||
}
|
||||
// Do the same checks for the other child.
|
||||
if (child2N < length) {
|
||||
var child2 = this.content[child2N],
|
||||
child2Score = this.scoreFunction(child2);
|
||||
if (child2Score < (swap == null ? elemScore : child1Score)) swap = child2N;
|
||||
}
|
||||
|
||||
// No need to swap further, we are done.
|
||||
if (swap == null) break;
|
||||
|
||||
// Otherwise, swap and continue.
|
||||
this.content[n] = this.content[swap];
|
||||
this.content[swap] = element;
|
||||
n = swap;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default BinaryHeap;
|
||||
74
src/client/js/ImageGallery/Gallery/utils/dijkstra.js
Normal file
@@ -0,0 +1,74 @@
|
||||
import { BinaryHeap } from './binary-heap';
|
||||
|
||||
const buildPrecedentsMap = (graph, startNode, endNode) => {
|
||||
// store the previous vertex of the shortest path of arrival
|
||||
const precedentsMap = {};
|
||||
|
||||
// store nodes already visited
|
||||
const visited = {};
|
||||
|
||||
// store/update only the shortest edge weights measured
|
||||
// the purpose of this is object is constant time lookup vs. binary heap lookup O(n)
|
||||
const storedShortestPaths = {};
|
||||
storedShortestPaths[startNode] = 0;
|
||||
|
||||
// priority queue of ALL nodes and storedShortestPaths
|
||||
// don't bother to delete them because it's faster to look at visited?
|
||||
const pQueue = new BinaryHeap(function(n) {
|
||||
return n.weight;
|
||||
});
|
||||
pQueue.push({ id: startNode, weight: 0 });
|
||||
|
||||
while (pQueue.size()) {
|
||||
// pop node with shortest total weight from start node
|
||||
const shortestNode = pQueue.pop();
|
||||
const shortestNodeId = shortestNode.id;
|
||||
|
||||
// if already visited, continue
|
||||
if (visited[shortestNodeId]) continue;
|
||||
|
||||
// visit neighboring nodes
|
||||
const neighboringNodes = graph(shortestNodeId) || {};
|
||||
visited[shortestNodeId] = 1;
|
||||
|
||||
// meet the neighbors, looking for shorter paths
|
||||
for (let neighbor in neighboringNodes) {
|
||||
// weight of path from startNode to this neighbor
|
||||
const newTotalWeight = shortestNode.weight + neighboringNodes[neighbor];
|
||||
|
||||
// if this is the first time meeting the neighbor OR if the new total weight from
|
||||
// start node to this neighbor node is greater than the old weight path, update it,
|
||||
// and update precedent node
|
||||
if (typeof storedShortestPaths[neighbor] === 'undefined' || storedShortestPaths[neighbor] > newTotalWeight) {
|
||||
storedShortestPaths[neighbor] = newTotalWeight;
|
||||
pQueue.push({ id: neighbor, weight: newTotalWeight });
|
||||
precedentsMap[neighbor] = shortestNodeId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof storedShortestPaths[endNode] === 'undefined') {
|
||||
throw new Error(`There is no path from ${startNode} to ${endNode}`);
|
||||
}
|
||||
|
||||
return precedentsMap;
|
||||
};
|
||||
|
||||
// build the route from precedent node vertices
|
||||
const getPathFromPrecedentsMap = (precedentsMap, endNode) => {
|
||||
const nodes = [];
|
||||
let n = endNode;
|
||||
let precedent;
|
||||
while (n) {
|
||||
nodes.push(n);
|
||||
precedent = precedentsMap[n];
|
||||
n = precedentsMap[n];
|
||||
}
|
||||
return nodes.reverse();
|
||||
};
|
||||
|
||||
// build the precedentsMap and find the shortest path from it
|
||||
export const findShortestPath = (graph, startNode, endNode) => {
|
||||
const precedentsMap = buildPrecedentsMap(graph, startNode, endNode);
|
||||
return getPathFromPrecedentsMap(precedentsMap, endNode);
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
import { round } from './round';
|
||||
|
||||
// guesstimate how many neighboring nodes should be searched based on
|
||||
// the aspect ratio of the container with images having an avg AR of 1.5
|
||||
// as the minimum amount of photos per row, plus some nodes
|
||||
export const findIdealNodeSearch = ({ targetRowHeight, containerWidth }) => {
|
||||
const rowAR = containerWidth / targetRowHeight;
|
||||
return round(rowAR / 1.5) + 8;
|
||||
};
|
||||
4
src/client/js/ImageGallery/Gallery/utils/ratio.js
Normal file
@@ -0,0 +1,4 @@
|
||||
import { round } from './round';
|
||||
|
||||
// return two decimal places rounded number
|
||||
export const ratio = ({ width, height }) => round(width / height, 2);
|
||||
4
src/client/js/ImageGallery/Gallery/utils/round.js
Normal file
@@ -0,0 +1,4 @@
|
||||
export const round = (value, decimals) => {
|
||||
if (!decimals) decimals = 0;
|
||||
return Number(Math.round(value + 'e' + decimals) + 'e-' + decimals);
|
||||
};
|
||||
47
src/client/js/ImageGallery/ImageGallery.tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
import * as React from 'react';
|
||||
import Carousel, {Modal, ModalGateway} from "react-images";
|
||||
import {useCallback, useState} from "react";
|
||||
import {photos} from "./photos";
|
||||
import Gallery from "./Gallery/Gallery";
|
||||
|
||||
export type ImageGalleryProps = {};
|
||||
|
||||
function ImageGallery({}: ImageGalleryProps) {
|
||||
|
||||
const [currentImage, setCurrentImage] = useState(0);
|
||||
const [viewerIsOpen, setViewerIsOpen] = useState(false);
|
||||
|
||||
const openLightbox = useCallback((event, {photo, index}) => {
|
||||
setCurrentImage(index);
|
||||
setViewerIsOpen(true);
|
||||
}, []);
|
||||
|
||||
const closeLightbox = () => {
|
||||
setCurrentImage(0);
|
||||
setViewerIsOpen(false);
|
||||
};
|
||||
|
||||
return <div>
|
||||
{/* @ts-ignore*/}
|
||||
<Gallery photos={photos} onClick={openLightbox}></Gallery>
|
||||
<ModalGateway>
|
||||
{viewerIsOpen ? (
|
||||
<Modal onClose={closeLightbox}>
|
||||
<Carousel
|
||||
currentIndex={currentImage}
|
||||
views={photos.map(x => ({
|
||||
...x,
|
||||
source: x.src
|
||||
// srcset: x.srcSet,
|
||||
// caption: x.title
|
||||
}))}
|
||||
/>
|
||||
</Modal>
|
||||
) : null}
|
||||
</ModalGateway>
|
||||
</div>;
|
||||
}
|
||||
|
||||
// Need ImageGalleryMemo for autocompletion of phpstorm
|
||||
const ImageGalleryMemo = React.memo(ImageGallery) as typeof ImageGallery;
|
||||
export {ImageGalleryMemo as ImageGallery}
|
||||
82
src/client/js/ImageGallery/photos.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
export const photos = [
|
||||
{
|
||||
src: require("../../img/standesamt/1.jpg").default,
|
||||
width: 3024,
|
||||
height: 4032
|
||||
},
|
||||
{
|
||||
src: require("../../img/standesamt/2.jpg").default,
|
||||
width: 4928,
|
||||
height: 3264
|
||||
},
|
||||
{
|
||||
src: require("../../img/standesamt/3.jpg").default,
|
||||
width: 4928,
|
||||
height: 3264
|
||||
},
|
||||
{
|
||||
src: require("../../img/standesamt/4.jpg").default,
|
||||
width: 3264,
|
||||
height: 4928
|
||||
},
|
||||
{
|
||||
src: require("../../img/standesamt/5.jpg").default,
|
||||
width: 3264,
|
||||
height: 4928
|
||||
},
|
||||
{
|
||||
src: require("../../img/standesamt/6.jpg").default,
|
||||
width: 4928,
|
||||
height: 3264
|
||||
},
|
||||
{
|
||||
src: require("../../img/standesamt/7.jpg").default,
|
||||
width: 3264,
|
||||
height: 4928
|
||||
},
|
||||
{
|
||||
src: require("../../img/standesamt/8.jpg").default,
|
||||
width: 4928,
|
||||
height: 3264
|
||||
},
|
||||
{
|
||||
src: require("../../img/standesamt/9.jpg").default,
|
||||
width: 4928,
|
||||
height: 3264
|
||||
},
|
||||
{
|
||||
src: require("../../img/standesamt/10.jpg").default,
|
||||
width: 4928,
|
||||
height: 3264
|
||||
},
|
||||
{
|
||||
src: require("../../img/standesamt/11.jpg").default,
|
||||
width: 3299,
|
||||
height: 2209
|
||||
},
|
||||
{
|
||||
src: require("../../img/standesamt/12.jpg").default,
|
||||
width: 2592,
|
||||
height: 3872
|
||||
},
|
||||
{
|
||||
src: require("../../img/standesamt/13.jpg").default,
|
||||
width: 3872,
|
||||
height: 2592
|
||||
},
|
||||
{
|
||||
src: require("../../img/standesamt/14.jpg").default,
|
||||
width: 3872,
|
||||
height: 2592
|
||||
},
|
||||
{
|
||||
src: require("../../img/standesamt/15.jpg").default,
|
||||
width: 3872,
|
||||
height: 2592
|
||||
},
|
||||
{
|
||||
src: require("../../img/standesamt/16.jpg").default,
|
||||
width: 3872,
|
||||
height: 2592
|
||||
},
|
||||
]
|
||||
@@ -2,11 +2,15 @@ import * as $ from "jquery";
|
||||
import "foundation-sites/dist/js/foundation.es6";
|
||||
import {PresentsHandler} from "./PresentsHandler";
|
||||
|
||||
import "../sass/index.scss"
|
||||
import {setupImageGallery} from "./setupImageGallery";
|
||||
|
||||
const templates = {
|
||||
home: require("../html/home.html"),
|
||||
unterkunft: require("../html/unterkunft.html"),
|
||||
tagesablauf: require("../html/tagesablauf.html"),
|
||||
geschenke: require("../html/geschenke.html"),
|
||||
standesamt: require("../html/standesamt.html"),
|
||||
}
|
||||
|
||||
const images = {
|
||||
@@ -14,6 +18,7 @@ const images = {
|
||||
unterkunft: require("../img/unterkunft.jpg").default,
|
||||
tagesablauf: null,
|
||||
geschenke: require("../img/geschenke.jpg").default,
|
||||
standesamt: null,
|
||||
}
|
||||
|
||||
const callbacks = {
|
||||
@@ -87,6 +92,7 @@ const callbacks = {
|
||||
});
|
||||
},
|
||||
geschenke: async () => await new PresentsHandler().showPresents(),
|
||||
standesamt: setupImageGallery
|
||||
}
|
||||
|
||||
$(document).foundation();
|
||||
@@ -134,4 +140,4 @@ $(function () {
|
||||
document.querySelector("li[data-site='home']").dispatchEvent(new Event("click"));
|
||||
})
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,26 +1,29 @@
|
||||
export default [{
|
||||
id: 1,
|
||||
isBought: false,
|
||||
image: require("../img/geschenke/Quicheform.png").default,
|
||||
name: "Quicheform",
|
||||
description: "Eine Keramik-Quicheform mit Haltegriffen, die spülmaschinengeeigent ist (wie im Link oder ähnlich)",
|
||||
link: "https://www.zwilling.com/de/zwilling-kuchenform-28-cm-keramik-40202-028-0/40202-028-0.html",
|
||||
version: 0,
|
||||
}, {
|
||||
id: 2,
|
||||
isBought: false,
|
||||
image: require("../img/geschenke/Sodastream.png").default,
|
||||
name: "2 Sodastream Flaschen",
|
||||
description: "Zwei Glaskaraffen für den Sodastream Crystal",
|
||||
link: "https://sodastream.de/products/glaskaraffe-duo-pack-0-8l",
|
||||
version: 0,
|
||||
}, {
|
||||
export default [
|
||||
// {
|
||||
// id: 1,
|
||||
// isBought: false,
|
||||
// image: require("../img/geschenke/Quicheform.png").default,
|
||||
// name: "Quicheform",
|
||||
// description: "Eine Keramik-Quicheform mit Haltegriffen, die spülmaschinengeeigent ist (wie im Link oder ähnlich)",
|
||||
// link: "https://www.zwilling.com/de/zwilling-kuchenform-28-cm-keramik-40202-028-0/40202-028-0.html",
|
||||
// version: 0,
|
||||
// },
|
||||
// {
|
||||
// id: 2,
|
||||
// isBought: false,
|
||||
// image: require("../img/geschenke/Sodastream.png").default,
|
||||
// name: "2 Sodastream Flaschen",
|
||||
// description: "Zwei Glaskaraffen für den Sodastream Crystal",
|
||||
// link: "https://sodastream.de/products/glaskaraffe-duo-pack-0-8l",
|
||||
// version: 0,
|
||||
// },
|
||||
{
|
||||
id: 3,
|
||||
isBought: false,
|
||||
image: require("../img/geschenke/GoPro.png").default,
|
||||
name: "Go Pro Hero 7 black",
|
||||
description: "Eine Go Pro Hero 7 Actioncam in schwarz",
|
||||
link: "https://gopro.com/de/de/shop/hero7-black/tech-specs?pid=CHDHX-701-master",
|
||||
name: "Go Pro Hero 9 black",
|
||||
description: "Eine Go Pro Hero 9 Action Cam in schwarz",
|
||||
link: "https://gopro.com/de/de/shop/cameras/hero9-black/CHDHX-901-master.html",
|
||||
version: 0,
|
||||
}, {
|
||||
id: 4,
|
||||
@@ -28,58 +31,64 @@ export default [{
|
||||
image: require("../img/geschenke/AdventureKit_GoPro.png").default,
|
||||
name: "Go Pro Zubehör",
|
||||
description: "Go Pro Abenteuer Kit mit schwimmendem Handgriff, Kopfgurt, QuickClip und Tasche",
|
||||
link: "https://gopro.com/de/de/shop/mounts-accessories/abenteuer-kit/AKTES-002.html",
|
||||
link: "https://gopro.com/de/de/shop/mounts-accessories/adventure-kit/AKTES-002.html",
|
||||
version: 0,
|
||||
}, {
|
||||
id: 5,
|
||||
isBought: false,
|
||||
image: require("../img/geschenke/Messerblock.png").default,
|
||||
name: "Messerblock",
|
||||
description: "ZWILLING Messerblock, 8-tlg., Bambusblock, 6 Messer und eine Schere aus rostfreiem Spezialstahl",
|
||||
link: "https://www.amazon.de/Zwilling-32434-002-0-Bambus-Style-8-tlg/dp/B00AO2TRUI/",
|
||||
description: "ZWILLING Selbstschärfender Messerblock, 7-tlg. In schwarz",
|
||||
link: "https://www.otto.de/p/zwilling-messerblock-gourmet-selbstschaerfend-7-tlg-weiss-selbstschaerfend-scharfe-messer-eisgehaertete-klinge-C1197649235/#variationId=1197649236",
|
||||
version: 0,
|
||||
}, {
|
||||
id: 6,
|
||||
isBought: false,
|
||||
image: require("../img/geschenke/Brettspiele.jpg").default,
|
||||
name: "Brettspiele",
|
||||
// description: "Wir freuen uns immer über ein neues, spannendes Brettspiel. Hier eine Liste von Spielen, die wir schon haben:<ul><li>Die Siedler inklusive Seefahrer Erweiterung</li><li>Dominion</li><li>Kingdom Builder</li><li>Keltis</li><li> Das verrückte Labyrinth</li><li> Trivial Pursuit</li><li> Dog</li><li> Outburst</li><li>eine Spielesammlung</li></ul>",
|
||||
description: "Wir freuen uns immer über ein neues, spannendes Brettspiel. Falls ihr sichergehen wollt, welche Spiele wir schon haben, fragt doch unsere Trauzeugen Sinah oder Miriam.",
|
||||
link: "",
|
||||
version: 0,
|
||||
}, {
|
||||
id: 7,
|
||||
isBought: false,
|
||||
image: require("../img/geschenke/Zahnbürste.png").default,
|
||||
name: "Elektrische Pärchenzahn-bürste",
|
||||
description: "Nachhaltige elektrische Zahnbürste von happy brush, SCHALL VIBE 3 Partner Bundle",
|
||||
link: "https://www.happybrush.de/starterkit-vibe-3-schall-zahnbuerste-bundle-mix/",
|
||||
version: 0,
|
||||
}, {
|
||||
id: 8,
|
||||
isBought: false,
|
||||
image: require("../img/geschenke/Kappsäge.png").default,
|
||||
name: "Kappsäge",
|
||||
description: "Einhell Kapp-/Gehrungssäge TC-MS 2112 (1600 W, Sägeblatt Ø 210 mm, Schnittbreite 120 mm, schwenkbarer Sägekopf)",
|
||||
link: "https://www.amazon.de/dp/B00DEXXFMK",
|
||||
version: 0,
|
||||
}, {
|
||||
id: 9,
|
||||
isBought: false,
|
||||
image: require("../img/geschenke/Akkuschrauber.png").default,
|
||||
name: "Akku-schrauber",
|
||||
description: "LUX Akku-Bohrschrauber-Set inkl. Akku (wie im Link oder ähnlich)",
|
||||
link: "https://www.obi.de/akkuschrauber/lux-akku-bohrschrauber-set-1-powersystem-a-bs-20/p/9543208",
|
||||
version: 0,
|
||||
}, {
|
||||
id: 10,
|
||||
isBought: false,
|
||||
image: require("../img/geschenke/BodumBrotbox.jpg").default,
|
||||
name: "Bodum Brotbox",
|
||||
description: "Bodum bistroBrotkasten mit Bambus-Schneidebrett, 23.81 x 37.15 x 14.29 cm; 1.11 Kilogramm",
|
||||
link: "https://www.amazon.de/Bodum-bistroBrotkasten-Bambus-Schneidebrett-BPA-freier-Kunststoff/dp/B00MAPNVCW/",
|
||||
version: 0,
|
||||
}, {
|
||||
},
|
||||
// {
|
||||
// id: 6,
|
||||
// isBought: false,
|
||||
// image: require("../img/geschenke/Brettspiele.jpg").default,
|
||||
// name: "Brettspiele",
|
||||
// // description: "Wir freuen uns immer über ein neues, spannendes Brettspiel. Hier eine Liste von Spielen, die wir schon haben:<ul><li>Die Siedler inklusive Seefahrer Erweiterung</li><li>Dominion</li><li>Kingdom Builder</li><li>Keltis</li><li> Das verrückte Labyrinth</li><li> Trivial Pursuit</li><li> Dog</li><li> Outburst</li><li>eine Spielesammlung</li></ul>",
|
||||
// description: "Wir freuen uns immer über ein neues, spannendes Brettspiel. Falls ihr sichergehen wollt, welche Spiele wir schon haben, fragt doch unsere Trauzeugen Sinah oder Miriam.",
|
||||
// link: "",
|
||||
// version: 0,
|
||||
// },
|
||||
// {
|
||||
// id: 7,
|
||||
// isBought: false,
|
||||
// image: require("../img/geschenke/Zahnbürste.png").default,
|
||||
// name: "Elektrische Pärchenzahn-bürste",
|
||||
// description: "Nachhaltige elektrische Zahnbürste von happy brush, SCHALL VIBE 3 Partner Bundle",
|
||||
// link: "https://www.happybrush.de/starterkit-vibe-3-schall-zahnbuerste-bundle-mix/",
|
||||
// version: 0,
|
||||
// },
|
||||
// {
|
||||
// id: 8,
|
||||
// isBought: false,
|
||||
// image: require("../img/geschenke/Kappsäge.png").default,
|
||||
// name: "Kappsäge",
|
||||
// description: "Einhell Kapp-/Gehrungssäge TC-MS 2112 (1600 W, Sägeblatt Ø 210 mm, Schnittbreite 120 mm, schwenkbarer Sägekopf)",
|
||||
// link: "https://www.amazon.de/dp/B00DEXXFMK",
|
||||
// version: 0,
|
||||
// },
|
||||
// {
|
||||
// id: 9,
|
||||
// isBought: false,
|
||||
// image: require("../img/geschenke/Akkuschrauber.png").default,
|
||||
// name: "Akku-schrauber",
|
||||
// description: "LUX Akku-Bohrschrauber-Set inkl. Akku (wie im Link oder ähnlich)",
|
||||
// link: "https://www.obi.de/akkuschrauber/lux-akku-bohrschrauber-set-1-powersystem-a-bs-20/p/9543208",
|
||||
// version: 0,
|
||||
// },
|
||||
// {
|
||||
// id: 10,
|
||||
// isBought: false,
|
||||
// image: require("../img/geschenke/BodumBrotbox.jpg").default,
|
||||
// name: "Bodum Brotbox",
|
||||
// description: "Bodum bistroBrotkasten mit Bambus-Schneidebrett, 23.81 x 37.15 x 14.29 cm; 1.11 Kilogramm",
|
||||
// link: "https://www.amazon.de/Bodum-bistroBrotkasten-Bambus-Schneidebrett-BPA-freier-Kunststoff/dp/B00MAPNVCW/",
|
||||
// version: 0,
|
||||
// },
|
||||
{
|
||||
id: 11,
|
||||
isBought: false,
|
||||
image: require("../img/geschenke/großer_Topf.png").default,
|
||||
@@ -105,53 +114,185 @@ export default [{
|
||||
description: "MacArthur Studienbibel mit Schlachter 2000 Übersetzung",
|
||||
link: "https://www.scm-shop.de/macarthur-studienbibel-schlachter-2000-7485697.html",
|
||||
version: 0,
|
||||
}, {
|
||||
id: 14,
|
||||
},
|
||||
// {
|
||||
// id: 14,
|
||||
// isBought: false,
|
||||
// image: require("../img/geschenke/nudelholz.png").default,
|
||||
// name: "Nudelholz",
|
||||
// description: "Eine Teigrolle aus Holz (wie im Link oder ähnlich)",
|
||||
// link: "https://shop.oetker.at/dr-oetker-teigroller-holz",
|
||||
// version: 0,
|
||||
// },
|
||||
// {
|
||||
// id: 15,
|
||||
// isBought: false,
|
||||
// image: require("../img/geschenke/suppenkelle.png").default,
|
||||
// name: "Suppenkelle mit Ausguss",
|
||||
// description: "Eine Suppenkelle/ Schöpflöffel mit Ausguss",
|
||||
// link: "https://www.fackelmann.de/fackelmann-ovalgriff-schoepfloeffel-29cm",
|
||||
// version: 0,
|
||||
// },
|
||||
// {
|
||||
// id: 16,
|
||||
// isBought: false,
|
||||
// image: require("../img/geschenke/pizzaschneider.png").default,
|
||||
// name: "Pizzaschneider",
|
||||
// description: "Ein Fahrrad Pizzaschneider",
|
||||
// link: "https://www.amazon.de/s?k=Fahrrad+Pizzaschneider&i=kitchen&__mk_de_DE=%C3%85M%C3%85%C5%BD%C3%95%C3%91",
|
||||
// version: 0,
|
||||
// },
|
||||
// {
|
||||
// id: 17,
|
||||
// isBought: false,
|
||||
// image: require("../img/geschenke/teekasten.png").default,
|
||||
// name: "Teebox",
|
||||
// description: "Eine Teebox mit genügend Platz für viele Teebeutel (wie im Link oder ähnlich)",
|
||||
// link: "https://www.amazon.de/dp/B002P9JK4Q?tag=teebox-best-21",
|
||||
// version: 0,
|
||||
// },
|
||||
// {
|
||||
// id: 18,
|
||||
// isBought: false,
|
||||
// image: require("../img/geschenke/backblech.png").default,
|
||||
// name: "Backblech mit Kuchenhaube",
|
||||
// description: "Ein Backblech mit passender Kuchenhaube (wie im Link oder ähnlich)",
|
||||
// link: "https://www.real.de/product/309417147/",
|
||||
// version: 0,
|
||||
// },
|
||||
// {
|
||||
// id: 19,
|
||||
// isBought: false,
|
||||
// image: require("../img/geschenke/zimmerpflanze.png").default,
|
||||
// name: "Zimmerpflanze Strelitzia nicolai",
|
||||
// description: "Strelitzie mit einer Höhe von 100 - 110 cm, Topf-Ø 24 cm, Paradiesvogelblume (wie im Link oder ähnlich)",
|
||||
// link: "https://www.obi.de/weitere-gruenpflanzen/strelitzie-hoehe-100-110-cm-topf-24-cm-paradiesvogelblume-strelitzia-nicolai/p/9625096",
|
||||
// version: 0,
|
||||
// },
|
||||
{
|
||||
id: 20,
|
||||
isBought: false,
|
||||
image: require("../img/geschenke/nudelholz.png").default,
|
||||
name: "Nudelholz",
|
||||
description: "Eine Teigrolle aus Holz (wie im Link oder ähnlich)",
|
||||
link: "https://shop.oetker.at/dr-oetker-teigroller-holz",
|
||||
image: require("../img/geschenke/Bang.png").default,
|
||||
name: "Bang! The Bullet",
|
||||
description: "Das Bang! Grundspiel mit Erweiterungen",
|
||||
link: "https://www.thalia.de/shop/home/artikeldetails/A1017416573",
|
||||
version: 0,
|
||||
}, {
|
||||
id: 15,
|
||||
},
|
||||
{
|
||||
id: 21,
|
||||
isBought: false,
|
||||
image: require("../img/geschenke/suppenkelle.png").default,
|
||||
name: "Suppenkelle mit Ausguss",
|
||||
description: "Eine Suppenkelle/ Schöpflöffel mit Ausguss",
|
||||
link: "https://www.fackelmann.de/fackelmann-ovalgriff-schoepfloeffel-29cm",
|
||||
image: require("../img/geschenke/Codenames.png").default,
|
||||
name: "Codenames XXL",
|
||||
description: "Condenames XXL mit extra großen Bildkarten",
|
||||
link: "https://www.thalia.de/shop/home/artikeldetails/A1052674361",
|
||||
version: 0,
|
||||
}, {
|
||||
id: 16,
|
||||
},
|
||||
{
|
||||
id: 23,
|
||||
isBought: false,
|
||||
image: require("../img/geschenke/pizzaschneider.png").default,
|
||||
name: "Pizzaschneider",
|
||||
description: "Ein Fahrrad Pizzaschneider",
|
||||
link: "https://www.amazon.de/s?k=Fahrrad+Pizzaschneider&i=kitchen&__mk_de_DE=%C3%85M%C3%85%C5%BD%C3%95%C3%91",
|
||||
image: require("../img/geschenke/Staubsaugerroboter.png").default,
|
||||
name: "Staubsaugerroboter mit Wischfunktion",
|
||||
description: "Staubsaugerroboter Roborock S5 Max mit Wischfunktion in schwarz",
|
||||
link: "https://www.idealo.de/preisvergleich/OffersOfProduct/200074714_-s5-max-schwarz-roborock.html",
|
||||
version: 0,
|
||||
}, {
|
||||
id: 17,
|
||||
},
|
||||
{
|
||||
id: 24,
|
||||
isBought: false,
|
||||
image: require("../img/geschenke/teekasten.png").default,
|
||||
name: "Teebox",
|
||||
description: "Eine Teebox mit genügend Platz für viele Teebeutel (wie im Link oder ähnlich)",
|
||||
link: "https://www.amazon.de/dp/B002P9JK4Q?tag=teebox-best-21",
|
||||
image: require("../img/geschenke/Weltkarte.jpg").default,
|
||||
name: "Weltkarte",
|
||||
description: "Weltkarte als Poster (197 x 116,5 cm)",
|
||||
link: "https://www.amazon.de/Weltkarte-Klassische-Vorderseite-laminiert-118/dp/B014FW44H8/ref=sr_1_14?keywords=weltkarte%2Bposter&qid=1642886702&sr=8-14&th=1",
|
||||
version: 0,
|
||||
}, {
|
||||
id: 18,
|
||||
},
|
||||
{
|
||||
id: 25,
|
||||
isBought: false,
|
||||
image: require("../img/geschenke/backblech.png").default,
|
||||
name: "Backblech mit Kuchenhaube",
|
||||
description: "Ein Backblech mit passender Kuchenhaube (wie im Link oder ähnlich)",
|
||||
link: "https://www.real.de/product/309417147/",
|
||||
image: require("../img/geschenke/Korkplatte.png").default,
|
||||
name: "4 Korkplatten für die Weltkarte",
|
||||
description: "Vier Korkplatten 60x 100 cm, als Unterlage zur Weltkarte",
|
||||
link: "https://www.amazon.de/Schadstofffrei-Antistatisch-Bastel-Unterlage-Trittschalld%C3%A4mmung-Wandverkleidung/dp/B079ND27TG/ref=pb_allspark_purchase_sims_desktop_2/258-0765775-0428551",
|
||||
version: 0,
|
||||
}, {
|
||||
id: 19,
|
||||
},
|
||||
{
|
||||
id: 26,
|
||||
isBought: false,
|
||||
image: require("../img/geschenke/zimmerpflanze.png").default,
|
||||
name: "Zimmerpflanze Strelitzia nicolai",
|
||||
description: "Strelitzie mit einer Höhe von 100 - 110 cm, Topf-Ø 24 cm, Paradiesvogelblume (wie im Link oder ähnlich)",
|
||||
link: "https://www.obi.de/weitere-gruenpflanzen/strelitzie-hoehe-100-110-cm-topf-24-cm-paradiesvogelblume-strelitzia-nicolai/p/9625096",
|
||||
image: require("../img/geschenke/Sitzkissen.png").default,
|
||||
name: "4 Sitzkissen",
|
||||
description: "4 Sitzkissen für unsere Wohnzimmerstühle",
|
||||
link: "https://jysk.de/wohnaccessoires/sitzkissen/sitzkissen-kejserlind-o34-lammfell-weiss",
|
||||
version: 0,
|
||||
},
|
||||
{
|
||||
id: 27,
|
||||
isBought: false,
|
||||
image: require("../img/geschenke/Stoffservietten.png").default,
|
||||
name: "12 Stoffservieten",
|
||||
description: "12 weiße Stoffservietten aus 100% Bio-Baumwolle",
|
||||
link: "https://www.bewusstgruen.de/12-stoffservietten-aus-100-bio-baumwolle/",
|
||||
version: 0,
|
||||
},
|
||||
{
|
||||
id: 28,
|
||||
isBought: false,
|
||||
image: require("../img/geschenke/Nudelzange.png").default,
|
||||
name: "WMF Nudelzange",
|
||||
description: "Nudelzange von WMF",
|
||||
link: "https://www.wmf.com/de/nudelzange-bistro.html",
|
||||
version: 0,
|
||||
},
|
||||
{
|
||||
id: 29,
|
||||
isBought: false,
|
||||
image: require("../img/geschenke/Eisportionierer.png").default,
|
||||
name: "Eisportionierer",
|
||||
description: "Eisportionierer mit Kugel-Auswurf Funktion (wie im Link oder ähnlich)",
|
||||
link: "https://www.fackelmann.de/fackelmann-eisportionierer-mit-kugel-auswurf-funktion-oe5cm",
|
||||
version: 0,
|
||||
},
|
||||
{
|
||||
id: 30,
|
||||
isBought: false,
|
||||
image: require("../img/geschenke/Gießkanne.png").default,
|
||||
name: "Blechgießkanne",
|
||||
description: "Eine Blechgießkann mit max. 2l Füllvolumen zum Blumengießen in der Wohnung",
|
||||
link: "https://www.bauhaus.info/giesskannen/zimmergiesskanne/p/16640093",
|
||||
version: 0,
|
||||
},
|
||||
{
|
||||
id: 31,
|
||||
isBought: false,
|
||||
image: require("../img/geschenke/Saftpresse.png").default,
|
||||
name: "Saftpresse Thermomix",
|
||||
description: "Saftpressen-Aufsatz für den Thermomix",
|
||||
link: "https://www.wundermix.de/thermomix-zubehoer/zubereiten-aufbewahren/1372/saftpresse-fuer-thermomix-tm6/tm5?",
|
||||
version: 0,
|
||||
},
|
||||
{
|
||||
id: 32,
|
||||
isBought: false,
|
||||
image: require("../img/geschenke/Buch.jpeg").default,
|
||||
name: "Buch „Du+Ich in Ewigkeit“",
|
||||
description: "Buch „Du + Ich in Ewigkeit“",
|
||||
link: "https://www.thalia.de/shop/home/artikeldetails/A1038260264",
|
||||
version: 0,
|
||||
},
|
||||
{
|
||||
id: 33,
|
||||
isBought: false,
|
||||
image: require("../img/geschenke/Backpapier.png").default,
|
||||
name: "Mehrfachverwendbares Backpapier",
|
||||
description: "Spülmaschinenfestes, mehrfachverwendbares Backpapier",
|
||||
link: "https://www.amazon.de/Pritogo-Dauerbackfolie-Backunterlage-sp%C3%BClmaschinenfest-antihaftbeschichtet/dp/B07GNVHQKQ/ref=pd_sbs_3/259-2377249-7131115",
|
||||
version: 0,
|
||||
},
|
||||
{
|
||||
id: 34,
|
||||
isBought: false,
|
||||
image: require("../img/geschenke/Bienenwachstuch.jpeg").default,
|
||||
name: "Großes Bienenwachstuch",
|
||||
description: "Ein großes Bienenwachstuch (mind. 50x40cm) zum Abdecken unserer Auflaufform (Link als Beispiel)",
|
||||
link: "https://pachamama-laden.de/de/item/wildwax-xl-50x40cm-bienenwachstucher-versch-designs",
|
||||
version: 0,
|
||||
},
|
||||
]
|
||||
|
||||
7
src/client/js/setupImageGallery.tsx
Normal file
@@ -0,0 +1,7 @@
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import {ImageGallery} from "./ImageGallery/ImageGallery";
|
||||
|
||||
export function setupImageGallery(){
|
||||
ReactDOM.render(<ImageGallery/>, document.getElementById("gallery"));
|
||||
}
|
||||
@@ -58,4 +58,11 @@
|
||||
.present-name {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.present-info{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
3
src/client/sass/_standesamt.scss
Normal file
@@ -0,0 +1,3 @@
|
||||
#gallery img {
|
||||
height: initial;
|
||||
}
|
||||
@@ -3,6 +3,51 @@
|
||||
$opacityVisible: 0.7;
|
||||
$states: godi fingerfood foto sekt essen spiel dance;
|
||||
|
||||
$positions: (
|
||||
godi: (
|
||||
top: 9.5%,
|
||||
left: 47%,
|
||||
width: initial,
|
||||
height: 12%
|
||||
),
|
||||
fingerfood: (
|
||||
left: 2%,
|
||||
top: 20%,
|
||||
width: 41%,
|
||||
height: 20%,
|
||||
),
|
||||
foto: (
|
||||
left: 54%,
|
||||
top: 36%,
|
||||
width: 33%,
|
||||
height: 12%
|
||||
),
|
||||
sekt: (
|
||||
left: 7%,
|
||||
top: 50%,
|
||||
width: 35%,
|
||||
height: 12%
|
||||
),
|
||||
essen: (
|
||||
left: 54%,
|
||||
top: 62.5%,
|
||||
width: 33%,
|
||||
height: 12%
|
||||
),
|
||||
spiel: (
|
||||
left: 4%,
|
||||
top: 74.5%,
|
||||
width: 37%,
|
||||
height: 12%
|
||||
),
|
||||
dance: (
|
||||
left: 54%,
|
||||
top: 86%,
|
||||
width: 35%,
|
||||
height: 12%
|
||||
)
|
||||
);
|
||||
|
||||
#info-image-container {
|
||||
position: relative;
|
||||
|
||||
@@ -13,61 +58,74 @@ $states: godi fingerfood foto sekt essen spiel dance;
|
||||
}
|
||||
|
||||
img.circler {
|
||||
transition: all 0.2s;
|
||||
position: absolute;
|
||||
height: 12%;
|
||||
opacity: 0;
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
&.visible {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
//left: 0;
|
||||
&.godi {
|
||||
top: 1.5%;
|
||||
left: 51%;
|
||||
top: 9.5%;
|
||||
left: 47%;
|
||||
}
|
||||
|
||||
&.fingerfood {
|
||||
left: 5%;
|
||||
top: 12.5%;
|
||||
width: 38%;
|
||||
left: 2%;
|
||||
top: 20%;
|
||||
width: 41%;
|
||||
height: 20%;
|
||||
}
|
||||
|
||||
&.foto {
|
||||
left: 55%;
|
||||
top: 32%;
|
||||
left: 54%;
|
||||
top: 36%;
|
||||
width: 33%;
|
||||
}
|
||||
|
||||
&.sekt {
|
||||
left: 7%;
|
||||
top: 46.5%;
|
||||
top: 50%;
|
||||
width: 35%;
|
||||
}
|
||||
|
||||
&.essen {
|
||||
left: 55%;
|
||||
top: 60%;
|
||||
width: 32%;
|
||||
left: 54%;
|
||||
top: 62.5%;
|
||||
width: 33%;
|
||||
}
|
||||
|
||||
&.spiel {
|
||||
left: 8%;
|
||||
top: 72.5%;
|
||||
width: 34%;
|
||||
left: 4%;
|
||||
top: 74.5%;
|
||||
width: 37%;
|
||||
}
|
||||
|
||||
&.dance {
|
||||
left: 55%;
|
||||
left: 54%;
|
||||
top: 86%;
|
||||
width: 32%;
|
||||
width: 35%;
|
||||
}
|
||||
}
|
||||
|
||||
@each $state in $states {
|
||||
&[data-state='#{$state}'] .#{$state} {
|
||||
opacity: $opacityVisible;
|
||||
$data: map-get($positions, $state);
|
||||
|
||||
&[data-state='#{$state}'] .circler.visible {
|
||||
//opacity: $opacityVisible;
|
||||
top: map-get($data, "top");
|
||||
left: map-get($data, "left");
|
||||
width: map-get($data, "width");
|
||||
height: map-get($data, "height");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.anchor {
|
||||
@@ -86,7 +144,8 @@ $states: godi fingerfood foto sekt essen spiel dance;
|
||||
&.show-in-dialog {
|
||||
position: fixed;
|
||||
}
|
||||
&:last-child{
|
||||
|
||||
&:last-child {
|
||||
height: calc(100vh - 8rem - 1px);
|
||||
@include breakpoint(medium down) {
|
||||
height: calc(100vh - 7rem - 1px);
|
||||
@@ -121,4 +180,4 @@ $states: godi fingerfood foto sekt essen spiel dance;
|
||||
height: initial;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@import "../../../node_modules/foundation-sites/scss/foundation";
|
||||
@import "node_modules/foundation-sites/scss/foundation";
|
||||
@import "settings";
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
@import "unterkunft";
|
||||
@import "geschenke";
|
||||
@import "tagesablauf";
|
||||
@import "standesamt";
|
||||
|
||||
@font-face {
|
||||
font-family: "WinterSunrise";
|
||||
@@ -184,4 +185,4 @@ img.full-screen-width {
|
||||
&::-webkit-scrollbar{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||