Skip to content

Commit

Permalink
feat(image-picker): 新增 image-picker 组件
Browse files Browse the repository at this point in the history
  • Loading branch information
jimczj committed Nov 16, 2018
1 parent 83603a4 commit b500eae
Show file tree
Hide file tree
Showing 9 changed files with 484 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ class App extends Component {
'pages/form/picker/index',
'pages/form/picker-view/index',
'pages/form/slider/index',
'pages/form/search-bar/index'
'pages/form/search-bar/index',
'pages/form/image-picker/index'
],
window: {
backgroundTextStyle: 'light',
Expand Down
17 changes: 17 additions & 0 deletions src/components/image-picker/__snapshots__/index.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AtImagePicker Snap render AtImagePicker -- props className 1`] = `"<div class=\\"at-image-picker test\\"><div class=\\"at-image-picker__flex-box\\"><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item at-image-picker__choose-btn\\"><span style=\\"font-size:30px;color:;\\" class=\\"taro-text at-icon at-icon-add\\"></span><input accept=\\"image/*\\" multiple=\\"\\" class=\\"weui-input at-image-picker__file-input\\" type=\\"file\\"/></div></div><div class=\\"at-image-picker__flex-item\\"></div><div class=\\"at-image-picker__flex-item\\"></div><div class=\\"at-image-picker__flex-item\\"></div></div></div>"`;
exports[`AtImagePicker Snap render AtImagePicker -- props customStyle 1`] = `"<div style=\\"color: red\\" class=\\"at-image-picker\\"><div class=\\"at-image-picker__flex-box\\"><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item at-image-picker__choose-btn\\"><span style=\\"font-size:30px;color:;\\" class=\\"taro-text at-icon at-icon-add\\"></span><input accept=\\"image/*\\" multiple=\\"\\" class=\\"weui-input at-image-picker__file-input\\" type=\\"file\\"/></div></div><div class=\\"at-image-picker__flex-item\\"></div><div class=\\"at-image-picker__flex-item\\"></div><div class=\\"at-image-picker__flex-item\\"></div></div></div>"`;
exports[`AtImagePicker Snap render AtImagePicker -- props files 1`] = `"<div class=\\"at-image-picker\\"><div class=\\"at-image-picker__flex-box\\"><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-scaletofill\\" src=\\"https://zos.alipayobjects.com/rmsportal/PZUUCKTRIHWiZSY.jpeg\\"/></div></div></div><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-scaletofill\\" src=\\"https://zos.alipayobjects.com/rmsportal/hqQWgTXdrlmVVYi.jpeg\\"/></div></div></div><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-scaletofill\\" src=\\"https://zos.alipayobjects.com/rmsportal/PZUUCKTRIHWiZSY.jpeg\\"/></div></div></div><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-scaletofill\\" src=\\"https://zos.alipayobjects.com/rmsportal/PZUUCKTRIHWiZSY.jpeg\\"/></div></div></div></div><div class=\\"at-image-picker__flex-box\\"><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-scaletofill\\" src=\\"https://zos.alipayobjects.com/rmsportal/PZUUCKTRIHWiZSY.jpeg\\"/></div></div></div><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item at-image-picker__choose-btn\\"><span style=\\"font-size:30px;color:;\\" class=\\"taro-text at-icon at-icon-add\\"></span><input accept=\\"image/*\\" multiple=\\"\\" class=\\"weui-input at-image-picker__file-input\\" type=\\"file\\"/></div></div><div class=\\"at-image-picker__flex-item\\"></div><div class=\\"at-image-picker__flex-item\\"></div></div></div>"`;
exports[`AtImagePicker Snap render AtImagePicker -- props length 1`] = `"<div class=\\"at-image-picker\\"><div class=\\"at-image-picker__flex-box\\"><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-scaletofill\\" src=\\"https://zos.alipayobjects.com/rmsportal/PZUUCKTRIHWiZSY.jpeg\\"/></div></div></div><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-scaletofill\\" src=\\"https://zos.alipayobjects.com/rmsportal/hqQWgTXdrlmVVYi.jpeg\\"/></div></div></div><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-scaletofill\\" src=\\"https://zos.alipayobjects.com/rmsportal/PZUUCKTRIHWiZSY.jpeg\\"/></div></div></div><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-scaletofill\\" src=\\"https://zos.alipayobjects.com/rmsportal/PZUUCKTRIHWiZSY.jpeg\\"/></div></div></div><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-scaletofill\\" src=\\"https://zos.alipayobjects.com/rmsportal/PZUUCKTRIHWiZSY.jpeg\\"/></div></div></div></div><div class=\\"at-image-picker__flex-box\\"><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item at-image-picker__choose-btn\\"><span style=\\"font-size:30px;color:;\\" class=\\"taro-text at-icon at-icon-add\\"></span><input accept=\\"image/*\\" multiple=\\"\\" class=\\"weui-input at-image-picker__file-input\\" type=\\"file\\"/></div></div><div class=\\"at-image-picker__flex-item\\"></div><div class=\\"at-image-picker__flex-item\\"></div><div class=\\"at-image-picker__flex-item\\"></div><div class=\\"at-image-picker__flex-item\\"></div></div></div>"`;
exports[`AtImagePicker Snap render AtImagePicker -- props mode 1`] = `"<div class=\\"at-image-picker\\"><div class=\\"at-image-picker__flex-box\\"><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-top\\" src=\\"https://zos.alipayobjects.com/rmsportal/PZUUCKTRIHWiZSY.jpeg\\"/></div></div></div><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-top\\" src=\\"https://zos.alipayobjects.com/rmsportal/hqQWgTXdrlmVVYi.jpeg\\"/></div></div></div><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-top\\" src=\\"https://zos.alipayobjects.com/rmsportal/PZUUCKTRIHWiZSY.jpeg\\"/></div></div></div><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-top\\" src=\\"https://zos.alipayobjects.com/rmsportal/PZUUCKTRIHWiZSY.jpeg\\"/></div></div></div></div><div class=\\"at-image-picker__flex-box\\"><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-top\\" src=\\"https://zos.alipayobjects.com/rmsportal/PZUUCKTRIHWiZSY.jpeg\\"/></div></div></div><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item at-image-picker__choose-btn\\"><span style=\\"font-size:30px;color:;\\" class=\\"taro-text at-icon at-icon-add\\"></span><input accept=\\"image/*\\" multiple=\\"\\" class=\\"weui-input at-image-picker__file-input\\" type=\\"file\\"/></div></div><div class=\\"at-image-picker__flex-item\\"></div><div class=\\"at-image-picker__flex-item\\"></div></div></div>"`;
exports[`AtImagePicker Snap render AtImagePicker -- props multiple 1`] = `"<div class=\\"at-image-picker\\"><div class=\\"at-image-picker__flex-box\\"><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item at-image-picker__choose-btn\\"><span style=\\"font-size:30px;color:;\\" class=\\"taro-text at-icon at-icon-add\\"></span><input accept=\\"image/*\\" multiple=\\"multiple\\" class=\\"weui-input at-image-picker__file-input\\" type=\\"file\\"/></div></div><div class=\\"at-image-picker__flex-item\\"></div><div class=\\"at-image-picker__flex-item\\"></div><div class=\\"at-image-picker__flex-item\\"></div></div></div>"`;
exports[`AtImagePicker Snap render AtImagePicker -- props showAddBtn 1`] = `"<div class=\\"at-image-picker\\"><div class=\\"at-image-picker__flex-box\\"><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-scaletofill\\" src=\\"https://zos.alipayobjects.com/rmsportal/PZUUCKTRIHWiZSY.jpeg\\"/></div></div></div><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-scaletofill\\" src=\\"https://zos.alipayobjects.com/rmsportal/hqQWgTXdrlmVVYi.jpeg\\"/></div></div></div><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-scaletofill\\" src=\\"https://zos.alipayobjects.com/rmsportal/PZUUCKTRIHWiZSY.jpeg\\"/></div></div></div><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-scaletofill\\" src=\\"https://zos.alipayobjects.com/rmsportal/PZUUCKTRIHWiZSY.jpeg\\"/></div></div></div></div><div class=\\"at-image-picker__flex-box\\"><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item\\"><div class=\\"at-image-picker__remove-btn\\"><span style=\\"font-size:14px;color:#fff;\\" class=\\"taro-text at-icon at-icon-close\\"></span></div><div class=\\"taro-img at-image-picker__preview-img\\"><img class=\\"taro-img__mode-scaletofill\\" src=\\"https://zos.alipayobjects.com/rmsportal/PZUUCKTRIHWiZSY.jpeg\\"/></div></div></div><div class=\\"at-image-picker__flex-item\\"></div><div class=\\"at-image-picker__flex-item\\"></div><div class=\\"at-image-picker__flex-item\\"></div></div></div>"`;
exports[`AtImagePicker Snap render initial AtImagePicker 1`] = `"<div class=\\"at-image-picker\\"><div class=\\"at-image-picker__flex-box\\"><div class=\\"at-image-picker__flex-item\\"><div class=\\"at-image-picker__item at-image-picker__choose-btn\\"><span style=\\"font-size:30px;color:;\\" class=\\"taro-text at-icon at-icon-add\\"></span><input accept=\\"image/*\\" multiple=\\"\\" class=\\"weui-input at-image-picker__file-input\\" type=\\"file\\"/></div></div><div class=\\"at-image-picker__flex-item\\"></div><div class=\\"at-image-picker__flex-item\\"></div><div class=\\"at-image-picker__flex-item\\"></div></div></div>"`;
204 changes: 204 additions & 0 deletions src/components/image-picker/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
/* eslint-disable no-nested-ternary */
import Taro from '@tarojs/taro'
import { View, Input, Image } from '@tarojs/components'
import PropTypes from 'prop-types'
import classNames from 'classnames'

import AtComponent from '../../common/component'
import AtIcon from '../../components/icon/index'
import './index.scss'

// 生成 jsx 二维矩阵
const generateMatrix = (files, col, showAddBtn) => {
const matrix = []
const length = showAddBtn ? files.length + 1 : files.length
const row = Math.ceil(length / col)
for (let i = 0; i < row; i++) {
if (i === row - 1) {
// 最后一行数据加上添加按钮
const lastArr = files.slice(i * col)
if (lastArr.length < col) {
if (showAddBtn) {
lastArr.push({ type: 'btn' })
}
// 填补剩下的空列
for (let j = lastArr.length; j < col; j++) {
lastArr.push({ type: 'blank' })
}
}
matrix.push(lastArr)
} else {
matrix.push(files.slice(i * col, (i + 1) * col))
}
}
return matrix
}

const defaultFunc = () => {}

export default class AtImagePicker extends AtComponent {
static defaultProps = {
className: '',
customStyle: '',
files: [],
mode: 'scaleToFill',
showAddBtn: true,
multiple: false,
length: 4,
onChange: defaultFunc,
onImageClick: defaultFunc,
onFail: defaultFunc
}

static propTypes = {
className: PropTypes.oneOfType([
PropTypes.string,
PropTypes.array
]),
customStyle: PropTypes.oneOfType([
PropTypes.string,
PropTypes.object
]),
files: PropTypes.array,
showAddBtn: PropTypes.number,
multiple: PropTypes.bool,
length: PropTypes.number,
onChange: PropTypes.func,
onImageClick: PropTypes.func,
onFail: PropTypes.func
}

chooseFile () {
const { onChange, files, onFail, multiple } = this.props
const env = Taro.getEnv()
if (env === Taro.ENV_TYPE.WEB) {
this.fileInput.vnode.dom.click()
} else if (env === Taro.ENV_TYPE.WEAPP) {
// 微信小程序图片选择逻辑
Taro.chooseImage({
count: multiple ? 99 : 1
}).then(res => {
const targetFiles = res.tempFilePaths.map((path, i) => (
{
url: path,
file: res.tempFiles[i]
}
))
onChange(files.concat(targetFiles), 'add')
}).catch(onFail)
}
}

handleImgChoose (event) {
// h5 图片监听逻辑
const { onChange, files, onFail } = this.props
const targetFiles = event.target.files
if (targetFiles) {
for (let i = 0; i < targetFiles.length; i++) {
const reader = new FileReader()
reader.onload = function (e) {
if (!e.target.result) {
onFail(`Fail to get the ${i} image`)
}
files.push({ url: e.target.result, file: targetFiles[i] })
onChange(files, 'add')
}
reader.readAsDataURL(targetFiles[i])
}
}
}

handleImageClick (i) {
const { onImageClick, files } = this.props
onImageClick(i, files[i])
}

handleRemoveImg (i) {
const { onChange, files } = this.props
files.splice(i, 1)
onChange(files, 'remove', i)
}

refFileInput = node => {
this.fileInput = node
}

render () {
const {
className,
customStyle,
files,
mode,
multiple,
length,
showAddBtn
} = this.props
// 行数
const matrix = generateMatrix(files, length, showAddBtn)

return (
<View
className={
classNames('at-image-picker', className)
}
style={customStyle}
>
{
matrix.map((row, i) => (
<View
key={i}
className='at-image-picker__flex-box'
>
{
row.map((item, j) => (
item.url
? <View
className='at-image-picker__flex-item'
key={item}
>
<View className='at-image-picker__item'>
<View
className='at-image-picker__remove-btn'
onClick={this.handleRemoveImg.bind(this, (i * length) + j)}
>
<AtIcon value='close' size='14' color='#fff' />
</View>
<Image
mode={mode}
onClick={this.handleImageClick.bind(this, (i * length) + j)}
className='at-image-picker__preview-img'
src={item.url}
/>
</View>
</View>
: item.type === 'blank'
? <View
className='at-image-picker__flex-item'
key={item}
>
</View>
: <View
className='at-image-picker__flex-item'
onClick={this.chooseFile.bind(this)}
>
<View className='at-image-picker__item at-image-picker__choose-btn'>
<AtIcon value='add' size='30' />
<Input
className='at-image-picker__file-input'
ref={this.refFileInput}
type='file'
accept='image/*'
multiple={multiple ? 'multiple' : ''}
onChange={this.handleImgChoose.bind(this)}
/>
</View>
</View>
))
}
</View>
))
}
</View>
)
}
}
Loading

0 comments on commit b500eae

Please sign in to comment.