-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.tsx
251 lines (217 loc) · 6.58 KB
/
index.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
// feat: 哈理工 70 周年校庆官方活动
import React, { Component, Fragment } from 'react'
import { connect } from 'react-redux'
import Taro from '@tarojs/taro'
import { View, Image, Button, ScrollView, Canvas } from '@tarojs/components'
import { IRootState } from '@/types'
import { Cropper, withShare } from '@/components'
import cn from 'classnames'
import WeCropper from 'we-cropper'
// import { eventCenter, getCurrentInstance } from '@tarojs/taro'
import { saveImage } from '@/utils'
import bgImg from './res/bg.png'
import shareIcon from './res/share-icon.jpg'
import './index.less'
type PropsFromState = ReturnType<typeof mapStateToProps>
type PropsFromDispatch = {}
type PageOwnProps = {}
type PageState = {
image: string,
step: number, // 三步
frameIndex: number,
cropperImage: string,
combineImage: string,
}
type IProps = PropsFromState & PropsFromDispatch & PageOwnProps
const { windowWidth } = Taro.getSystemInfoSync()
class SchoolAnniversary extends Component<IProps, PageState> {
state: Readonly<PageState> = {
image: '',
step: 0,
frameIndex: 0,
cropperImage: '',
combineImage: '',
}
componentDidMount() {
}
cropper: WeCropper
onLoad() {
}
// 相机、相册
chooseImage = () => {
Taro.chooseImage({
count: 1, // 默认9
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
success: (res) => {
const image = res.tempFilePaths[0]
this.setState({
image
})
},
})
}
// 用户点击下一步
nextStep = async () => {
const nextStep = this.state.step + 1
// 需要获取裁剪之后的图片
if (nextStep === 1) {
// @ts-ignore
const path = await this.cropper.getCropperImage({ original: true })
this.setState({
cropperImage: path
})
}
// 合成图片
if (nextStep === 2) {
this.initCombineCanvas()
return
}
// 用户点击保存图片
if (nextStep === 3) {
this.saveCombineImage()
return
}
this.setState({
step: nextStep,
})
}
// 用户点击上一步
prevStep = () => {
const nextStep = this.state.step - 1
this.setState({
step: nextStep,
})
}
// 合并图片
initCombineCanvas = async () => new Promise((resolve) => {
Taro.showLoading()
const ctx = Taro.createCanvasContext('combineCanvas')
const { cropperImage, frameIndex } = this.state
const frameImage = require(`./res/avatar-frames/${frameIndex + 1}.png`).default
ctx.drawImage(cropperImage, windowWidth / 2 - 150, 0, 300, 300)
ctx.drawImage(frameImage, windowWidth / 2 - 150, 0, 300, 300)
ctx.draw(false, () => {
Taro.canvasToTempFilePath({
x: windowWidth / 2 - 150,
y: 0,
height: 300,
width: 300,
canvasId: 'combineCanvas',
success: (res) => {
this.setState({
combineImage: res.tempFilePath,
step: 2
}, resolve)
Taro.hideLoading()
},
fail: (error) => {
console.log('error', error)
Taro.hideLoading()
}
})
})
})
// 保存图片到本地
saveCombineImage = () => {
const { combineImage } = this.state
saveImage(combineImage)
}
// 获取头像
onGetUserInfo = (e) => {
// 授权失败不允许登录
if (/fail auth deny/.test(e.detail.errMsg)) {
return
}
if (e.detail.userInfo) {
Taro.setStorageSync('userInfo', e.detail.userInfo)
}
let { avatarUrl } = e.detail.userInfo
if (avatarUrl.endsWith('132')) {
avatarUrl = avatarUrl.substring(0, avatarUrl.length - 3)
avatarUrl = `${avatarUrl}0`
}
this.setState({
image: avatarUrl
})
}
// cropper 加载完成
onCropperReady = (cropper: WeCropper) => {
this.cropper = cropper
}
// 切换头像框
chooseFrame = (frameIndex: number) => {
this.setState({
frameIndex,
step: 1, // 切换图片一定是步骤 1
})
}
clearCanvas = () => {
this.setState({
image: ''
})
}
render () {
const { image, step, frameIndex, cropperImage } = this.state
return (
<View className="school-snniversary">
<Image src={bgImg} className="bg-image" mode="widthFix" />
<View className={cn('cropper-wrapper', {
hidden: !image
})}
>
{(step === 1 || step === 2) && <Image src={cropperImage} className="frame" />}
{(step === 1 || step === 2) && <Image src={require(`./res/avatar-frames/${frameIndex + 1}.png`).default} className="frame" />}
{step === 0 && <Cropper src={image} onReady={this.onCropperReady} />}
{step === 0 && image && <View className="tips">*图片可以缩放、裁剪</View>}
</View>
{
step === 1 && <ScrollView className="frames" scrollX>
{
Array(7).fill(0).map((_, index) => {
return <Image className={cn('frame', {
active: index === frameIndex
})} key={index} src={require(`./res/avatar-frames/${index + 1}.png`).default} onClick={() => this.chooseFrame(index)}
></Image>
})
}
</ScrollView>
}
<View className="btn-wrapper">
{
step === 0 && <Fragment>
<Button data-way="camera" openType="getUserInfo" onGetUserInfo={this.onGetUserInfo}>使用微信头像</Button>
<Button data-way="album" onClick={this.chooseImage}>使用相机/相册</Button>
</Fragment>
}
<Fragment>
{ step > 0 && <Button onClick={this.prevStep}>上一步</Button>}
{/* { step === 0 && image && <Button onClick={this.clearCanvas}>清空画布</Button>} */}
<Button
onClick={this.nextStep}
className={cn({
// flex1: step === 0 && !image
flex1: step === 0
})}
disabled={!image}
>{ step === 2 ? '保存图片' : '下一步'}</Button>
</Fragment>
</View>
<Canvas
type="33"
canvasId="combineCanvas"
// canvas-id="combine-canvas"
className="combine-canvas"
style="height:300px;;width:100%;"
/>
</View>
)
}
}
const mapStateToProps = (state: IRootState) => ({
user: state.user,
})
export default withShare({
title: '理工70周年专属校庆头像上线!',
imageUrl: shareIcon,
})(SchoolAnniversary)