回答編集履歴

2

脱字の修正

2019/01/18 03:01

投稿

yhg
yhg

スコア2161

test CHANGED
@@ -54,7 +54,7 @@
54
54
 
55
55
  2. `uploadedImage` はレイヤーと同じ数だけ保存しないと、反映した途端に全レイヤー同じ画像になります。
56
56
 
57
- 下記のサンプルコードでは配列の添字を使っているため、レイヤー配列が並び替わったり、間にレイヤーが追加されたりすると `uploadedImages` とレイヤーの対応付けが崩れますが、レイヤーごとにユニークIDを割り振っている場合は、`uploadedImages`を配列ではなくオブジェクトに変更し、IDで対応付けする形することで対応付けが崩れなくなります。
57
+ 下記のサンプルコードでは配列の添字を使っているため、レイヤー配列が並び替わったり、間にレイヤーが追加されたりすると `uploadedImages` とレイヤーの対応付けが崩れますが、レイヤーごとにユニークIDを割り振っている場合は、`uploadedImages`を配列ではなくオブジェクトに変更し、IDで対応付けする形することで対応付けが崩れなくなります。
58
58
 
59
59
 
60
60
 

1

コメントを受けての追記

2019/01/18 03:01

投稿

yhg
yhg

スコア2161

test CHANGED
@@ -41,3 +41,179 @@
41
41
  },
42
42
 
43
43
  ```
44
+
45
+
46
+
47
+ ## 追記
48
+
49
+
50
+
51
+ 1. `v-for` の内側で `ref` を使うとややこしいことになるので、単純に `event.target` を参照したほうが良いです。
52
+
53
+
54
+
55
+ 2. `uploadedImage` はレイヤーと同じ数だけ保存しないと、反映した途端に全レイヤー同じ画像になります。
56
+
57
+ 下記のサンプルコードでは配列の添字を使っているため、レイヤー配列が並び替わったり、間にレイヤーが追加されたりすると `uploadedImages` とレイヤーの対応付けが崩れますが、レイヤーごとにユニークIDを割り振っている場合は、`uploadedImages`を配列ではなくオブジェクトに変更し、IDで対応付けする形することで対応付けが崩れなくなります。
58
+
59
+
60
+
61
+ 3. `getDataURI` は非同期関数なので、 `async/await` を使わないと、 `uploadedImage` に文字列ではなく `Promise` インスタンスが代入されてしまいます。
62
+
63
+ それと今回の `getDataURI` のように使い回しの効く関数はなるべく別ファイルに分離したほうが良いです。
64
+
65
+
66
+
67
+ 以上3点をふまえると下記のような感じでしょうか。
68
+
69
+
70
+
71
+ ```js
72
+
73
+ // utils/getDataURI
74
+
75
+ export function getDataURI(file) {
76
+
77
+ return new Promise((resolve, reject) => {
78
+
79
+ const reader = new FileReader()
80
+
81
+ reader.readAsDataURL(file)
82
+
83
+ reader.onload = () => resolve(reader.result)
84
+
85
+ reader.onerror = error => reject(error)
86
+
87
+ })
88
+
89
+ }
90
+
91
+ ```
92
+
93
+
94
+
95
+ ```vue
96
+
97
+ //image.vue
98
+
99
+ <template>
100
+
101
+ <div>
102
+
103
+ <div v-for="(image, index) in layer">
104
+
105
+ <img v-show="index in uploadedImages && uploadedImages[index]" :src="uploadedImages[index]" />
106
+
107
+ <input type="file" @change="event => onFileChange(event, index)" />
108
+
109
+ <el-button @click="setImage(index)">反映</el-button>
110
+
111
+ </div>
112
+
113
+ </div>
114
+
115
+ </template>
116
+
117
+
118
+
119
+ <script>
120
+
121
+ import { getDataURI } from '@/utils/getDataURI'
122
+
123
+
124
+
125
+ export default {
126
+
127
+ props: ['tmp_template'],
128
+
129
+ data() {
130
+
131
+ return {
132
+
133
+ uploadedImages: []
134
+
135
+ }
136
+
137
+ },
138
+
139
+ computed: {
140
+
141
+ layer() {
142
+
143
+ return this.tmp_template.layers.filter(function(layer) {
144
+
145
+ if (layer.type === 'image') {
146
+
147
+ return layer
148
+
149
+ }
150
+
151
+ })
152
+
153
+ },
154
+
155
+ },
156
+
157
+ methods: {
158
+
159
+ viewValue() {
160
+
161
+ //previe.vueの関数
162
+
163
+ this.$emit('viewValue')
164
+
165
+ },
166
+
167
+ async onFileChange(event, index) {
168
+
169
+ const { files } = event.target
170
+
171
+ const file = files.item(0)
172
+
173
+ if (file) {
174
+
175
+ this.uploadedImages[index] = await getDataURI(file)
176
+
177
+ }
178
+
179
+ },
180
+
181
+ setImage(index) {
182
+
183
+ this.layer[index].value = this.uploadedImages[index]
184
+
185
+ this.viewValue()
186
+
187
+ }
188
+
189
+ },
190
+
191
+ }
192
+
193
+ </script>
194
+
195
+ ```
196
+
197
+
198
+
199
+ ```js
200
+
201
+ // preview.vue の一部
202
+
203
+ else if(layer.type === 'image' && layer.value)
204
+
205
+ {
206
+
207
+       //画像表示処理
208
+
209
+ let image1 = new Image()
210
+
211
+ image1.src = layer.value
212
+
213
+ // もしかしたら 画像の load イベント待たないと drawImage 失敗するかも?要検証
214
+
215
+ this.ctx.drawImage(image1, 0, 0)
216
+
217
+ }
218
+
219
+ ```