Skip to content

Commit

Permalink
feat(images): add zoomable imager viewer
Browse files Browse the repository at this point in the history
- replace images in sections with thumbnails
  • Loading branch information
SimonGolms committed Jan 15, 2021
1 parent 405e1db commit fe663c4
Show file tree
Hide file tree
Showing 5 changed files with 229 additions and 59 deletions.
82 changes: 82 additions & 0 deletions src/components/ImageViewer/ImageViewer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import {
IonButton,
IonButtons,
IonContent,
IonHeader,
IonIcon,
IonModal,
IonSlide,
IonSlides,
IonToolbar,
} from '@ionic/react';
import { close } from 'ionicons/icons';
import React, {
cloneElement,
ReactElement,
SyntheticEvent,
useState,
} from 'react';
import './imageViewer.css';

type ContainerProps = {
alt: string;
class?: string;
children?: ReactElement;
className?: string;
onError?:
| ((event: SyntheticEvent<HTMLImageElement, Event>) => void)
| undefined;
src: string;
open?: boolean;
};

export const ImageViewer: React.FC<ContainerProps> = (props) => {
const { alt, children, onError = () => {}, open = false, src } = props;

const [isOpen, setIsOpen] = useState(open);

const slideOpts = {
passiveListeners: false,
zoom: {
maxRatio: 5,
},
};

return (
<>
<IonModal
cssClass="image-viewer"
isOpen={isOpen}
onDidDismiss={() => setIsOpen(false)}
swipeToClose
>
<IonHeader translucent>
<IonToolbar>
<IonButtons slot="end">
<IonButton onClick={() => setIsOpen(false)}>
<IonIcon icon={close}></IonIcon>
</IonButton>
</IonButtons>
</IonToolbar>
</IonHeader>
<IonContent fullscreen>
<IonSlides
options={slideOpts}
// Current workaround for strangely behavior of slides
// see: https://github.com/ionic-team/ionic-framework/issues/19638#issuecomment-593412711
onIonSlidesDidLoad={function (this: any) {
this.update();
}}
>
<IonSlide>
<img alt={alt} onError={onError} src={src} />
</IonSlide>
</IonSlides>
</IonContent>
</IonModal>
{cloneElement(children as ReactElement, {
onClick: () => setIsOpen(true),
})}
</>
);
};
31 changes: 31 additions & 0 deletions src/components/ImageViewer/imageViewer.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
.image-viewer {
--border-radius: 0;
--background: transparent;
}

.image-viewer ion-slides {
height: 100vh;
}

.image-viewer ion-slides img {
height: 100vh;
}

.image-viewer ion-toolbar {
--background: transparent;
--border-width: 0 !important;
position: absolute;
}

.image-viewer ion-toolbar::after {
display: none;
}

.image-viewer .modal-wrapper {
display: block;
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}
1 change: 1 addition & 0 deletions src/components/ImageViewer/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { ImageViewer } from './ImageViewer';
48 changes: 35 additions & 13 deletions src/data/chapter/chapter01.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { IonImg, IonText } from '@ionic/react';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { ImageViewer } from '../../components/ImageViewer';
import { ChapterId } from '../../utils/chapters';

const CHAPTER_ID = '01';
const CHAPTER_ID: ChapterId = '01';

export const Section01 = () => {
const sectionId = '01';
Expand Down Expand Up @@ -30,10 +32,15 @@ export const Section01 = () => {
<li>{t(`CHAPTER.${CHAPTER_ID}.${sectionId}.TEXT.LIST.01.070000`)}</li>
<li>{t(`CHAPTER.${CHAPTER_ID}.${sectionId}.TEXT.LIST.01.080000`)}</li>
</ul>
<IonImg
class="ion-padding-vertical"
<ImageViewer
alt={t(`CHAPTER.${CHAPTER_ID}.${sectionId}.IMAGE.01.FILENAME`)}
src={t(`CHAPTER.${CHAPTER_ID}.${sectionId}.IMAGE.01.FILENAME`)}
/>
>
<IonImg
class="ion-padding-vertical"
src={t(`CHAPTER.${CHAPTER_ID}.${sectionId}.IMAGE.01.THUMBNAIL.LARGE`)}
/>
</ImageViewer>
<IonText class="ion-padding-bottom" className="image-text">
{t(`CHAPTER.${CHAPTER_ID}.${sectionId}.IMAGE.01.TITLE`)}
</IonText>
Expand All @@ -56,10 +63,15 @@ export const Section02 = () => {
<li>{t(`CHAPTER.${CHAPTER_ID}.${sectionId}.TEXT.LIST.01.050000`)}</li>
<li>{t(`CHAPTER.${CHAPTER_ID}.${sectionId}.TEXT.LIST.01.060000`)}</li>
</ul>
<IonImg
class="ion-padding-vertical"
<ImageViewer
alt={t(`CHAPTER.${CHAPTER_ID}.${sectionId}.IMAGE.01.FILENAME`)}
src={t(`CHAPTER.${CHAPTER_ID}.${sectionId}.IMAGE.01.FILENAME`)}
/>
>
<IonImg
class="ion-padding-vertical"
src={t(`CHAPTER.${CHAPTER_ID}.${sectionId}.IMAGE.01.THUMBNAIL.LARGE`)}
/>
</ImageViewer>
<IonText class="ion-padding-bottom" className="image-text">
{t(`CHAPTER.${CHAPTER_ID}.${sectionId}.IMAGE.01.TITLE`)}
</IonText>
Expand All @@ -81,10 +93,15 @@ export const Section03 = () => {
<li>{t(`CHAPTER.${CHAPTER_ID}.${sectionId}.TEXT.LIST.01.050000`)}</li>
<li>{t(`CHAPTER.${CHAPTER_ID}.${sectionId}.TEXT.LIST.01.060000`)}</li>
</ul>
<IonImg
class="ion-padding-vertical"
<ImageViewer
alt={t(`CHAPTER.${CHAPTER_ID}.${sectionId}.IMAGE.01.FILENAME`)}
src={t(`CHAPTER.${CHAPTER_ID}.${sectionId}.IMAGE.01.FILENAME`)}
/>
>
<IonImg
class="ion-padding-vertical"
src={t(`CHAPTER.${CHAPTER_ID}.${sectionId}.IMAGE.01.THUMBNAIL.LARGE`)}
/>
</ImageViewer>
<IonText class="ion-padding-bottom" className="image-text">
{t(`CHAPTER.${CHAPTER_ID}.${sectionId}.IMAGE.01.TITLE`)}
</IonText>
Expand Down Expand Up @@ -115,10 +132,15 @@ export const Section04 = () => {
</ul>
<li>{t(`CHAPTER.${CHAPTER_ID}.${sectionId}.TEXT.LIST.01.040000`)}</li>
</ul>
<IonImg
class="ion-padding-vertical"
<ImageViewer
alt={t(`CHAPTER.${CHAPTER_ID}.${sectionId}.IMAGE.01.FILENAME`)}
src={t(`CHAPTER.${CHAPTER_ID}.${sectionId}.IMAGE.01.FILENAME`)}
/>
>
<IonImg
class="ion-padding-vertical"
src={t(`CHAPTER.${CHAPTER_ID}.${sectionId}.IMAGE.01.THUMBNAIL.LARGE`)}
/>
</ImageViewer>
<IonText class="ion-padding-bottom" className="image-text">
{t(`CHAPTER.${CHAPTER_ID}.${sectionId}.IMAGE.01.TITLE`)}
</IonText>
Expand Down
Loading

0 comments on commit fe663c4

Please sign in to comment.