@@ -136,20 +136,63 @@ async function submit() {
136136 return
137137 submitting .value = true
138138 try {
139- const blob = await new Promise <Blob >((resolve , reject ) => {
140- cropper .value ?.getCropBlob ((blob : Blob | null ) => {
141- if (blob ) {
142- resolve (blob )
139+ const formData = new FormData ()
140+ const isGif = fileRaw .value .type === ' image/gif'
141+ const fileName = fileRaw .value ?.name ?? ' image.png'
142+
143+ if (isGif ) {
144+ const getCropAxisData = await new Promise <string | object >((resolve , reject ) => {
145+ if (! cropper .value ) {
146+ reject (new Error (' 裁切器未初始化' ))
147+ return
143148 }
144- else {
145- reject (new Error (' Failed to crop image' ))
149+ cropper .value .getCropAxis ((axis : string | object ) => resolve (axis ))
150+ })
151+
152+ let x = 0 ; let y = 0 ; let w = 0 ; let h = 0
153+
154+ if (typeof getCropAxisData === ' string' ) {
155+ const axisParts = getCropAxisData .split (' ,' ).map (Number )
156+ if (axisParts .length >= 4 && ! axisParts .some (isNaN )) {
157+ x = axisParts [0 ] || 0
158+ y = axisParts [1 ] || 0
159+ w = axisParts [2 ] || 0
160+ h = axisParts [3 ] || 0
146161 }
162+ }
163+ else if (typeof getCropAxisData === ' object' && getCropAxisData !== null ) {
164+ const axisObj = getCropAxisData as any
165+ x = axisObj .x || 0
166+ y = axisObj .y || 0
167+ w = axisObj .width || 0
168+ h = axisObj .height || 0
169+ }
170+
171+ formData .append (' crop_x' , String (Math .floor (x )))
172+ formData .append (' crop_y' , String (Math .floor (y )))
173+ formData .append (' crop_w' , String (Math .floor (w )))
174+ formData .append (' crop_h' , String (Math .floor (h )))
175+
176+ formData .append (' file' , fileRaw .value , fileName )
177+ }
178+ else {
179+ const blob = await new Promise <Blob >((resolve , reject ) => {
180+ if (! cropper .value ) {
181+ reject (new Error (' 裁切器未初始化' ))
182+ return
183+ }
184+ cropper .value .getCropBlob ((blob : Blob | null ) => {
185+ if (blob ) {
186+ resolve (blob )
187+ }
188+ else {
189+ reject (new Error (' Failed to crop image' ))
190+ }
191+ })
147192 })
148- })
193+ formData .append (' file' , blob , fileName )
194+ }
149195
150- const formData = new FormData ()
151- const fileName = fileRaw .value ?.name ?? ' image.png'
152- formData .append (' file' , blob , fileName )
153196 formData .append (' aspect_id' , props .aspect .id )
154197 formData .append (' name' , metadata .name .trim ())
155198 formData .append (' description' , metadata .description .trim () ?? metadata .name .trim ())
@@ -204,13 +247,16 @@ async function submit() {
204247 <ClientOnly >
205248 <div class =" rounded-lg border h-64 md:h-80 lg:h-96 w-full overflow-hidden" >
206249 <VueCropper
207- ref =" cropper " :img =" filePreviewImage" output-type =" png" :auto-crop =" true" :fixed =" true"
250+ ref =" cropperRef " :img =" filePreviewImage" output-type =" png" :auto-crop =" true" :fixed =" true"
208251 :fixed-number =" cropRatio" :center-box =" false" :auto-crop-width =" cropBox.width"
209252 :auto-crop-height =" cropBox.height" :full =" true" :can-scale =" true" :info-true =" true"
210253 class =" h-64 md:h-80 lg:h-96 w-full"
211254 />
212255 </div >
213256 </ClientOnly >
257+ <div v-if =" fileRaw?.type === 'image/gif'" class =" alert alert-info py-2 shadow-sm text-sm" >
258+ <span >检测到 GIF 动图。预览区将只显示静态帧,但上传成功后在展示处将保留动画效果。</span >
259+ </div >
214260 <div class =" flex flex-wrap gap-2" >
215261 <button class =" btn btn-sm" type =" button" @click =" rotateLeft" >
216262 ⟲ 向左旋转
0 commit comments