PixelAI-mobile/pages/mobile_web/workshops/index.vue
2024-12-05 11:46:54 +08:00

514 lines
14 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<!-- #ifdef APP -->
<view class="mobile-workshops" :style="{ backgroundImage: `url(${myFileUrl+background})`,paddingTop: CustomBar+'rpx' }">
<view class="app-top" :style="{ height: CustomBar+'rpx',
background: topLevel===0? '#ffffff00' : `rgba(255, 255, 255,${topLevel})` }"></view>
<!-- #endif -->
<!-- #ifndef APP -->
<view class="mobile-workshops" :style="{ backgroundImage: `url(${myFileUrl+background})` }">
<!-- #endif -->
<view class="mwt-top">
<view class="mobile-logo" :style="{backgroundColor: `rgba(255, 255, 255,${topLevel})`}">
<!-- #ifdef H5 -->
<!-- <u-icon name="arrow-left" size="40" color="#c2ea04" class="back" @click="back"></u-icon> -->
<!-- #endif -->
<image :src="myFileUrl+logo"></image>
</view>
<view class="mw-title">
<u-icon name="arrow-left" size="40" color="#fff" class="back" @click="back"></u-icon>
{{ form.title }}
</view>
<view class="mw-upload">
<view class="mwu-cover" v-if="uploadFile==''" @click="selectImage">
<u-icon name="plus-circle" size="100" color="#fff" label="上传图片" labelSize="40"
labelColor="#fff" labelPos="bottom" marginTop="25"></u-icon>
</view>
<view class="center-image" v-else-if="resultFile===''">
<image mode="widthFix" :src="uploadFile" @click="selectImage"></image>
</view>
<view class="center-image" v-else>
<image mode="widthFix" :src="ip+resultFile" @click="previewImage"></image>
</view>
<view class="selections" v-if="form.model=='repaint'">
<view class="selections-item" :style="currentSelect===index?{ backgroundImage: `url(${fileUrl+selectBackground})` }:
{ color: '#000', backgroundImage: `url(${fileUrl+noSelectBackground})` }"
v-for="(item,index) in selections" :key="index" @click="currentSelect=index">
{{ item }}
</view>
</view>
</view>
<view class="mw-editor" v-if="form.model=='repaint'">
<EditorBox :icon="fileUrl+editorIcon"
placeholder="如: 衣服/鞋子/头发或者英文:clothes and shose">
<template #title>
<text class="slot">需<text style="color: #d8fa35;">替换</text>的元素</text>
</template>
</EditorBox>
<EditorBox :icon="fileUrl+editorIcon"
placeholder="如: 衣服/鞋子/头发或者英文:clothes and shose">
<template #title>
<text class="slot"><text style="color: #d8fa35;">替换后</text>的图像</text>
</template>
</EditorBox>
</view>
<view class="workshops-tip" v-else>
Tips{{ resultFile ? '点击预览图片效果~' : placeholderList[form.model] }}
</view>
</view>
<view class="workshops-btn">
<u-button class="wbu-btn" @click="startDeal" v-if="resultFile===''"
ripple :hairLine="false" shape="circle" rippleBgColor="#f0fdbf" :loading='dotLoading'>
<u-icon name="edit-pen" size="42"></u-icon>开启魔法
</u-button>
<u-button :loading="functionLoading" class="wbu-btn" v-else ripple :hairLine="false"
shape="circle" rippleBgColor="#f0fdbf" @click="resultFunction[currentType].fun"
:style="{backgroundImage: resultFunction[currentType].background}" :class="transition?'transition':''">
<u-icon :name="resultFunction[currentType].icon" size="42"></u-icon>
{{ resultFunction[currentType].name }}
</u-button>
<view class="wb-change" v-if="resultFile!==''">
<u-icon :name="fileUrl+'change.png'" size="50" @click="changeFunction"></u-icon>
</view>
</view>
<u-toast ref="uToast"></u-toast>
<DotLoading :show="dotLoading" />
</view>
</template>
<script>
import configService from '@/common/config.service.js';
import { tools } from '@/utils/utils.js';
import EditorBox from './components/editor.vue';
import { selectDealFunction } from './common/imgDeal'
export default {
components: {
EditorBox
},
data(){
return{
// 顶部距离等级
topLevel: 0,
// 基础路径
ip: configService.ip,
myFileUrl: configService.fileUrl + 'pixel/my/',
fileUrl: configService.fileUrl + 'pixel/workshops/',
// 上传图片
// http://8.138.171.103/upload%5CAttachment%5C20241127%5Caa73abfb8b3a433292c94de57aef0a35.png
uploadFile: '',
// 结果图
// upload%5CAttachment%5C20241127%5Caa73abfb8b3a433292c94de57aef0a35.png
resultFile: '',
// logo图标
logo: 'logo.png',
// 我的页面背景
background: 'background.png',
// 数据
form: {
title: '',// 标题
model: ''// 模式
},
// 模式选择
selections:["保留模式","替换模式"],
// 模式选择下标
currentSelect: 0,
// 模式选择背景
selectBackground: 'selectedBd.png',
// 未选择背景
noSelectBackground: 'noSelectedBd.png',
// 编辑图标
editorIcon: 'editor.png',
// 提示语列表
placeholderList: {
stylereplace: '上传图片后,选择更换不同风格~',
animeization: '上传人像图快进入anime的世界吧~',
oldrepair: '上传黑白旧照片,焕发色彩~'
},
// 创作之后的操作按钮
resultFunction: {
download: {
name: '下载',
icon: 'download',
background: 'linear-gradient(to right, #56ab2f 0%, #96fe11 51%, #56ab2f 100%)',
fun: ()=>{this.download()}
},
reUpload: {
name: '重新上传',
icon: 'camera',
background: 'linear-gradient(to right, #c2fc3b 0%, #c2ffd8 51%, #c2fc3b 100%)',
fun: ()=>{this.selectImage()}
},
saveWork: {
name: '保存作品',
icon: 'bookmark',
background: 'linear-gradient(to right, #4AC29A 0%, #BDFFF3 51%, #4AC29A 100%)',
fun: ()=>{}
}
},
// 当前功能按钮
currentType: 'download',
// 当前功能下标
index: 0,
// 下载加载
functionLoading: false,
// 过渡动画
transition: false,
// 图片处理加载动画
dotLoading: false
}
},
// #ifndef H5
onPageScroll(e) {
const level = e.scrollTop/60;
if(level<=1) this.topLevel = level;
else this.topLevel = 1;
},
// #endif
// #ifdef H5
mounted(){
let that = this;
window.onscroll = function () {
//为了保证兼容性,这里取三个值,哪个有值取哪一个
//scrollTop就是触发滚轮事件时滚轮的高度
var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
const level = scrollTop/60;
if(level<=1) that.topLevel = level;
else that.topLevel = 1;
}
},
onHide() {
window.onscroll = null;
},
// #endif
onLoad(options) {
this.form.title = options.name;
this.form.model = options.model;
},
methods:{
// 返回
back(){
uni.navigateBack();
},
// 上传图片
selectImage(){
let that = this;
uni.chooseImage({
count: 1, // 默认9
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
success: (res) => {
// #ifdef H5
if (res.tempFiles[0].type.indexOf('image') === -1) {
that.$refs.uToast.show({
type: 'warning',
title: "图片上传格式错误!"
});
return;
}
// #endif
if(this.resultFile!=='') this.resultFile = '';
that.uploadFile = res.tempFilePaths[0];
}
});
},
// 预览图片
previewImage(){
tools.methods.lookImage(0,[this.ip+this.resultFile,this.uploadFile]);
},
// 开始处理图片
async startDeal(){
try{
this.dotLoading = true;
let that = this;
if(this.uploadFile===''){
this.$refs.uToast.show({type:'error',title: "请上传图片!"});
this.dotLoading = false;
return;
}
// 再实际处理
selectDealFunction(that,that.form.model,that.getParams(that.form.model),
(path)=>{
that.resultFile = path;
that.$refs.uToast.show({type:'success',title: `${that.form.title}成功!`});
this.dotLoading = false;
});
}catch(e){
this.dotLoading = false;
}finally{
}
},
// 获取参数值
getParams(model){
let result,that = this;
switch(model){
case 'oldrepair' :
result = {
filePath: this.uploadFile,
}
break;
case 'animeization' :
result = {
filePath: this.uploadFile,
}
break;
}
return result;
},
// 判断是否在微信内置浏览器打开
// #ifndef APP
isMpWeb(){
if(navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger'){
this.$refs.uToast.show({type:'warning',title: "请在浏览器打开进行下载,或长按图片保存到相册!"});
return true;
}else{
return false;
}
},
// #endif
// 图片下载
async download(){
let that = this;
// #ifndef APP
if(this.isMpWeb()) return;
// #endif
this.functionLoading = true;
if(this.resultFile==='') {
this.$refs.uToast.show({type:'error',title: "暂无结果图片可下载!"});
this.functionLoading = false;
return;
}
// #ifdef H5
uni.request({
url: '/'+that.resultFile,
method: 'GET',
header: { 'token' : that.$store.state.vuex_token },
responseType: 'arraybuffer',
success(res) {
const arrayBuffer = res.data;
const blob = new Blob([arrayBuffer], {type: 'image/png'}); // 创建 Blob 对象
const imageUrl = URL.createObjectURL(blob); // 通过 Blob 对象创建图片 URL
let a = document.createElement('a'); //创建一个 a 标签
a.href = imageUrl; //把路径赋到a标签的href上
a.download = 'pixel.png';
a.click();
URL.revokeObjectURL(imageUrl);
a = null;
that.$refs.uToast.show({type:'success',title: "图片下载成功!"});
},
fail() {
that.$refs.uToast.show({type:'error',title: "图片下载失败,请重试!"});
},
complete() {
that.functionLoading = false;
}
});
// #endif
// #ifndef H5
uni.downloadFile({
url: that.ip+that.resultFile,
header: { 'token': that.$store.state.vuex_token },
success: (res) => {
if (res.statusCode === 200) {
//文件保存到本地
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath, //临时路径
success: function(resp) {
that.$refs.uToast.show({type:'success',title: "下载成功,请前往手机相册查看!"});
}
});
}else{
that.$refs.uToast.show({type:'error',title: "下载失败,请重试!"});
}
},
fail() {
that.$refs.uToast.show({type:'error',title: "暂不支持下载,请长按保存!"});
},
complete() {
that.functionLoading = false;
}
});
// #endif
},
// 切换操作按钮
changeFunction(){
this.transition = true;
const keys = Object.keys(this.resultFunction);
this.index = (this.index+1) % keys.length;
this.currentType = keys[this.index];
setTimeout(()=>{
this.transition = false;
},500)
}
}
}
</script>
<style scoped lang="scss">
.mobile-workshops{
display: flex;
flex-direction: column;
justify-content: space-between;
min-height: 100vh;
background-size: cover;
.mwt-top{
// #ifdef APP
.app-top{
width: 100%;
position: fixed;
z-index: 81;
top: 0;
}
// #endif
.mobile-logo{
width: 100%;
display: flex;
justify-content: center;
position: fixed;
z-index: 81;
padding: 15rpx 0;
image{
width: 200rpx;
height: 45rpx;
}
}
.mw-title{
color: #fff;
font-size: 35rpx;
line-height: 35rpx;
font-weight: bold;
position: relative;
display: flex;
align-items: center;
justify-content: center;
margin: 80rpx 40rpx 32rpx;
height: 40rpx;
.back{
position: absolute;
left: 0;
&:active{
filter: opacity(0.8);
}
}
}
.mw-upload{
display: flex;
flex-direction: column;
margin: 15rpx 100rpx;
.mwu-cover{
width: 100%;
height: 550rpx;
background-color: #626262;
border-radius: 35rpx;
border: 2rpx solid #858585;
display: flex;
align-items: center;
justify-content: center;
&:active{
filter: opacity(0.8);
}
}
.center-image{
border-radius: 35rpx;
width: 100%;
min-height: 650rpx;
display: flex;
align-items: center;
image{
width: 100%;
border-radius: 35rpx;
}
}
.selections{
margin-top: 20rpx;
width: 100%;
display: flex;
align-items: center;
justify-content: flex-end;
.selections-item{
margin-left: 20rpx;
width: 150rpx;
height: 48rpx;
line-height: 50rpx;
border: 56rpx;
color: #fff;
font-weight: bold;
font-size: 20rpx;
display: flex;
align-items: center;
justify-content: center;
background-size: cover;
}
}
}
.mw-editor{
margin: 12rpx 46rpx;
display: flex;
flex-direction: column;
.slot{
color: #fff;
font-size: 32rpx;
font-weight: bold;
}
}
.workshops-tip{
margin-top: 70rpx;
color: #d5ff00;
font-size: 28rpx;
text-align: center;
}
}
.workshops-btn{
display: flex;
align-items: center;
justify-content: center;
margin: 80rpx 0 40rpx;
.wbu-btn{
margin: 0;
border: none;
width: 70%;
height: 100rpx;
color: rgba(42, 35, 61, 0.9);
font-size: 35rpx;
font-weight: bold;
background-size: 200% auto;
transition: 0.5s;
animation-duration: 1s;
animation-fill-mode: both;
background-image: linear-gradient(to right, #c2fc3b 0%, #c2ffd8 51%, #c2fc3b 100%);
&:active {
background-position: right center;
color: #fff;
text-decoration: none;
}
.u-icon{
margin-right: 10rpx;
}
}
.transition{
animation-name: fadeIn;
}
.wb-change{
color: #fff;
margin-left: 20rpx;
margin-right: -70rpx;
&:active{
filter: opacity(0.6);
}
}
}
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
</style>