1
0
Fork 0
mirror of https://github.com/muerwre/vault-frontend.git synced 2025-04-24 20:36:40 +07:00

NodeImageBlock resizes to content

This commit is contained in:
muerwre 2019-08-25 17:29:26 +07:00
parent a0272f5baa
commit 1299a0e766
5 changed files with 79 additions and 14 deletions

View file

@ -7,13 +7,18 @@ import classNames = require('classnames');
interface IProps { interface IProps {
total: number; total: number;
current: number; current: number;
onChange: (current: number) => void;
} }
const ImageSwitcher: FC<IProps> = ({ total, current }) => ( const ImageSwitcher: FC<IProps> = ({ total, current, onChange }) => (
<div className={styles.wrap}> <div className={styles.wrap}>
<div className={styles.switcher}> <div className={styles.switcher}>
{range(0, total).map(item => ( {range(0, total).map(item => (
<div className={classNames({ is_active: item === current })} key={item} /> <div
className={classNames({ is_active: item === current })}
key={item}
onClick={() => onChange(item)}
/>
))} ))}
</div> </div>
</div> </div>

View file

@ -2,6 +2,7 @@
width: 100%; width: 100%;
height: 0; height: 0;
position: relative; position: relative;
z-index: 2;
} }
.switcher { .switcher {
@ -22,7 +23,7 @@
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
opacity: .5; opacity: 0.5;
transition: opacity 0.25s; transition: opacity 0.25s;
&:hover { &:hover {

View file

@ -1,10 +1,20 @@
import React, { FC, useMemo } from 'react'; import React, {
FC,
useMemo,
useState,
useEffect,
RefObject,
LegacyRef,
useRef,
useCallback,
} from 'react';
import { ImageSwitcher } from '../ImageSwitcher'; import { ImageSwitcher } from '../ImageSwitcher';
import * as styles from './styles.scss'; import * as styles from './styles.scss';
import { INode } from '~/redux/types'; import { INode } from '~/redux/types';
import classNames from 'classnames'; import classNames from 'classnames';
import { getImageSize } from '~/utils/dom'; import { getImageSize } from '~/utils/dom';
import { UPLOAD_TYPES } from '~/redux/uploads/constants'; import { UPLOAD_TYPES } from '~/redux/uploads/constants';
import { readFileSync } from 'fs';
interface IProps { interface IProps {
is_loading: boolean; is_loading: boolean;
@ -12,26 +22,56 @@ interface IProps {
} }
const NodeImageBlock: FC<IProps> = ({ node, is_loading }) => { const NodeImageBlock: FC<IProps> = ({ node, is_loading }) => {
const [current, setCurrent] = useState(0);
const [height, setHeight] = useState(0);
const refs = useRef<HTMLDivElement[]>([]);
// const [refs, setRefs] = useState<Record<number, HTMLDivElement | RefObject<any>>>({});
const images = useMemo( const images = useMemo(
() => () =>
(node && node.files && node.files.filter(({ type }) => type === UPLOAD_TYPES.IMAGE)) || [], (node && node.files && node.files.filter(({ type }) => type === UPLOAD_TYPES.IMAGE)) || [],
[node] [node]
); );
const setRef = useCallback(
index => el => {
refs.current[index] = el;
},
[refs]
);
useEffect(() => {
console.log({ refs });
if (!refs || !refs.current[current]) return;
const el = refs.current[current];
const element_height = el.getBoundingClientRect && el.getBoundingClientRect().height;
setHeight(element_height);
}, [refs, current]);
return ( return (
<div className={classNames(styles.wrap, { is_loading })}> <div className={classNames(styles.wrap, { is_loading })}>
{!is_loading && ( {!is_loading && (
<div> <div>
<ImageSwitcher total={5} current={2} /> <ImageSwitcher total={images.length} current={current} onChange={setCurrent} />
<div className={styles.image_container}> <div className={styles.image_container} style={{ height }}>
{images.map(file => ( {images.map((file, index) => (
<img <div
className={styles.image} className={classNames(styles.image_wrap, { is_active: index === current })}
src={getImageSize(file.url, 'node')} ref={setRef(index)}
alt=""
key={file.id} key={file.id}
/> >
<img
className={styles.image}
src={getImageSize(file.url, 'node')}
alt=""
key={file.id}
/>
</div>
))} ))}
</div> </div>
</div> </div>

View file

@ -5,6 +5,9 @@
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
position: relative;
overflow: hidden;
transition: height 0.5s;
.image { .image {
max-height: 800px; max-height: 800px;
@ -13,3 +16,19 @@
border-radius: $radius $radius 0 0; border-radius: $radius $radius 0 0;
} }
} }
.image_wrap {
width: 100%;
position: absolute;
top: 0;
left: 0;
opacity: 0;
pointer-events: none;
touch-action: none;
z-index: 1;
transition: opacity 0.5s;
&:global(.is_active) {
opacity: 1;
}
}

View file

@ -9,13 +9,13 @@ import { NodePanel } from '~/components/node/NodePanel';
import { NodeRelated } from '~/components/node/NodeRelated'; import { NodeRelated } from '~/components/node/NodeRelated';
import { Tags } from '~/components/node/Tags'; import { Tags } from '~/components/node/Tags';
import { NodeNoComments } from '~/components/node/NodeNoComments'; import { NodeNoComments } from '~/components/node/NodeNoComments';
import { ImageSwitcher } from "~/components/node/ImageSwitcher"; import { ImageSwitcher } from '~/components/node/ImageSwitcher';
interface IProps {} interface IProps {}
const ImageExample: FC<IProps> = () => ( const ImageExample: FC<IProps> = () => (
<Card className={styles.node} seamless> <Card className={styles.node} seamless>
<ImageSwitcher total={5} current={2} /> <ImageSwitcher total={5} current={2} onChange={console.log} />
<div className={styles.image_container}> <div className={styles.image_container}>
<img <img