Skip to content

Commit

Permalink
feat: add ErrorIcon/Preview use Image
Browse files Browse the repository at this point in the history
  • Loading branch information
zWingz committed Aug 15, 2018
1 parent a1b478d commit 652e10f
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 69 deletions.
1 change: 1 addition & 0 deletions src/assets/img-load-error.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
63 changes: 29 additions & 34 deletions src/lib/Image/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import './style.scss'
import LoadingIcon from '../LoadingIcon'
import { CanUseIntersecion, observe, unobserve } from './observer'
import { PreviewApi } from '../ImgPreview'
import picNull from '../../assets/pic_null.png'
import picError from '../../assets/pic_loading_fail.png'
import ErrorIcon from '../ErrorIcon'
export default class ReactImage extends React.PureComponent {
static propTypes = {
/** Component Style */
Expand All @@ -26,6 +25,8 @@ export default class ReactImage extends React.PureComponent {
imgProps: PropTypes.object,
/** Can it be previewed */
preview: PropTypes.bool,
/** show mask when hover */
mask: PropTypes.bool,
/** onDelete callback, param: src, it will display an icon on right corner when hover */
onDelete: PropTypes.func,
/** Image onError callback, param: src */
Expand All @@ -40,7 +41,8 @@ export default class ReactImage extends React.PureComponent {
width: 100,
group: 'default',
objectFit: 'cover',
preview: true
preview: true,
mask: true
}

constructor() {
Expand All @@ -54,15 +56,6 @@ export default class ReactImage extends React.PureComponent {
loadObserve: !CanUseIntersecion // InterseciontObserver, 监听图片是否出现在viewport
}

get url() {
const { src } = this.props
return src === ''
? picNull
: this.state.isError
? picError
: src
}

get style() {
const { height, width } = this.props
return {
Expand All @@ -73,15 +66,16 @@ export default class ReactImage extends React.PureComponent {
}

get imgStyle() {
const { isLoading, isError } = this.state
const ret = {
objectFit: this.props.objectFit
}
const { imgProps } = this.props
if(imgProps && imgProps.style) {
if (imgProps && imgProps.style) {
Object.assign(ret, imgProps.style)
}
Object.assign(ret, {
display: this.state.isLoading ? 'none' : ''
display: (isLoading || isError) ? 'none' : ''
})
return ret
}
Expand All @@ -98,18 +92,19 @@ export default class ReactImage extends React.PureComponent {
onLoad = () => {
const { onLoad, src } = this.props
this.setState({
isLoading: false
isLoading: false,
isError: false
})
onLoad && onLoad(src)
}

onClickHandler = () => {
const { isLoading, isError } = this.state
const {
src, group, preview, onClick
} = this.props
if(preview && src && !isLoading && !isError) {
const dom = document.querySelectorAll(`.mask-img[data-img-group="${group}"]`)
const { src, group, preview, onClick } = this.props
if (preview && src && !isLoading && !isError) {
const dom = document.querySelectorAll(
`.mask-img[data-img-group="${group}"]`
)
const list = Array.from(dom).map(each => each.dataset.imgSrc)
PreviewApi.preview(src, list)
}
Expand All @@ -131,44 +126,44 @@ export default class ReactImage extends React.PureComponent {

render() {
// const { width, height } = this.props
const {
group, imgProps, onDelete, src
} = this.props
const { isLoading, loadObserve } = this.state
const { group, imgProps, onDelete, src, height, preview, className, mask } = this.props
const { isLoading, loadObserve, isError } = this.state

return (
<span
className={['mask-img', this.props.className].join(
' '
)}
data-img-group={group}
data-img-src={this.url}
className={['mask-img', mask ? 'mask' : '', className].join(' ')}
data-img-group={preview ? group : null}
data-img-src={preview ? src : null}
style={this.style}
ref={this.refDom}
>
{this.props.onDelete ? (
{onDelete ? (
<span className="delete-img">
<i className="react-image-icon" style={{display: 'inline-block'}} onClick={() => onDelete(src)}>
<i
className="react-image-icon"
style={{ display: 'inline-block' }}
onClick={() => onDelete(src)}
>
&#xe904;
</i>
</span>
) : null}
{loadObserve && (
<img
{...imgProps}
src={this.url}
src={src}
onError={this.onError}
onLoad={this.onLoad}
onClick={this.onClickHandler}
style={this.imgStyle}
/>
)}
{isLoading && (
<div className="mask-loading">
<div className="mask-loading" style={{minHeight: `${height || 100}px`}}>
<LoadingIcon size="sm" />
<span className="mask-loading-text">Loading</span>
</div>
)}
{isError && <ErrorIcon style={{ width: '100%', height: '100%' }} />}
</span>
)
}
Expand Down
8 changes: 4 additions & 4 deletions src/lib/Image/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,11 @@
position: relative;
flex-shrink: 0;
&:hover {
&:after {
background: rgba(0, 0, 0, 0.1);
}
.delete-img {
opacity: 1;
}
}
&:after {
&.mask::after {
content: '';
pointer-events: none;
position: absolute;
Expand All @@ -23,6 +20,9 @@
bottom: -2px;
transition: background 0.1s ease;
background: transparent;
&:hover::after {
background: rgba(0, 0, 0, 0.1);
}
}
img {
width: 100%;
Expand Down
72 changes: 50 additions & 22 deletions src/lib/ImgPreview/ImgPreview.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import React from 'react'
// import { reaction } from 'mobx'
import ReactDOM from 'react-dom'
import LoadingIcon from '../LoadingIcon'
import ErrorIcon from '../ErrorIcon'
import Image from '../Image'
// import Store from './imgViewStore'
function find(list, arg) {
return list.findIndex(each => each === arg)
Expand All @@ -23,7 +25,8 @@ export default class ImgPpreview extends React.PureComponent {
current: 0,
open: false,
changed: false,
loaded: false
loaded: false,
error: false
}

/**
Expand All @@ -41,15 +44,15 @@ export default class ImgPpreview extends React.PureComponent {
exportPreview = (current, list) => {
let l = this.state.images
let c = current
if(list) {
if (list) {
l = list
}
// 如果为number型则直接设置
if(typeof c !== 'number') {
if (typeof c !== 'number') {
// 否则调用find方法找下标
// 如果不存在则设为images
const idx = find(l, c)
if(idx === -1) {
if (idx === -1) {
l = [c]
c = 0
} else {
Expand All @@ -73,11 +76,11 @@ export default class ImgPpreview extends React.PureComponent {
e.stopPropagation()
e.preventDefault()
const { keyCode } = e
if(keyCode === 27) {
if (keyCode === 27) {
this.hide()
} else if(keyCode === 37) {
} else if (keyCode === 37) {
this.prev()
} else if(keyCode === 39) {
} else if (keyCode === 39) {
this.next()
}
}
Expand All @@ -90,10 +93,10 @@ export default class ImgPpreview extends React.PureComponent {
*/
hideHandle = e => {
const { target } = e
if(
target === this.$close
|| target === this.$el
|| target === this.$footer
if (
target === this.$close ||
target === this.$el ||
target === this.$footer
) {
this.hide()
}
Expand Down Expand Up @@ -191,7 +194,7 @@ export default class ImgPpreview extends React.PureComponent {
*/
mouseDownHandle = e => {
e.stopPropagation()
if(e.button !== 0) {
if (e.button !== 0) {
return
}
const container = this.$el
Expand Down Expand Up @@ -240,7 +243,7 @@ export default class ImgPpreview extends React.PureComponent {
// 放大缩小功能
// const delta = e.wheelDelta ? e.wheelDelta : -(e.detail || 0)
let { scale } = this.state
if(-e.deltaY < 0) {
if (-e.deltaY < 0) {
// 放大
scale *= 1.2
} else {
Expand All @@ -263,12 +266,13 @@ export default class ImgPpreview extends React.PureComponent {
const width = img.naturalWidth
let scale = 1
const windwoWidth = (window.innerWidth * 3) / 4
if(width > windwoWidth) {
if (width > windwoWidth) {
scale = windwoWidth / width
}
this.setState(
{
loaded: true
loaded: true,
error: false
},
() => {
setTimeout(() => {
Expand All @@ -280,6 +284,14 @@ export default class ImgPpreview extends React.PureComponent {
)
}

imgOnError = e => {
console.log('onError');
this.setState({
loaded: true,
error: true
})
}

get scaleFixed() {
return +this.state.scale.toFixed(2)
}
Expand Down Expand Up @@ -316,6 +328,7 @@ export default class ImgPpreview extends React.PureComponent {

get imgListStyle() {
return {
display: 'flex',
transform: `translate3d(-${this.state.current * 50}px, 0, 0)`,
transition: 'transform .3s linear'
}
Expand All @@ -329,6 +342,7 @@ export default class ImgPpreview extends React.PureComponent {
mouseWheelHandle,
mouseDownHandle,
imgOnLoad,
imgOnError,
imgSty,
prev,
next,
Expand Down Expand Up @@ -361,16 +375,20 @@ export default class ImgPpreview extends React.PureComponent {
<img
className={[
'img-viewer-current',
state.loaded ? '' : 'dis-none'
state.loaded && !state.error ? '' : 'dis-none'
].join(' ')}
onMouseDown={mouseDownHandle}
onLoad={imgOnLoad}
onError={imgOnError}
src={currentImg}
alt=""
draggable="false"
style={imgSty}
/>
{!state.loaded && <LoadingIcon />}
{state.error && (
<ErrorIcon style={{ width: '300px', height: '300px' }} />
)}
</React.Fragment>
)}
<div
Expand Down Expand Up @@ -405,12 +423,22 @@ export default class ImgPpreview extends React.PureComponent {
<div className="img-viewer-list-inner">
<div style={this.imgListStyle}>
{state.images.map((src, idx) => (
<img
className={state.current === idx ? 'active' : ''}
src={src}
key={idx}
<div
onClick={() => this.change(idx)}
/>
key={idx}
className={[
'img-viewer-list-item',
state.current === idx ? 'active' : ''
].join(' ')}
>
<Image
width="50"
height="50"
preview={false}
mask={false}
src={src}
/>
</div>
))}
</div>
</div>
Expand All @@ -425,7 +453,7 @@ ImgPpreview.newInstance = function newNotificationInstance(callback) {
const div = document.createElement('div')
let called = false
function ref(ins) {
if(called) {
if (called) {
return
}
called = true
Expand Down
13 changes: 4 additions & 9 deletions src/lib/ImgPreview/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -78,18 +78,13 @@
overflow: auto;
background: rgba(0, 0, 0, 0.7);
overflow: hidden;
img {
// border: 2px solid transparent;
object-fit: cover;
width: 50px;
.img-viewer-list-item {
opacity: .5;
height: 50px;
box-sizing: border-box;
border: 1px solid transparent;
// margin: 0 5px;
&:hover {
opacity: 1;
}
&.active {
opacity: 1;
border-color: #fff;
}
}
}
Expand Down

0 comments on commit 652e10f

Please sign in to comment.