Merge remote-tracking branch 'origin/develop' into dev_vite

This commit is contained in:
X1627315083
2025-06-19 09:38:42 +08:00
24 changed files with 8310 additions and 9513 deletions

View File

@@ -485,6 +485,7 @@ export default defineComponent({
float: left;
user-select:none;
-webkit-user-drag: none;
object-fit: cover;
}
.modal_imgItem{
position: absolute;

View File

@@ -101,7 +101,7 @@ export default defineComponent({
eventLangData = eventDataCn
}
eventLangData.eventsItem.forEach((item:any)=>{
if(item.id == router.currentRoute.value.query.id){
if(item.id == router.currentRoute.value.query.eventId){
filter.eventsDetail = item;
}
})

View File

@@ -728,11 +728,6 @@ export default defineComponent({
if(rv.filter((item:any)=>item.status == 'Invalid').length ==dataNum){
message.info(this.t('Generate.effectPoor'));
}else{
nextTick().then(()=>{
if(this.driver__.driver){
driverObj__.moveNext()
}
})
}
this.store.dispatch('getCredits')

View File

@@ -687,7 +687,7 @@ export default defineComponent({
display: flex;
align-items: center;
justify-content: center;
z-index: 2;
z-index: 99;
.operate_icon{
font-size: 1.8rem;
color: #fff;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,452 +1,429 @@
<template>
<div class="Falls">
<div
class="falls_item"
v-fadeIn="isScroll"
v-for="item in list"
:key="item.id"
:style="{
width: item.style.width + 'px',
height: item.style.height + 'px',
top: item.style.top + 'px',
left: item.style.left + 'px',
}"
>
<!-- 图片 -->
<div class="falls_item_img">
<img
v-lazy="item.canvasUrl"
@click="setItemDetail(item)"
:style="{
height: item.style.imgHeihgt + 'px',
}"
/>
<div v-if="item.original == 1" class="falls_item_user_Original">
{{ $t("newScaleImage.Original") }}
</div>
</div>
<!-- 文字 -->
<div class="falls_item_bottom" v-if="isText">
<div class="falls_item_text" :title="item.text">
{{ item.text }}
</div>
<div class="falls_item_content">
<div class="falls_item_user">
<!-- <img src="http://121.40.53.210:3000/falls/5.png" alt=""> -->
<div class="falls_item_user_detail">
<span>@{{ item.userName }}</span>
<div :title="item.portfolioName">{{ item.portfolioName }}</div>
<!-- <span :title="item.portfolioDes">{{item.portfolioDes}}</span> -->
</div>
</div>
<div class="falls_item_detail">
<!-- <div>
<div class="Falls">
<div class="falls_item" v-fadeIn="isScroll" v-for="item in list" :key="item.id"
:style="{
width: item.style.width + 'px',
height: item.style.height + 'px',
top: item.style.top + 'px',
left: item.style.left + 'px',
}"
>
<!-- 图片 -->
<div class="falls_item_img">
<img
v-lazy="item.canvasUrl"
@click="setItemDetail(item)"
:style="{
height: item.style.imgHeihgt + 'px',
}"
/>
<div v-if="item.original == 1" class="falls_item_user_Original">{{$t('newScaleImage.Original')}}</div>
</div>
<!-- 文字 -->
<div class="falls_item_bottom" v-if="isText">
<div class="falls_item_text" :title="item.text">
{{item.text}}
</div>
<div class="falls_item_content">
<div class="falls_item_user">
<!-- <img src="http://121.40.53.210:3000/falls/5.png" alt=""> -->
<div class="falls_item_user_detail">
<span>@{{ item.userName }}</span>
<div :title="item.portfolioName">{{item.portfolioName}}</div>
<!-- <span :title="item.portfolioDes">{{item.portfolioDes}}</span> -->
</div>
</div>
<div class="falls_item_detail">
<!-- <div>
<svg xmlns="http://www.w3.org/2000/svg" width="2.5rem" height="2.5rem" viewBox="0 0 16 16" fill="none" role="img" :style="{color:'#9e9ea7',fill: 'currentColor'}">
<path d="M10.7408 2C13.0889 2 14.6667 4.235 14.6667 6.32C14.6667 10.5425 8.11856 14 8.00004 14C7.88152 14 1.33337 10.5425 1.33337 6.32C1.33337 4.235 2.91115 2 5.2593 2C6.60745 2 7.48893 2.6825 8.00004 3.2825C8.51115 2.6825 9.39263 2 10.7408 2Z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
</svg>
<span>{{item.viewNums}}</span>
</div> -->
<label @click="portfolioLike(item)">
<i
v-if="true"
class="fi fi-sr-thumbs-up"
style="color: rgba(158, 158, 167)"
></i>
<i v-else class="fi fi-rr-social-network"></i>
<span>{{ item.likeNum }}</span>
</label>
<div>
<!-- <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none" role="img" style="color: #9e9ea7;fill: currentColor;">
<label @click="portfolioLike(item)">
<i v-if="true" class="fi fi-sr-thumbs-up" style="color:rgba(158, 158, 167);"></i>
<i v-else class="fi fi-rr-social-network"></i>
<span>{{item.likeNum}}</span>
</label>
<div>
<!-- <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none" role="img" style="color: #9e9ea7;fill: currentColor;">
<path d="M8 3C4.36992 3 1.98789 6.21774 1.18763 7.49059C1.09079 7.64462 1.04237 7.72163 1.01527 7.84042C0.99491 7.92964 0.99491 8.07036 1.01527 8.15958C1.04237 8.27837 1.09079 8.35539 1.18763 8.50941C1.98789 9.78226 4.36992 13 8 13C11.6301 13 14.0121 9.78226 14.8124 8.50941L14.8124 8.50939C14.9092 8.35538 14.9576 8.27837 14.9847 8.15958C15.0051 8.07036 15.0051 7.92964 14.9847 7.84042C14.9576 7.72163 14.9092 7.64462 14.8124 7.4906L14.8124 7.49059C14.0121 6.21774 11.6301 3 8 3Z" fill="currentColor"></path>
<path d="M8 10C9.10457 10 10 9.10457 10 8C10 6.89543 9.10457 6 8 6C6.89543 6 6 6.89543 6 8C6 9.10457 6.89543 10 8 10Z" fill="white"></path>
</svg> -->
<i class="fi fi-sr-eye"></i>
<span>{{ item.viewNums }}</span>
</div>
</div>
</div>
</div>
</div>
</div>
<i class="fi fi-sr-eye"></i>
<span>{{item.viewNums}}</span>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import {
defineComponent,
h,
toRefs,
ref,
reactive,
onMounted,
nextTick,
provide,
computed,
} from "vue";
import { defineComponent,h ,toRefs,ref,reactive,onMounted,onBeforeDestroy,nextTick,provide,computed} from 'vue'
import { gsap, TweenMax } from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
export default defineComponent({
props: {
isScroll: {
type: Boolean,
default: true,
},
isText: {
type: Boolean,
default: true,
},
itemWidth: {
type: Number,
default: 300,
},
},
setup() {
let list = ref([]);
let wait_list = ref([]);
let width = ref(300);
let num_x = ref(1);
let gap_x = ref(0);
let gap_y = ref(0);
let poss = ref([]);
let loading = ref(false);
let computedHeight = 0;
let imgDom = ref();
return {
list,
wait_list,
width,
num_x,
gap_x,
gap_y,
poss,
loading,
computedHeight,
imgDom,
};
},
directives: {
fadeIn: {
mounted(el, binding) {
let dom;
if (binding.value) {
dom = document.querySelector(".works_page .page_content");
} else {
dom = document.querySelector(".homeRecommend_content_body");
}
gsap.registerPlugin(ScrollTrigger);
let tl1 = gsap.timeline();
tl1.from(el, 1, { y: "30px", opacity: 0 });
ScrollTrigger.create({
trigger: el, // 触发器元素
start: "top 90%", // 滚动触发器的起始滚动位置
end: "100% 80%", // 滚动触发器的结束滚动位置
// markers: true, // 开启标注功能
scrub: true,
animation: tl1,
scroller: dom, //设置指定元素为滚动依据
scrub: 2,
// onUpdate:(v)=>{
// if(v.progress < 0.1){
// v.trigger?.classList.remove('active')
// }else{
// v.trigger?.classList.add('active')
// // v.trigger?.classList.add('active')
// }
// }
});
},
},
},
mounted() {
this.resize();
window.addEventListener("resize", this.resize);
let domFalls = document.querySelector(".Falls");
let domCss = getComputedStyle(domFalls);
const paddingBottom =
domCss.getPropertyValue("--paddingBottom").split("px")[0] * 1;
const textMarginTop =
domCss.getPropertyValue("--textMarginTop").split("px")[0] * 1;
const textHeight =
domCss.getPropertyValue("--textHeight").split("px")[0] * 1;
const contentHeight =
domCss.getPropertyValue("--contentHeight").split("px")[0] * 1;
if (this.$props.isText) {
this.computedHeight =
paddingBottom + textMarginTop + textHeight + contentHeight;
}
},
beforeDestroy() {
this.wait_list = [];
window.removeEventListener("resize", this.resize);
},
// 挂载方法
methods: {
clearData() {
this.wait_list = [];
this.width = this.itemWidth;
this.num_x = 1;
this.gap_x = 0;
this.gap_y = 0;
this.poss = [];
this.loading = false;
this.list = [];
this.resize();
if (this.imgDom) {
this.imgDom.remove();
this.imgDom = null;
}
},
push(arr) {
this.wait_list = this.wait_list.concat(arr);
if (!this.loading) {
this.loading = true;
this.loadImg();
}
},
deleteItem(id) {
for (let index = 0; index < this.list.length; index++) {
if (this.list[index].id == id) {
this.list.splice(index, 1);
this.resize();
break;
}
}
},
loadImg() {
if (this.wait_list.length <= 0) {
this.loading = false;
this.$emit("loadend");
return;
}
let url = this.wait_list[0].canvasUrl || this.wait_list[0].url;
let data = this.wait_list[0];
this.imgDom = document.createElement("img");
this.imgDom.src = url;
this.imgDom.style.width = this.itemWidth + "px";
this.imgDom.style.maxHeight = this.itemWidth + 330 + "px";
this.imgDom.style.position = "absolute";
this.imgDom.style.top = "-99999px";
document.body.appendChild(this.imgDom);
this.imgDom.addEventListener("load", () => {
if (!this.imgDom) return;
var idx = 0;
var pos_num = this.poss[idx];
for (var i = 1; i < this.poss.length; i++) {
if (pos_num > this.poss[i]) {
idx = i;
pos_num = this.poss[i];
}
}
// this.computedHeight = 0
let width = this.imgDom.offsetWidth;
let height = this.imgDom.offsetHeight + this.computedHeight;
let top = this.poss[idx] + this.gap_y;
let left = (idx + 1) * this.gap_x + idx * width;
let imgHeight = height - this.computedHeight;
this.poss[idx] = top + height;
let obj = {
canvasUrl: url,
style: { width, height, top, left, imgHeight },
...data,
};
this.list.push(obj);
this.imgDom.remove();
this.imgDom = null;
this.wait_list.splice(0, 1);
this.$el.style.height = Math.max(...this.poss) + this.gap_y + "px";
if (this.wait_list.length <= 0) {
this.loading = false;
this.$emit("loadend");
} else {
this.loadImg();
}
});
},
resize() {
nextTick(() => {
var t_width = this.$el.offsetWidth;
var width = this.itemWidth;
var num_x = parseInt(t_width / (width + 20));
if (num_x < 1) num_x = 1;
var remain = t_width - width * num_x;
var gap_x = remain / (num_x + 1);
this.gap_x = gap_x;
this.gap_y = gap_x > 30 ? 30 : gap_x < 30 ? 20 : gap_x;
this.num_x = num_x;
var poss = [];
for (var i = 0; i < num_x; i++) poss.push(0);
this.poss = poss;
this.reset();
});
},
reset() {
for (let i = 0; i < this.list.length; i++) {
let width = this.list[i].style.width;
let height = this.list[i].style.height;
var idx = 0;
var pos_num = this.poss[idx];
for (var j = 1; j < this.poss.length; j++) {
if (pos_num > this.poss[j]) {
idx = j;
pos_num = this.poss[j];
}
}
let top = this.poss[idx] + this.gap_y;
let left = (idx + 1) * this.gap_x + idx * width;
this.poss[idx] = top + height;
this.list[i].style = { width, height, top, left };
}
this.$el.style.height = Math.max(...this.poss) + this.gap_y + "px";
},
setItemDetail(data) {
this.$emit("getImgScale", data);
},
portfolioLike(data) {
this.$emit("setPortfolioLike", data);
},
},
});
props:{
isScroll:{
type:Boolean,
default:true,
},
isText:{
type:Boolean,
default:true,
},
itemWidth:{
type:Number,
default:300,
}
},
setup(){
let list = ref([])
let wait_list = ref([])
let width = ref(300)
let num_x = ref(1)
let gap_x = ref(0)
let gap_y = ref(0)
let poss = ref([])
let loading = ref(false)
let computedHeight = 0
let imgDom = ref()
return{
list,
wait_list,
width,
num_x,
gap_x,
gap_y,
poss,
loading,
computedHeight,
imgDom,
}
},
directives:{
fadeIn:{
mounted (el,binding) {
let dom
if(binding.value){
dom = document.querySelector('.works_page .page_content')
}else{
dom = document.querySelector('.homeRecommend_content_body')
}
gsap.registerPlugin(ScrollTrigger);
let tl1 = gsap.timeline();
tl1.from(el,1, {y:'30px',opacity:0},)
ScrollTrigger.create({
trigger: el, // 触发器元素
start: "top 90%", // 滚动触发器的起始滚动位置
end: '100% 80%', // 滚动触发器的结束滚动位置
// markers: true, // 开启标注功能
scrub: true,
animation:tl1,
scroller:dom,//设置指定元素为滚动依据
scrub:2,
// onUpdate:(v)=>{
// if(v.progress < 0.1){
// v.trigger?.classList.remove('active')
// }else{
// v.trigger?.classList.add('active')
// // v.trigger?.classList.add('active')
// }
// }
});
}
},
},
mounted () {
this.resize()
window.addEventListener("resize", this.resize);
let domFalls = document.querySelector('.Falls')
let domCss = getComputedStyle(domFalls);
const paddingBottom = domCss.getPropertyValue('--paddingBottom').split('px')[0]*1;
const textMarginTop = domCss.getPropertyValue('--textMarginTop').split('px')[0]*1;
const textHeight = domCss.getPropertyValue('--textHeight').split('px')[0]*1;
const contentHeight = domCss.getPropertyValue('--contentHeight').split('px')[0]*1;
if(this.$props.isText){
this.computedHeight = paddingBottom + textMarginTop + textHeight + contentHeight;
}
},
beforeDestroy () {
this.wait_list = []
window.removeEventListener("resize", this.resize);
},
// 挂载方法
methods: {
clearData(){
this.wait_list = []
this.width = this.itemWidth
this.num_x = 1
this.gap_x = 0
this.gap_y = 0
this.poss = []
this.loading = false
this.list = []
this.resize()
if(this.imgDom){
this.imgDom.remove();
this.imgDom = null
}
},
push(arr) {
this.wait_list = this.wait_list.concat(arr);
if (!this.loading) {
this.loading = true;
this.loadImg();
}
},
deleteItem(id){
for (let index = 0; index < this.list.length; index++) {
if(this.list[index].id == id){
this.list.splice(index,1)
this.resize()
break;
}
}
},
loadImg() {
if (this.wait_list.length <= 0) {
this.loading = false;
this.$emit("loadend");
return;
}
let url = this.wait_list[0].canvasUrl || this.wait_list[0].url;
let data = this.wait_list[0]
this.imgDom = document.createElement("img");
this.imgDom.src = url;
this.imgDom.style.width = this.itemWidth + "px";
this.imgDom.style.maxHeight = this.itemWidth+330 + "px";
this.imgDom.style.position = "absolute";
this.imgDom.style.top = "-99999px";
document.body.appendChild(this.imgDom);
this.imgDom.addEventListener("load", () => {
if(!this.imgDom) return
var idx = 0;
var pos_num = this.poss[idx];
for (var i = 1; i < this.poss.length; i++) {
if (pos_num > this.poss[i]) {
idx = i;
pos_num = this.poss[i];
}
}
// this.computedHeight = 0
let width = this.imgDom.offsetWidth;
let height = this.imgDom.offsetHeight+this.computedHeight;
let top = this.poss[idx] + this.gap_y;
let left = (idx + 1) * this.gap_x + idx * width;
let imgHeight = height - this.computedHeight
this.poss[idx] = top + height;
let obj = {
canvasUrl:url,
style: { width, height, top, left, imgHeight },
...data
};
this.list.push(obj);
this.imgDom.remove();
this.imgDom = null
this.wait_list.splice(0, 1);
this.$el.style.height =
Math.max(...this.poss) + this.gap_y + "px";
if (this.wait_list.length <= 0) {
this.loading = false;
this.$emit("loadend");
} else {
this.loadImg();
}
});
},
resize() {
nextTick(() => {
var t_width = this.$el.offsetWidth;
var width = this.itemWidth;
var num_x = parseInt(t_width / (width + 20));
if (num_x < 1) num_x = 1;
var remain = t_width - width * num_x;
var gap_x = remain / (num_x + 1);
this.gap_x = gap_x;
this.gap_y = gap_x > 30 ? 30 : gap_x < 30 ? 20 : gap_x;
this.num_x = num_x;
var poss = [];
for (var i = 0; i < num_x; i++) poss.push(0);
this.poss = poss;
this.reset();
})
},
reset() {
for (let i = 0; i < this.list.length; i++) {
let width = this.list[i].style.width;
let height = this.list[i].style.height;
var idx = 0;
var pos_num = this.poss[idx];
for (var j = 1; j < this.poss.length; j++) {
if (pos_num > this.poss[j]) {
idx = j;
pos_num = this.poss[j];
}
}
let top = this.poss[idx] + this.gap_y;
let left = (idx + 1) * this.gap_x + idx * width;
this.poss[idx] = top + height;
this.list[i].style = { width, height, top, left };
}
this.$el.style.height = Math.max(...this.poss) + this.gap_y + "px";
},
setItemDetail(data){
this.$emit('getImgScale',data)
},
portfolioLike(data){
this.$emit('setPortfolioLike',data)
}
},
})
</script>
<style lang="less" scoped>
.Falls {
width: 100%;
height: auto;
position: relative;
--paddingBottom: 10px;
--textMarginTop: 10px;
--textHeight: 25px;
--contentHeight: 35px;
.falls_item {
position: absolute;
transition: all 0.15s;
display: flex;
flex-direction: column;
background: #fff;
border-radius: 2rem;
overflow: hidden;
padding-bottom: var(--paddingBottom);
&.falls_item:hover {
.falls_item_img {
img {
transform: scale(1.1);
}
}
}
.falls_item_img {
cursor: pointer;
width: 100%;
overflow: hidden;
img {
width: 100%;
object-fit: cover;
height: 100%;
transition: all 0.3s;
}
.falls_item_user_Original {
font-weight: 600;
font-size: 12px;
color: #39215b;
background: #c9a2ff;
padding: 0 5px;
border-radius: 4px;
margin-right: 2px;
position: absolute;
top: 10px;
right: 10px;
left: auto;
}
}
.falls_item_bottom {
padding: 0 10px;
.falls_item_text {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-weight: 600;
font-size: 18px;
margin-top: var(--textMarginTop);
height: var(--textHeight);
}
.falls_item_content {
display: flex;
justify-content: space-between;
align-items: center;
color: #525252;
height: var(--contentHeight);
.falls_item_user {
width: 50%;
display: flex;
align-items: center;
flex: 1;
overflow: hidden;
img {
width: 25px;
height: 25px;
border-radius: 50%;
margin-right: 10px;
}
.falls_item_user_detail {
line-height: 1;
width: 60%;
width: 100%;
color: #000;
display: flex;
flex-direction: column;
align-items: flex-start;
<style lang='less' scoped>
.Falls {
width: 100%;
height: auto;
position: relative;
--paddingBottom:10px;
--textMarginTop:10px;
--textHeight:25px;
--contentHeight:35px;
.falls_item{
position: absolute;
transition: all 0.15s;
display: flex;
flex-direction: column;
background: #fff;
border-radius: 2rem;
overflow: hidden;
padding-bottom: var(--paddingBottom);
&.falls_item:hover{
.falls_item_img{
img{
transform: scale(1.1);
}
}
}
.falls_item_img{
cursor: pointer;
width: 100%;
overflow: hidden;
img{
width: 100%;
object-fit: cover;
height: 100%;
transition: all .3s;
}
.falls_item_user_Original{
font-weight: 600;
font-size: 12px;
color: #39215b;
background: #c9a2ff;
padding: 0 5px;
border-radius: 4px;
margin-right: 2px;
position: absolute;
top: 10px;
right: 10px;
left: auto;
}
}
.falls_item_bottom{
padding: 0 10px;
.falls_item_text{
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-weight: 600;
font-size: 18px;
margin-top: var(--textMarginTop);
height: var(--textHeight);
}
.falls_item_content{
display: flex;
justify-content: space-between;
align-items: center;
color: #525252;
height: var(--contentHeight);
.falls_item_user{
width: 50%;
display: flex;
align-items: center;
flex: 1;
overflow: hidden;
img{
width: 25px;
height: 25px;
border-radius: 50%;
margin-right: 10px;
}
.falls_item_user_detail{
line-height: 1;
width: 60%;
width: 100%;
color: #000;
display: flex;
flex-direction: column;
align-items: flex-start;
>div{
width: 100%;
font-size: 16px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
span{
font-size: 12px;
color: #525252;
}
}
}
.falls_item_detail{
display: flex;
// width: 40%;
// width: 20%;
// width: 7rem;
// width: 70px;
width: auto;
justify-content: space-between;
>label:nth-child(1){
margin-right: 2rem;
}
>label{
// cursor: pointer;
}
>label,>div{
display: flex;
align-items: center;
i{
// font-size: 1.8rem;
font-size: 12px;
}
svg,i{
color: #9e9ea7;
display: flex;
// width: 10px;
// height: 10px;
margin-right: 5px;
}
span{
margin-left: 3px;
font-size: 12px;
}
}
}
}
}
> div {
width: 100%;
font-size: 16px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
span {
font-size: 12px;
color: #525252;
}
}
}
.falls_item_detail {
display: flex;
// width: 40%;
// width: 20%;
// width: 7rem;
// width: 70px;
width: auto;
justify-content: space-between;
> label:nth-child(1) {
margin-right: 2rem;
}
> label {
// cursor: pointer;
}
> label,
> div {
display: flex;
align-items: center;
i {
// font-size: 1.8rem;
font-size: 12px;
}
svg,
i {
color: #9e9ea7;
display: flex;
// width: 10px;
// height: 10px;
margin-right: 5px;
}
span {
margin-left: 3px;
font-size: 12px;
}
}
}
}
}
}
}
</style>
}
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -928,8 +928,8 @@ export default defineComponent({
right: 1rem;
top: 1rem;
// opacity: 0;
width: 3.5rem;
height: 3.5rem;
width: 3rem;
height: 3rem;
transition: all 0.3s ease-in-out;
}
&.modal_imgItem:nth-child(even) {
@@ -942,10 +942,10 @@ export default defineComponent({
}
.pin_block{
position: absolute;
left: 1rem;
left: .5rem;
top: 1rem;
width: 8rem;
height: 3.5rem;
width: 7rem;
height: 3rem;
border-radius: 3rem;
background: rgba(0,0,0,.7);
color: #fff;
@@ -960,8 +960,8 @@ export default defineComponent({
padding-left: .2rem;
}
i{
width: 3rem;
height: 3rem;
width: 2.5rem;
height: 2.5rem;
border-radius: 50%;
display: flex;
align-items: center;
@@ -974,7 +974,7 @@ export default defineComponent({
}
}
span{
font-size: 1.8rem;
font-size: 1.4rem;
font-weight: 600;
}
}

View File

@@ -882,8 +882,8 @@ export default defineComponent({
right: 1rem;
top: 1rem;
// opacity: 0;
width: 3.5rem;
height: 3.5rem;
width: 3rem;
height: 3rem;
transition: all 0.3s ease-in-out;
}
&.modal_imgItem:nth-child(even) {
@@ -900,10 +900,10 @@ export default defineComponent({
}
.pin_block{
position: absolute;
left: 1rem;
left: .5rem;
top: 1rem;
width: 8rem;
height: 3.5rem;
width: 7rem;
height: 3rem;
border-radius: 3rem;
background: rgba(0,0,0,.7);
color: #fff;
@@ -918,8 +918,8 @@ export default defineComponent({
padding-left: .2rem;
}
i{
width: 3rem;
height: 3rem;
width: 2.5rem;
height: 2.5rem;
border-radius: 50%;
display: flex;
align-items: center;
@@ -932,7 +932,7 @@ export default defineComponent({
}
}
span{
font-size: 1.8rem;
font-size: 1.4rem;
font-weight: 600;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -65,6 +65,7 @@ export default defineComponent({
}else{
data.openType = ''
data.dataLoad = false
return
}
// if((query.history || query.id) != (oldQuery.history || oldQuery.id)){
// }

View File

@@ -1,530 +1,459 @@
<template>
<div class="newProject">
<div class="contentBox">
<div class="content">
<div class="title">How can I help you today?</div>
<div class="selectFlow">
<div class="select">
<div
class="item"
@click="setFlow(item)"
:class="{ active: item.title == selectFlow.title }"
v-for="item in flowList"
>
{{ item.title }}
</div>
</div>
<div class="describe">
<p v-for="item in selectFlow.describe">{{ item }}</p>
</div>
</div>
<div class="chatOrSetting">
<div class="select">
<div
class="item"
@click="setChatOrSetting('chat')"
:class="{ active: chatOrSetting == 'chat' }"
>
Chat
</div>
<div
class="item"
@click="setChatOrSetting('setting')"
:class="{ active: chatOrSetting == 'setting' }"
>
Setting
</div>
</div>
</div>
<div class="chatBox" v-show="chatOrSetting == 'chat'">
<textarea
ref="textarea"
@input="inputText($event)"
@keydown.enter.prevent="sendChat"
placeholder="Write your message"
></textarea>
<div class="btn">
<div class="uploadBox">
<div class="filList">
<div class="item" v-for="(item, index) in filList">
<div>{{ item.name }}</div>
<span
class="icon iconfont icon-shanchu"
@click="deleteFile(item, index)"
></span>
</div>
</div>
<i class="fi fi-rs-paperclip-vertical">
<input type="file" @change="handleFileUpload($event)" />
</i>
<div
class="enableThinking"
:class="{ active: enableThinking }"
@click="() => (enableThinking = !enableThinking)"
>
Deep Thinking
</div>
</div>
<div class="sendBox">
<div class="maxNum">{{ chatContent.length }}/10000</div>
<div class="send" @click="sendChat">
<i class="fi fi-ss-paper-plane-top"></i>
</div>
</div>
</div>
</div>
<div v-show="chatOrSetting != 'chat'" class="workspaceBox">
<workspace
@setProject="setProject"
:httpWorkflowType="selectFlow.value"
></workspace>
</div>
<div class="hint" v-show="chatOrSetting == 'chat'">
<div
class="item"
v-for="item in hintList"
@click="addChatContent(item)"
>
{{ item }}
</div>
</div>
</div>
</div>
<div class="mark_loading" v-show="loadingShow">
<a-spin size="large" />
</div>
</div>
<div class="newProject">
<div class="contentBox">
<div class="content">
<div class="title">How can I help you today?</div>
<div class="selectFlow">
<div class="select">
<div class="item" @click="setFlow(item)" :class="{active:item.title == selectFlow.title}" v-for="item in flowList">{{ item.title }}</div>
</div>
<div class="describe">
<p v-for="item in selectFlow.describe">{{ item }}</p>
</div>
</div>
<div class="chatOrSetting">
<div class="select">
<div class="item" @click="setChatOrSetting('chat')" :class="{active:chatOrSetting == 'chat'}">Chat</div>
<div class="item" @click="setChatOrSetting('setting')" :class="{active:chatOrSetting == 'setting'}">Setting</div>
</div>
</div>
<div class="chatBox" v-show="chatOrSetting == 'chat'">
<textarea ref="textarea" @input="inputText($event)" @keydown.enter.prevent="sendChat" placeholder="Write your message"></textarea>
<div class="btn">
<div class="uploadBox">
<div class="filList">
<div class="item" v-for="item,index in filList">
<div>{{item.name}}</div>
<span class="icon iconfont icon-shanchu" @click="deleteFile(item,index)"></span>
</div>
</div>
<i class="fi fi-rs-paperclip-vertical">
<input type="file" @change="handleFileUpload($event)">
</i>
<div class="enableThinking" :class="{active:enableThinking}" @click="()=>enableThinking = !enableThinking">Deep Thinking</div>
</div>
<div class="sendBox">
<div class="maxNum">{{ chatContent.length }}/10000</div>
<div class="send" @click="sendChat">
<i class="fi fi-ss-paper-plane-top"></i>
</div>
</div>
</div>
</div>
<div v-show="chatOrSetting != 'chat'" class="workspaceBox">
<workspace @setProject="setProject" :httpWorkflowType="selectFlow.value"></workspace>
</div>
<div class="hint" v-show="chatOrSetting == 'chat'">
<div class="item" v-for="item in hintList" @click="addChatContent(item)">{{ item }}</div>
</div>
</div>
</div>
<div class="mark_loading" v-show="loadingShow">
<a-spin size="large" />
</div>
</div>
</template>
<script lang="ts">
import {
defineComponent,
computed,
ref,
provide,
nextTick,
createVNode,
toRefs,
reactive,
onMounted,
} from "vue";
import { ExclamationCircleOutlined } from "@ant-design/icons-vue";
import { defineComponent,computed,ref,provide,nextTick,createVNode,toRefs, reactive, onMounted} from 'vue'
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { Https } from "@/tool/https";
import { useStore } from "vuex";
import { Modal, message, Upload, CascaderProps } from "ant-design-vue";
import { useI18n } from "vue-i18n";
import { getCookie, clonAllCookie } from "@/tool/cookie";
import router from "@/router";
import workspace from "./workspace.vue";
import { Modal,message,Upload,CascaderProps } from 'ant-design-vue';
import { useI18n } from 'vue-i18n'
import {getCookie,clonAllCookie} from '@/tool/cookie'
import router from '@/router';
import workspace from './workspace.vue'
export default defineComponent({
components: {
workspace,
},
props: {},
emits: ["newProject"],
setup(props, { emit }) {
const store = useStore();
const data = reactive({
flowList: [
{
title: "Series Design",
value: "SERIES_DESIGN",
describe: [
"Series Design focuses on the coordinated design of multi-category clothing, ideal for creating a unified fashion collection. You can use the Moodboard, Printboard, Colorboard, Sketchboard, and Mannequin sections in the Design Assests panel to organize your inspiration and design complementary clothing combinations. Finally, refine your designs in the Draft and Collection panels using tools like To Product Image, Relight, and Transfer Pose, then export to the Canvas to showcase your complete series design.",
],
},
{
title: "Single Design",
value: "SINGLE_DESIGN",
describe: [
"Single Design centers on the independent design of a single clothing category, such as a T-shirt, dress, or jacket, without considering coordination with other items. Use the Moodboard, Printboard, Colorboard, and Sketchboard in the Design Assests panel to gather inspiration and focus on crafting a unique piece. Once completed, optimize your design in the Draft and Collection panels with tools like To Product Image, Relight, and Transfer Pose, then export to the Canvas to display your individual creation.",
],
},
],
selectFlow: {
title: "Series Design",
value: "SERIES_DESIGN",
describe: [
"Series Design focuses on the coordinated design of multi-category clothing, ideal for creating a unified fashion collection. You can use the Moodboard, Printboard, Colorboard, Sketchboard, and Mannequin sections in the Design Assests panel to organize your inspiration and design complementary clothing combinations. Finally, refine your designs in the Draft and Collection panels using tools like To Product Image, Relight, and Transfer Pose, then export to the Canvas to showcase your complete series design.",
],
},
chatContent: "",
hintList: [
"设计一套田园风衣服",
"设计一套夏日风衣服",
"设计一套未来风格的衣服",
],
enableThinking: false, //深度思考
uploadFile: null as any,
loadingShow: false,
text: "",
filList: [] as any,
textarea: null as any,
chatOrSetting: "chat",
});
const dataDom = reactive({});
const setFlow = (item: any) => {
data.selectFlow = item;
};
const inputText = (e: any) => {
if (e.target.value.length <= 1000) {
data.chatContent = e.target.value;
} else {
e.target.value = data.chatContent;
}
e.target.style.height = `${e.target.scrollHeight}px`;
};
const addChatContent = (item: any) => {
if (data.textarea.value?.length + item.length > 10000) return;
data.chatContent += item;
data.textarea.value += item;
};
const sendChat = () => {
if (!data.chatContent) return;
data.loadingShow = true;
let fileList = JSON.parse(JSON.stringify(data.filList));
let fileUrl =
fileList.filter((item: any) => item.type == "file").length > 0
? fileList.filter((item: any) => item.type == "file")[0].minioPath
: "";
let imageUrlList =
fileList.filter((item: any) => item.type == "image").length > 0
? fileList
.filter((item: any) => item.type == "image")
.map((item: any) => item.minioPath)
.join(",")
: "";
Https.axiosGet(Https.httpUrls.chatCreateProject, {
params: {
prompt: data.chatContent,
process: data.selectFlow.value,
fileUrl: fileUrl,
imageUrlList,
},
})
.then((rv) => {
if (rv) {
data.loadingShow = false;
let value = {
id: rv,
fileList: fileList,
chatContent: data.chatContent,
enableThinking: data.enableThinking,
};
emit("newProject", value);
}
})
.catch(() => {
data.loadingShow = false;
});
// let projectId = ''
// const eventSource = new EventSource(`${import.meta.env.VITE_APP_BASE_URL}${Https.httpUrls.llmStream}?token=${getCookie('token')}&prompt=${data.chatContent}&projectId=&fileUrl=${fileUrl}&imageUrlList=${imageUrlList}&enableThinking=${data.enableThinking}&process=${data.selectFlow.value}`);
// eventSource.onmessage = function(event) {
// let eventData = JSON.parse(event.data)
// if(eventData.status == "[PROJECT_CREATE_SIGNAL]"){
// projectId = JSON.parse(eventData.tools_data).projectId
// }
// };
// eventSource.onerror = function(error) {
// if (eventSource.readyState === EventSource.CLOSED) {
// // data.chatList[data.chatList.length-1].content.message='服务器繁忙,请稍后再试。'
// } else {
// if(projectId){
// emit('newProject',projectId)
// }
// eventSource.close()
// }
// data.loadingShow = false
// };
};
const handleFileUpload = (event: any) => {
if (event.target.files[0].size > 5 * 1024 * 1024) {
// 5MB
message.info("The file size cannot exceed 5MB.");
return;
}
let type = event.target.files[0].type.startsWith("image/");
if (type) {
if (
data.filList.filter((item: any) => item.type == "image").length >= 5
) {
message.info("You can only upload five pictures.");
return;
}
} else {
if (
data.filList.filter((item: any) => item.type == "file").length >= 1
) {
message.info("You can only upload one file.");
return;
}
}
data.loadingShow = true;
const formData = new FormData();
formData.append("file", event.target.files[0]);
let config: any = {
headers: { "Content-Type": "multipart/form-data", Accept: "*/*" },
params: formData,
};
Https.axiosPost(Https.httpUrls.llmUploadFile, formData, config)
.then((rv: any) => {
let obj = {
name: event.target.files[0].name,
type: type ? "image" : "file",
minioPath: rv[0],
url: rv[1],
};
data.filList.push(obj);
data.loadingShow = false;
})
.catch((rv) => {
data.loadingShow = false;
});
};
const deleteFile = (item: any, index: number) => {
data.filList.splice(index, 1);
};
const setChatOrSetting = (str: any) => {
data.chatOrSetting = str;
};
const setProject = (item: any) => {
router.push(`home?history=${item.id}`);
};
onMounted(() => {
store.commit("createProbject");
});
return {
...toRefs(dataDom),
...toRefs(data),
setFlow,
inputText,
addChatContent,
sendChat,
handleFileUpload,
deleteFile,
setChatOrSetting,
setProject,
};
},
provide() {
return {};
},
});
components:{
workspace,
},
props:{
},
emits:['newProject'],
setup(props,{emit}) {
const store = useStore();
const data = reactive({
flowList:[
{
title:'Series Design',
value:'SERIES_DESIGN',
describe:[
'Series Design focuses on the coordinated design of multi-category clothing, ideal for creating a unified fashion collection. You can use the Moodboard, Printboard, Colorboard, Sketchboard, and Mannequin sections in the Design Assests panel to organize your inspiration and design complementary clothing combinations. Finally, refine your designs in the Draft and Collection panels using tools like To Product Image, Relight, and Transfer Pose, then export to the Canvas to showcase your complete series design.',
]
},
{
title:'Single Design',
value:'SINGLE_DESIGN',
describe:[
'Single Design centers on the independent design of a single clothing category, such as a T-shirt, dress, or jacket, without considering coordination with other items. Use the Moodboard, Printboard, Colorboard, and Sketchboard in the Design Assests panel to gather inspiration and focus on crafting a unique piece. Once completed, optimize your design in the Draft and Collection panels with tools like To Product Image, Relight, and Transfer Pose, then export to the Canvas to display your individual creation.',
]
},
],
selectFlow:{
title:'Series Design',
value:'SERIES_DESIGN',
describe:[
'Series Design focuses on the coordinated design of multi-category clothing, ideal for creating a unified fashion collection. You can use the Moodboard, Printboard, Colorboard, Sketchboard, and Mannequin sections in the Design Assests panel to organize your inspiration and design complementary clothing combinations. Finally, refine your designs in the Draft and Collection panels using tools like To Product Image, Relight, and Transfer Pose, then export to the Canvas to showcase your complete series design.',
]
},
chatContent:'',
hintList:[
'设计一套田园风衣服',
'设计一套夏日风衣服',
'设计一套未来风格的衣服',
],
enableThinking:false,//深度思考
uploadFile:null as any,
loadingShow:false,
text:'',
filList:[] as any,
textarea:null as any,
chatOrSetting:'chat',
})
const dataDom = reactive({
})
const setFlow = (item:any)=>{
data.selectFlow = item
}
const inputText = (e:any)=>{
if(e.target.value.length <= 1000){
data.chatContent = e.target.value
}else{
e.target.value = data.chatContent
}
e.target.style.height = `${e.target.scrollHeight}px`;
}
const addChatContent = (item:any)=>{
if((data.textarea.value?.length + item.length) > 10000)return
data.chatContent += item
data.textarea.value += item
}
const sendChat = ()=>{
if(!data.chatContent)return
data.loadingShow = true
let fileList = JSON.parse(JSON.stringify(data.filList))
let fileUrl = (fileList.filter((item:any)=>item.type == 'file').length > 0) ? fileList.filter((item:any)=>item.type == 'file')[0].minioPath : ''
let imageUrlList = (fileList.filter((item:any)=>item.type == 'image').length > 0)? fileList.filter((item:any)=>item.type == 'image').map((item:any)=>item.minioPath).join(',') : ''
Https.axiosGet(Https.httpUrls.chatCreateProject, {params:{prompt:data.chatContent,process:data.selectFlow.value,fileUrl:fileUrl,imageUrlList}}).then((rv)=>{
if(rv){
data.loadingShow = false
let value = {
id:rv,
fileList:fileList,
chatContent:data.chatContent,
enableThinking:data.enableThinking,
}
emit('newProject',value)
}
}).catch(()=>{
data.loadingShow = false
})
// let projectId = ''
// const eventSource = new EventSource(`${process.env.VUE_APP_BASE_URL}${Https.httpUrls.llmStream}?token=${getCookie('token')}&prompt=${data.chatContent}&projectId=&fileUrl=${fileUrl}&imageUrlList=${imageUrlList}&enableThinking=${data.enableThinking}&process=${data.selectFlow.value}`);
// eventSource.onmessage = function(event) {
// let eventData = JSON.parse(event.data)
// if(eventData.status == "[PROJECT_CREATE_SIGNAL]"){
// projectId = JSON.parse(eventData.tools_data).projectId
// }
// };
// eventSource.onerror = function(error) {
// if (eventSource.readyState === EventSource.CLOSED) {
// // data.chatList[data.chatList.length-1].content.message='服务器繁忙,请稍后再试。'
// } else {
// if(projectId){
// emit('newProject',projectId)
// }
// eventSource.close()
// }
// data.loadingShow = false
// };
}
const handleFileUpload = (event:any)=>{
if (event.target.files[0].size > 5 * 1024 * 1024) { // 5MB
message.info('The file size cannot exceed 5MB.');
return
}
let type = event.target.files[0].type.startsWith('image/')
if(type){
if(data.filList.filter((item:any)=>item.type == 'image').length >= 5){
message.info('You can only upload five pictures.');
return
}
}else{
if(data.filList.filter((item:any)=>item.type == 'file').length >= 1){
message.info('You can only upload one file.');
return
}
}
data.loadingShow = true
const formData = new FormData();
formData.append('file', event.target.files[0]);
let config:any = {
headers:{'Content-Type':'multipart/form-data','Accept':'*/*' },
params:formData,
}
Https.axiosPost(Https.httpUrls.llmUploadFile,formData,config)
.then((rv: any) => {
let obj = {
name:event.target.files[0].name,
type:type?'image':'file',
minioPath:rv[0],
url:rv[1],
}
data.filList.push(obj)
data.loadingShow = false
}
).catch(rv=>{
data.loadingShow = false
})
}
const deleteFile = (item:any,index:number)=>{
data.filList.splice(index,1)
}
const setChatOrSetting = (str:any)=>{
data.chatOrSetting = str
}
const setProject = (item:any)=>{
router.push(`home?history=${item.id}`)
}
onMounted(()=>{
store.commit('createProbject')
})
return{
...toRefs(dataDom),
...toRefs(data),
setFlow,
inputText,
addChatContent,
sendChat,
handleFileUpload,
deleteFile,
setChatOrSetting,
setProject,
}
},
provide() {
return {
}
},
})
</script>
<style lang="less" scoped>
.newProject {
width: 100%;
height: 100%;
position: relative;
> .contentBox {
width: 100%;
height: calc(100% - 3.9rem);
// height: calc(100% - 7.8rem);
display: flex;
align-items: center;
justify-content: center;
> .content {
// background: red;
width: 88rem;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
> .title {
font-size: 2rem;
font-weight: 600;
text-align: center;
}
> .workspaceBox {
flex: 1;
border-radius: 2.4rem;
padding: 1.2rem;
border: 1px solid #0000001a;
:deep(.workspace) {
padding: 0;
height: auto;
}
}
> .selectFlow {
margin-top: 4.8rem;
width: 100%;
border-radius: 2.4rem;
border: 1px solid #0000001a;
padding: 1.2rem;
> .select {
border: 1px solid #0000001a;
border-radius: 2.4rem;
display: flex;
padding: 0.2rem;
border-radius: 2rem;
> div {
white-space: nowrap;
justify-content: space-between;
border-radius: 2.2rem;
font-size: 1.6rem;
padding: 0.6rem 0.8rem;
min-width: 25%;
text-align: center;
font-weight: 600;
color: #71717a;
cursor: pointer;
&.active {
background: #efeff1;
color: #3f3f46;
}
}
}
> .describe {
margin-top: 1.6rem;
margin-left: 0.8rem;
> p {
margin: 0;
color: #71717a;
font-weight: 400;
font-size: 1.2rem;
}
}
}
> .chatOrSetting {
margin-top: 2.4rem;
width: min-content;
margin-left: auto;
> .select {
border: 1px solid #0000001a;
border-radius: 2.4rem;
display: flex;
padding: 0.2rem;
border-radius: 2rem;
> div {
white-space: nowrap;
justify-content: space-between;
border-radius: 2.2rem;
font-size: 1.6rem;
padding: 0.6rem 0.8rem;
min-width: 10rem;
text-align: center;
font-weight: 600;
color: #71717a;
cursor: pointer;
&.active {
background: #efeff1;
color: #3f3f46;
}
}
}
}
> .chatBox {
margin-top: 0.4rem;
border-radius: 2.4rem;
position: relative;
background: #f5f5f5;
> textarea {
padding: 1.6rem 2rem 0;
background: #f5f5f5;
width: 100%;
min-height: 7.2rem;
border-radius: 2.4rem;
font-weight: 400;
line-height: 2rem;
font-size: 1.4rem;
resize: none;
border: none;
overflow-y: hidden;
}
> .btn {
padding: 0 1.2rem 1.2rem;
display: flex;
justify-content: space-between;
> .uploadBox {
display: flex;
align-items: center;
> .filList {
display: flex;
> .item {
height: 3rem;
padding: 0.5rem 1rem;
background: #efeff1;
border-radius: 0.5rem;
margin-right: 1rem;
font-size: 1.4rem;
line-height: 2rem;
display: flex;
> div {
white-space: nowrap;
overflow: hidden;
max-width: 10rem;
text-overflow: ellipsis;
}
> span {
cursor: pointer;
}
}
}
> .enableThinking {
width: 10rem;
padding: 0.2rem 0.4rem;
margin-left: 1rem;
text-align: center;
font-size: 1.4rem;
border: 1px solid #000;
border-radius: 0.4rem;
cursor: pointer;
&.active {
background: #000;
color: #fff;
}
}
}
i {
font-size: 2rem;
display: flex;
cursor: pointer;
position: relative;
> input {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
opacity: 0;
cursor: pointer;
&::-webkit-file-upload-button {
cursor: pointer;
}
}
}
> .sendBox {
display: flex;
align-items: center;
.newProject{
width: 100%;
height: 100%;
position: relative;
> .contentBox{
width: 100%;
height: calc(100% - 3.9rem);
// height: calc(100% - 7.8rem);
display: flex;
align-items: center;
justify-content: center;
> .content{
// background: red;
width: 88rem;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
> .title{
font-size: 2rem;
font-weight: 600;
text-align: center;
}
> .workspaceBox{
flex: 1;
border-radius: 2.4rem;
padding: 1.2rem;
border: 1px solid #0000001a;
:deep(.workspace){
padding: 0;
height: auto;
}
}
> .selectFlow{
margin-top: 4.8rem;
width: 100%;
border-radius: 2.4rem;
border: 1px solid #0000001a;
padding: 1.2rem;
> .select{
border: 1px solid #0000001a;
border-radius: 2.4rem;
display: flex;
padding: .2rem;
border-radius: 2rem;
> div{
white-space: nowrap;
justify-content: space-between;
border-radius: 2.2rem;
font-size: 1.6rem;
padding: .6rem .8rem;
min-width: 25%;
text-align: center;
font-weight: 600;
color: #71717a;
cursor: pointer;
&.active{
background: #efeff1;
color: #3f3f46;
}
}
}
> .describe{
margin-top: 1.6rem;
margin-left: .8rem;
> p{
margin: 0;
color: #71717a;
font-weight: 400;
font-size: 1.2rem;
}
}
}
> .chatOrSetting{
margin-top: 2.4rem;
width: min-content;
margin-left: auto;
> .select{
border: 1px solid #0000001a;
border-radius: 2.4rem;
display: flex;
padding: .2rem;
border-radius: 2rem;
> div{
white-space: nowrap;
justify-content: space-between;
border-radius: 2.2rem;
font-size: 1.6rem;
padding: .6rem .8rem;
min-width: 10rem;
text-align: center;
font-weight: 600;
color: #71717a;
cursor: pointer;
&.active{
background: #efeff1;
color: #3f3f46;
}
}
}
}
> .chatBox{
margin-top: .4rem;
border-radius: 2.4rem;
position: relative;
background: #f5f5f5;
> textarea{
padding: 1.6rem 2rem 0;
background: #f5f5f5;
width: 100%;
min-height: 7.2rem;
border-radius: 2.4rem;
font-weight: 400;
line-height: 2rem;
font-size: 1.4rem;
resize: none;
border: none;
overflow-y: hidden;
}
> .btn{
padding: 0 1.2rem 1.2rem;
display: flex;
justify-content: space-between;
> .uploadBox{
display: flex;
align-items: center;
> .filList{
display: flex;
> .item{
height: 3rem;
padding: .5rem 1rem;
background: #efeff1;
border-radius: .5rem;
margin-right: 1rem;
font-size: 1.4rem;
line-height: 2rem;
display: flex;
> div{
white-space: nowrap;
overflow: hidden;
max-width: 10rem;
text-overflow: ellipsis;
}
> span{
cursor: pointer;
}
}
}
> .enableThinking{
width: 10rem;
padding: .2rem .4rem;
margin-left: 1rem;
text-align: center;
font-size: 1.4rem;
border: 1px solid #000;
border-radius: .4rem;
cursor: pointer;
&.active{
background: #000;
color: #fff;
> .maxNum {
font-size: 1.2rem;
margin-right: 0.8rem;
font-weight: 400;
}
}
}
}
> .hint {
display: flex;
margin-top: 2.4rem;
> div {
background: #efeff1;
width: 25rem;
height: 4.8rem;
margin-right: 1.2rem;
border-radius: 1.6rem;
cursor: pointer;
padding: 1.2rem;
&:hover {
background: #f5f5f5;
}
:first-child {
margin-right: 0;
}
}
}
}
}
}
</style>
}
}
}
i{
font-size: 2rem;
display: flex;
cursor: pointer;
position: relative;
> input{
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
opacity: 0;
cursor: pointer;
&::-webkit-file-upload-button {
cursor: pointer;
}
}
}
> .sendBox{
display: flex;
align-items: center;
> .maxNum{
font-size: 1.2rem;
margin-right: .8rem;
font-weight: 400;
}
}
}
}
> .hint{
display: flex;
margin-top: 2.4rem;
> div{
background: #efeff1;
width: 25rem;
height: 4.8rem;
margin-right: 1.2rem;
border-radius: 1.6rem;
cursor: pointer;
padding: 1.2rem;
&:hover{
background: #f5f5f5;
}
:first-child{
margin-right: 0;
}
}
}
}
}
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -1,843 +1,142 @@
<template>
<div class="generalMiniCanvas">
<div class="addDetails_canvasCenter">
<div class="generalMiniCanvas_input generalMiniCanvas_item" :class="{spread:spreadState}">
<div class="generalMiniCanvas_input_item brushwork" v-show="canvasState == 'pencil'">
<span >{{ $t('exportModel.Brushwork') }}:</span>
<a-select ref="select" class="label_select" size="small" v-model:value="brushworkValue"
style="width: 20rem"
@change="brushworkChange"
>
<a-select-option class="label_select_item" v-for="item in brushList" :value="item.value">
<img :src="item.url" alt="">
</a-select-option>
</a-select>
</div>
<div class="generalMiniCanvas_input_item" v-show="(canvasState != 'move' && canvasState != 'liquidation' && canvasState != 'movePosition' && canvasState != 'zoomIn' && canvasState != 'zoomOut' && brushworkValue != 'RibbonBrush' && brushworkValue != 'LongfurBrush')">
<span>{{ $t('exportModel.Size') }}</span>
<input type="range" @input="setPencilWidth" min="1" max="50" v-model="canvasPencilWidth[canvasState]">
</div>
<div class="generalMiniCanvas_input_item" v-show="canvasState == 'liquidation'">
<span>{{ $t('exportModel.Size') }}</span>{{ canvasPencilWidth.routes }}
<input type="range" @change="routesChange('routes')" min="1" max="100" v-model="canvasPencilWidth.routes">
</div>
<div class="generalMiniCanvas_input_item" v-show="canvasState == 'liquidation'">
<span>{{ $t('exportModel.density') }}</span>
<input type="range" @change="routesChange('density')" min="1" max="100" v-model="canvasPencilWidth.density">
</div>
<div class="generalMiniCanvas_input_item" v-show=" canvasState == 'pencil'">
<span>{{ $t('exportModel.Color') }}</span>
<input type="color" @input="setPencilColor" v-model="canvasPencilColor">
</div>
</div>
<div class="exportCanvasBox_center_data">
<div class="generalMiniCanvas_btn generalMiniCanvas_item" :class="{spread:spreadState}">
<!-- <div @click="setOperation('')" class="generalMiniCanvas_btn_item">
<div>新增</div>
</div> -->
<i class="icon iconfont icon-chehui" @click="canvasGeneral.historyState('')"></i>
<i class="icon iconfont icon-fanchehui" @click="canvasGeneral.historyState('reverse')"></i>
<i class="icon iconfont icon-move" @click="setOperation('movePosition')" :class="{active:canvasState == 'movePosition'}"></i>
<!-- <i class="icon iconfont icon-move" @click="setOperation('move')" :class="{active:canvasState == 'move'}"></i> -->
<i class="icon iconfont icon-bianji" @click="setOperation('pencil')" :class="{active:canvasState == 'pencil'}"></i>
<i class="icon iconfont icon-xiangpi_huaban1" @click="setOperation('eraser')" :class="{active:canvasState == 'eraser'}"></i>
<!-- <i class="icon iconfont icon-IC-yehua" @click="setOperation('liquidation')"></i> -->
<i class="icon iconfont icon-IC-yehua" @click="setLiquefaction()"></i>
<!-- <div class="icon iconfont icon-xiala" :class="{btnRotate:spreadState}" @click="()=>spreadState = !spreadState"></div> -->
<i class="fi fi-rr-zoom-in" @click="setOperation('zoomIn')" :class="{active:canvasState == 'zoomIn'}"></i>
<i class="fi fi-rr-zoom-out" @click="setOperation('zoomOut')" :class="{active:canvasState == 'zoomOut'}"></i>
</div>
<div class="exportCanvasBox_center_box">
<div class="exportCanvasBox_center">
</div>
<!-- <div v-show="arrows.show" class="moveDom" :style="arrows.domStyle"></div>
<div v-show="arrows.show" class="jiantouDom" :style="arrows.jiantouStyle"> </div> -->
<div class="editFrontBack_pencilbtn" v-show="loadingShow" :style="pencilbtnStyle"></div>
</div>
</div>
<div class="generalCanvas">
<div class="canvasBox" ref="canvasBox">
<editCanvas v-if="canvasLoad" :config="canvasConfig" :clothingImageUrl="imgUrl" ref="editCanvas"></editCanvas>
</div>
<div class="exportCanvasBox_submit" @click="setSubmit(false)">
<div class="started_btn">
{{ $t('addDetails.submit') }}
</div>
<div class="mark_loading" v-show="isShowMark">
<a-spin size="large" />
</div>
<liquefaction ref="liquefaction" @submitLiquefaction="submitLiquefaction"></liquefaction>
</div>
</template>
<script>
import { defineComponent, ref, reactive, watch, onMounted, onBeforeUnmount, nextTick, toRefs } from "vue";
import creditsDetail from "@/component/Pay/creditsDetail.vue";
import { exportSele,JSRectUpdata,JSchangeType,JScanvasMouseDown,JSSetRemoveImage,JScreateCheck,JSSetTexture } from "@/tool/canvasDrawing";
import {defineComponent, toRefs, provide, h, ref, nextTick, onBeforeUnmount, reactive, onMounted,
} from "vue";
import {message} from 'ant-design-vue'
import { Https } from "@/tool/https";
import { useStore } from "vuex";
import { useI18n } from "vue-i18n";
import canvasGeneral from "@/tool/canvasGeneral";
import { getMousePosition } from "@/tool/mdEvent";
import liquefaction from "@/component/modules/liquefaction.vue";
import canvasGeneral from "@/tool/canvasGeneralCopy";
import editCanvas from "@/component/Canvas/CanvasEditor/index.vue";
export default defineComponent({
components: {
creditsDetail,
liquefaction
editCanvas,
},
emits: ['submitBase64Data'],
props: {
imgUrl: {
type: String,
default: ''
},
props:{
imgUrl:{
type:String,
default:''
}
},
// watch: {
// // imgUrl: function(newVal, oldVal) {
// // console.log(newVal);
// // // 当propertyName数据发生变化时执行相应的操作
// // }
// imgUrl(newVal, oldVal) {
// console.log(`imgUrl changed from ${oldVal} to ${newVal}`);
// },
// },
emits:['submitBase64Data'],
setup(props,{emit}) {
let presentState = ref('paypal');
let showPayOrder = ref(false);
let loadingShow = ref(false);
let { t } = useI18n();
let canvas = reactive({});
let scale = 2;
let ratio = [1,1]
let exportWH = 512
let pencilbtnStyle = ref({
background:'',
width:0+'px',
height:0+'px',
display:'none',
left:0+'px',
top:0+'px',
const { t } = useI18n();
const store = useStore();
const isShowMark = ref(false)
const component = reactive({
})
let canvasBtn = reactive({
canvasState:'move',
canvasPencilWidth:{
pencil:20,
eraser:20,
routes:30,
density:30,
const data = reactive({
canvasLoad:false,
canvasConfig:{
},
canvasPencilColor:'#000000',
spreadState:false,
})
let canvasWH = ref(0);
let arrows = ref({
show:false,
domStyle:{
left:0,
top:0,
width:0,
height:0,
},
jiantouStyle:{
height:'1px',
transform:`translateY(-100%) rotate(${90}deg)`,
}
})
watch(
() => props.imgUrl,
(newValue, oldValue) => {
init()
const dataDom = reactive({
editCanvas:null,
canvasBox:null,
})
const openSetData = ()=>{
data.canvasLoad = true
}
const addImage = (value)=>{
console.log(value)
dataDom.editCanvas.addImageToLayer(value.imgUrl)
}
const addBottomImage = (value)=>{
dataDom.editCanvas.changeFixedImage(value)
}
const getData = async ()=>{
onMounted(()=>{
init()
})
onBeforeUnmount(()=>{
canvasGeneral.canvasClear()
})
let reverseCanvasState = ref([])//存放canvas操作
let normalCanvasState = ref([])//存放canvas操作
let canvasState = ref()//存放canvas操作
let keyDown = []//监听键盘的 keydown 和 keyup 事件
let isMovePostion = false
let init = ()=>{
normalCanvasState.value = []
reverseCanvasState.value = []
showPayOrder.value = true;
ratio = [1,1]
nextTick(()=>{
let canvasBox = document.querySelector(".generalMiniCanvas .exportCanvasBox_center");
document.removeEventListener('mousemove', mouseMove);
document.removeEventListener('touchmove', touchmove);
let img = new Image();
img.onload = async function(){
loadingShow.value = true
let height = canvasBox.offsetHeight;
canvasWH.value = height
// canvasBox.style.width = height+'px'
let wScale = 1
let hScale = 1
if(img.width>img.height){
hScale = img.height/img.width
exportWH = img.width
}else{
wScale = img.width/img.height
exportWH = img.height
}
ratio = [wScale,hScale]
canvas = canvasGeneral.canvasInit(canvasBox,{
width:canvasWH.value * wScale,
height:canvasWH.value * hScale,
})
canvas.selection = false;
// canvas.set({
// backgroundColor: 'lightblue'
// });
scale = img.height/canvas.height
pencilbtnStyle.value.background = canvasBtn.canvasPencilColor
fabric.Object.prototype.cornerSize = 10
fabric.Object.prototype.transparentCorners = false
await fabric.Image.fromURL(props.imgUrl, async function(img) {
// 设置背景图对象的宽度和高度与 canvas 相同
img.scaleToWidth(canvas.width);
img.scaleToHeight(canvas.height);
img.set({
scaleX: canvas.width / img.width,
scaleY: canvas.height / img.height
});
// 将背景图添加到 canvas 的底层
await canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas));
if(!fabric.Object.prototype.controls.deleteControl){
JSSetRemoveImage(deleteObj)
}else{
fabric.Object.prototype.controls.deleteControl.mouseUpHandler = deleteObj
}
setPencilWidth()
canvasGeneral.updateCanvasState()
},{ crossOrigin: "Anonymous" });
// 鼠标抬起事件
canvas.on('mouse:up', function(event) {
if(isMovePostion)isMovePostion = false
// if(canvasBtn.canvasState != 'move')canvasGeneral.updateCanvasState('mouseUp')
});
canvas.on("mouse:down", event=>setCanvasDown(event));
canvas.on('mouse:wheel', opt => {
const delta = opt.e.deltaY // 滚轮,向上滚一下是 -100向下滚一下是 100
let zoom = canvas.getZoom() // 获取画布当前缩放值
zoom *= 0.999 ** delta
if (zoom > 20) zoom = 20
if (zoom < 0.01) zoom = 0.01
canvas.zoomToPoint(
{ // 关键点
x: opt.e.offsetX,
y: opt.e.offsetY
},
zoom
)
opt.e.preventDefault()
opt.e.stopPropagation()
upDataPencilWidth(zoom)
})
canvas.on("mouse:move", event=>setCanvasMove(event));
//画布上移动
document.addEventListener('mousemove', mouseMove);
document.addEventListener('touchmove', touchmove);
setOperation('pencil')
img.remove()
}
const getCanvasData = ()=>{
return canvasExport
}
onMounted(() => {
if(props.imgUrl){
let img = new Image()
img.onload = ()=>{
let domHeight = dataDom.canvasBox.offsetHeight
let imgHeight = img.height
data.canvasConfig.height = domHeight
data.canvasConfig.width = imgHeight/domHeight * img.width
// canvasWH.value = height
// // canvasBox.style.width = height+'px'
// let wScale = 1
// let hScale = 1
// if(img.width>img.height){
// hScale = img.height/img.width
// exportWH = img.width
// }else{
// wScale = img.width/img.height
// exportWH = img.height
// }
// ratio = [wScale,hScale]
// canvas = canvasGeneral.canvasInit(canvasBox,{
// width:canvasWH.value * wScale,
// height:canvasWH.value * hScale,
// })
// canvas.selection = false;
// dataDom.editCanvas.addImageToLayer(img)
data.canvasLoad = true
}
img.src = props.imgUrl
})
}
let clearCanvas = ()=>{
canvasBtn.canvasState = 'move'
canvasBtn.spreadState = false
canvasGeneral.canvasClear()
}
let mouseMove = (event)=>{
let e = getMousePosition(event,false)
setDomMove(e)
}
let touchmove = (event)=>{
let e = getMousePosition(event,true)
setDomMove(e)
}
let setDomMove = (event)=>{
if(canvas.isDrawingMode){
canvas.setCursor('none');
}
let canvasCenterBox = document.querySelector(".generalMiniCanvas .exportCanvasBox_center_box");
if(!canvasCenterBox)return
let parentX = event.clientX - canvasCenterBox.getBoundingClientRect().left
let parentY = event.clientY - canvasCenterBox.getBoundingClientRect().top
pencilbtnStyle.value.left = parentX + "px"
pencilbtnStyle.value.top = parentY+'px'
}
let setCanvasMove = (event) =>{
if(canvasBtn.canvasState == 'movePosition' && isMovePostion)setCanvasPosition(event)
}
let lastPosX = 0
let lastPosY = 0
let setCanvasDown = (event)=>{
if(canvasBtn.canvasState == 'movePosition'){
isMovePostion = true;
lastPosX = event.pointer.x;
lastPosY = event.pointer.y;
return
}
if(canvasBtn.canvasState == 'zoomIn' || canvasBtn.canvasState == 'zoomOut'){
setCanvasZoom(event)
return
}
}
let setCanvasPosition = (event)=>{
const e = event;
const vpt = canvas.viewportTransform;
vpt[4] += e.pointer.x - lastPosX; // 更新水平偏移
vpt[5] += e.pointer.y - lastPosY; // 更新垂直偏移
canvas.requestRenderAll(); // 请求重绘画布
lastPosX = e.pointer.x;
lastPosY = e.pointer.y;
}
let setCanvasZoom = (opt)=>{
let zoom = canvas.getZoom() // 获取画布当前缩放值
let num = -100
if(canvasBtn.canvasState == 'zoomOut') num = 100
zoom *= 0.999 ** num
if (zoom > 20) zoom = 20
if (zoom < 0.01) zoom = 0.01
// console.log(zoom);
canvas.zoomToPoint(
{ // 关键点
x: opt.pointer.x,
y: opt.pointer.y
},
zoom
)
opt.e.preventDefault()
opt.e.stopPropagation()
upDataPencilWidth(zoom)
}
let setOperation = (str)=>{
canvasBtn.canvasState = str
let canvasCenterBox = document.querySelector(".generalMiniCanvas .exportCanvasBox_center_box");
let classList = canvasCenterBox.className.split(' ');
canvasCenterBox.className = 'exportCanvasBox_center_box'
if(str == 'move'){
setMove()
pencilbtnStyle.value.display = `none`
canvasCenterBox.className = 'exportCanvasBox_center_box'
}else if(str == 'pencil'){
setPencil()
pencilbtnStyle.value.display = `block`
canvasCenterBox.className = 'exportCanvasBox_center_box cursorNone'
}else if(str == 'eraser'){
setEraser()
pencilbtnStyle.value.display = `block`
canvasCenterBox.className = 'exportCanvasBox_center_box cursorNone'
}else if(str == 'liquidation'){
canvas.isDrawingMode = false
canvasCenterBox.className = 'exportCanvasBox_center_box cursorNone'
}else if(str == 'zoomIn' || str == 'zoomOut'){
pencilbtnStyle.value.display = `none`
canvas.isDrawingMode = false
canvas.forEachObject((obj) =>obj.selectable = false);
canvasCenterBox.className = 'exportCanvasBox_center_box'
}else if(str == 'movePosition'){
canvas.isDrawingMode = false
pencilbtnStyle.value.display = `none`
canvas.forEachObject((obj) =>obj.selectable = false);
canvasCenterBox.className = 'exportCanvasBox_center_box cursorMove'
}
}
let brushworkValue = ref('PencilBrush')
let brushworkChange = (value)=>{
brushworkValue.value = value
setPencil()
}
let setMove = ()=>{
canvas.isDrawingMode = false
canvas.forEachObject((obj) =>obj.selectable = true);
}
let brushList = ref([
{
value:'PencilBrush',
url:'/image/brush/PencilBrush.jpg'
},{
value:'Marking',
url:'/image/brush/PencilBrush-2.jpg'
},{
value:'InkBrush',
url:'/image/brush/InkBrush.jpg'
},{
value:'CrayonBrush',
url:'/image/brush/CrayonBrush.jpg'
},{
value:'RibbonBrush',
url:'/image/brush/RibbonBrush.jpg'
},{
value:'MarkerBrush',
url:'/image/brush/MarkerBrush.jpg'
},{
value:'WritingBrush',
url:'/image/brush/WritingBrush.jpg'
},{
value:'LongfurBrush',
url:'/image/brush/LongfurBrush.jpg'
},{
value:'SpraypaintBrush',
url:'/image/brush/SpraypaintBrush.jpg'
},
])
let setPencil = ()=>{
let pencil
canvas.isDrawingMode = true//开启绘画模式
if(brushworkValue.value == 'PencilBrush'){
pencil = new fabric.PencilBrush(canvas,{}); //普通笔
}else if(brushworkValue.value == 'Marking'){
pencil = new fabric.PencilBrush(canvas,); //记号笔
}else if(brushworkValue.value == 'InkBrush'){
pencil = new fabric.InkBrush(canvas,{}); //油画笔
}else if(brushworkValue.value=='CrayonBrush'){
pencil = new fabric.CrayonBrush(canvas,{}); //蜡笔
}else if(brushworkValue.value == 'RibbonBrush'){
pencil = new fabric.RibbonBrush(canvas,{width: 1,}); //色带
}else if(brushworkValue.value == 'MarkerBrush'){
pencil = new fabric.MarkerBrush(canvas,{}); //书写笔
// pencil = new fabric.PenBrush(canvas,{}); //书写笔
}else if(brushworkValue.value == 'WritingBrush'){
pencil = new fabric.WritingBrush(canvas,{}); //毛笔
}else if(brushworkValue.value == 'LongfurBrush'){
pencil = new fabric.LongfurBrush(canvas,{width: 1,}); //色带
}else if(brushworkValue.value == 'SpraypaintBrush'){
pencil = new fabric.SpraypaintBrush(canvas,{}); //长毛刷
}
canvas.freeDrawingBrush = pencil
canvas.freeDrawingBrush.width = Number(canvasBtn.canvasPencilWidth[canvasBtn.canvasState]);
pencilbtnStyle.value.background = canvasBtn.canvasPencilColor
canvas.freeDrawingBrush.isEraser = false
setPencilWidth()
pencilColor()
}
let setEraser = ()=>{
canvas.isDrawingMode = true
let eraser = new fabric.EraserBrush(canvas)
canvas.freeDrawingBrush = eraser
canvas.requestRenderAll();
canvas.freeDrawingBrush.isEraser = true
pencilbtnStyle.value.background = `rgb(255,255,255)`
canvas.freeDrawingBrush.width = Number(canvasBtn.canvasPencilWidth[canvasBtn.canvasState]);
setPencilWidth()
}
let upDataPencilWidth = (zoom)=>{
if(canvasBtn.canvasPencilWidth[canvasBtn?.canvasState]){
canvas.freeDrawingBrush.width = Number(canvasBtn.canvasPencilWidth[canvasBtn.canvasState]) / zoom;
}
}
let deleteObj = ()=> {
// if(!canvas.getActiveObjects()){
// return
// }
let target = canvas.getActiveObjects()
target.forEach((item)=>{
canvas.fxRemove(item, {
onComplete(){
canvas.discardActiveObject(); // 丢弃当前选中的对象
canvas.renderAll(); // 重新渲染 Canvas
}
})
canvas.FX_DURATION = 300
})
}
let setTimeOut = {
pencilWidth:null,
color:null,
}
let setPencilWidth = ()=>{//切换颜色给铅笔设置颜色
clearTimeout(setTimeOut.pencilWidth)
setTimeOut.pencilWidth = setTimeout(()=>{
let zoom = canvas.getZoom() // 获取画布当前缩放值
canvas.freeDrawingBrush.width = Number(canvasBtn.canvasPencilWidth[canvasBtn.canvasState]) / zoom
pencilbtnStyle.value.height = canvasBtn.canvasPencilWidth[canvasBtn.canvasState]+'px'
pencilbtnStyle.value.width = canvasBtn.canvasPencilWidth[canvasBtn.canvasState]+'px'
if(brushworkValue.value == 'RibbonBrush' || brushworkValue.value == 'LongfurBrush'){
canvas.freeDrawingBrush.width = 1;
pencilbtnStyle.value.height = 1+'px'
pencilbtnStyle.value.width = 1+'px'
}
},300)
}
let setPencilColor = ()=>{//切换颜色给铅笔设置颜色
clearTimeout(setTimeOut.color)
// clearTimeout(setTimeOut.colorHistory)
setTimeOut.color = setTimeout(()=>{
pencilColor()
},200)
// setTimeOut.colorHistory = setTimeout(()=>{
// colorHistoryList.value.push(canvasPencilColor.value)
// },1000)
}
let hexToRgba=(hex, alpha)=> {
const r = parseInt(hex.slice(1, 3), 16);
const g = parseInt(hex.slice(3, 5), 16);
const b = parseInt(hex.slice(5, 7), 16);
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
}
let pencilColor = ()=>{
if(canvas.freeDrawingBrush.isEraser){
canvas.freeDrawingBrush.color = '#FFFFFF';
}else{
pencilbtnStyle.value.background = canvasBtn.canvasPencilColor
if(brushworkValue.value == 'Marking'){
console.log(canvasBtn.canvasPencilColor);
console.log(hexToRgba(canvasBtn.canvasPencilColor,.5));
canvas.freeDrawingBrush.color = hexToRgba(canvasBtn.canvasPencilColor,.5)
}else{
canvas.freeDrawingBrush.color = canvasBtn.canvasPencilColor
}
data.canvasLoad = true
}
}
let routesChange = (str)=>{
canvasBtn.canvasPencilWidth[str] = Math.round(canvasBtn.canvasPencilWidth[str]/10)*10;
if (canvasBtn.canvasPencilWidth[str] < 10) {
canvasBtn.canvasPencilWidth[str] = 10; // 设置为最小值
} else if (canvasBtn.canvasPencilWidth[str] > 100) {
canvasBtn.canvasPencilWidth[str] = 100; // 设置为最大值
}
}
let setSubmit = (liquefation)=>{
return new Promise((resolve,reject)=>{
var allObjects = canvas.getObjects();
// return
// if(allObjects.length == 0){
// return message.info(t('addDetails.jsContent1'))
// }
var canvasDom = document.createElement("canvas");
let exportCanvas = new fabric.Canvas(canvasDom, {
backgroundColor: "#FFFFFF",
width: exportWH * ratio[0],
height: exportWH * ratio[1],
isDrawingMode: false, // 开启绘图模式
});
canvas.backgroundImage.clone(async (back)=>{
back.set({
scaleX:1,
scaleY:1,
left:back.left*scale,
top:back.top*scale ,
})
exportCanvas.backgroundImage = back
await new Promise((resolve, reject) => {
if(allObjects.length == 0)resolve('')
allObjects.forEach((item,index)=>{
// let obj = fabric.util.object.clone(item);
if(item.type == 'circle')return
let obj
item.clone((cloned)=>{
console.log(cloned);
obj = cloned
console.log(obj.set);
if(obj.set){
obj.set(
{
scaleX:(item.scaleX?item.scaleX:1)*scale,
scaleY:(item.scaleY?item.scaleY:1)*scale,
left:item.left*scale,
top:item.top*scale,
}
)
}
// else{
// console.log(item.width,scale);
// obj.width = (item.width?item.width:1)*scale
// obj.height = (item.height?item.height:1)*scale
// obj.left = item.left*scale
// obj.top = item.top*scale
// }
exportCanvas.add(obj)
if(index == allObjects.length - 1){
resolve('')
}
})
})
})
let position = JSON.parse(JSON.stringify(canvas.viewportTransform))
position[4] *= scale
position[5] *= scale
//设置画布当前那位置和缩放
// exportCanvas.viewportTransform = position
let data = exportCanvas.toDataURL("image/png");
if(liquefation){
return resolve(data)
}
cancelDsign()
clearCanvas()
emit('submitBase64Data',data)
resolve('')
})
})
}
let cancelDsign = ()=>{
showPayOrder.value = false
}
let liquefactionData = ref(null)
let liquefaction = ref(null)
let submitLiquefaction = (rv)=>{
// const originalWidth = liquefactionData.value.width // 保存原始宽度
// const originalHeight = liquefactionData.value.height; // 保存原始高度
canvas.viewportTransform = [1,0,0,1,0,0]
fabric.Image.fromURL(rv, function(img) {
// 设置背景图对象的宽度和高度与 canvas 相同
img.scaleToWidth(canvas.width);
img.scaleToHeight(canvas.height);
img.set({
scaleX: canvas.width / img.width,
scaleY: canvas.height / img.height
});
// 将背景图添加到 canvas 的底层
canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas));
if(!fabric.Object.prototype.controls.deleteControl){
JSSetRemoveImage(deleteObj)
}else{
fabric.Object.prototype.controls.deleteControl.mouseUpHandler = deleteObj
}
setPencilWidth()
canvasGeneral.updateCanvasState()
},{ crossOrigin: "Anonymous" });
}
let setLiquefaction =async ()=>{
// const activeObjects = canvas.backgroundImage // 获取选中的对象
// console.log(setSubmit(true));
let activeObjects = await setSubmit(true)
if (activeObjects) {
liquefactionData.value = activeObjects
liquefaction.value.init(activeObjects)
} else {
// message.info(useI18.t('exportModel.jsContent6'))
return null;
}
}
});
onBeforeUnmount(()=>{
data.canvasLoad = false
// canvasGeneral.canvasClear()
})
return {
presentState,
showPayOrder,
loadingShow,
t,
pencilbtnStyle,
...toRefs(canvasBtn),
arrows,
liquefactionData,
liquefaction,
init,
setOperation,
setPencilWidth,
setPencilColor,
setSubmit,
cancelDsign,
submitLiquefaction,
setLiquefaction,
routesChange,
brushList,
brushworkValue,
brushworkChange,
canvasGeneral,
...toRefs(data),
...toRefs(dataDom),
isShowMark,
addImage,
getData,
getCanvasData,
};
},
data() {
data(prop) {
return {
};
};
},
computed: {
},
watch: {
},
mounted() {},
methods: {
},
},
});
</script>
<style lang="less">
.generalMiniCanvas{
position: relative;
height: 100%;
display: flex;
<style lang="less" scoped>
.generalCanvas{
width: 100%;
// flex-direction: column;
margin: 0 auto;
flex-direction: row;
flex: 1;
height: 100%;
position: relative;
display: flex;
flex-direction: column;
overflow: hidden;
.generalMiniCanvas_item{
// position: relative;
background: #fff;
position: absolute;
display: flex;
// border: 0.2rem solid #c4c4c4;
width: 25rem;
border-radius: 4px; /* 设置圆角半径 */
flex-wrap: wrap;
.generalMiniCanvas_btn_item{
display: flex;
align-items: center;
padding: 1rem 0;
}
}
.generalMiniCanvas_input,.generalMiniCanvas_btn{
z-index: 2;
padding: 1rem 1.5rem;
position: relative;
width: auto;
flex-wrap: nowrap;
flex-direction: column;
}
.generalMiniCanvas_input{
flex-direction: row;
align-items: center;
margin-left: 7rem;
height: 6rem;
.generalMiniCanvas_input_item{
display: flex;
margin-right: 3rem;
align-items: center;
&.brushwork{
img{
width: 100%;
max-height: 100%;
object-fit: contain;
}
}
span{
margin-right: 1rem;
}
}
.generalMiniCanvas_input_item:last-child{
margin-right: 0;
}
}
.generalMiniCanvas_btn{
input{
// width: 100%;
width: 30rem;
// margin-top: 1rem;
flex: 1;
}
.icon-xiala{
position: absolute;
width: 2rem;
bottom: 0;
transform: translate(-50%, 90%);
left: 50%;
width: 6rem;
background: #fff;
text-align: center;
cursor: pointer;
&.icon-xiala::before{
transition: all .3s;
}
&.btnRotate::before{
transform: rotate(180deg);
display: block;
}
}
i{
font-size: 2.5rem;
cursor: pointer;
width: 4rem;
height: 4rem;
display: flex;
align-items: center;
justify-content: center;
&.active{
border: 1px solid;
border-radius: .4rem;
}
}
&.spread{
transform: translate(-50%,0);
}
}
.addDetails_canvasCenter{
flex: 1;
overflow: hidden;
display: flex;
// flex-direction: column;
// flex-direction: row;
position: relative;
margin: 0 auto;
flex-direction: column;
}
.exportCanvasBox_center_data{
flex: 1;
display: flex;
overflow: hidden;
}
.exportCanvasBox_center_box{
padding: 3rem;
height: 100%;
padding-top: 4rem;
> .canvasBox{
flex: 1;
position: relative;
overflow: hidden;
width: 100%;
background: #e6e6e6;
cursor: inherit;
&.cursorNone:hover{
cursor: none;
}
&.cursorMove:hover{
cursor: move;
canvas{
cursor: move !important;
}
}
.editFrontBack_pencilbtn{
position: absolute;
z-index: 1;
border-radius: 50%;
border: 1px solid #000;
pointer-events: none;
transform: translate(-50%,-50%);
}
}
.exportCanvasBox_center{
height: 100%;
flex: 1;
position: relative;
overflow: hidden;
background: #e6e6e6;
// overflow: scroll;
.canvas-container{
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
}
.editFrontBack_pencilbtn{
position: absolute;
z-index: 1;
border-radius: 50%;
border: 1px solid #000;
pointer-events: none;
transform: translate(-50%,-50%);
}
}
.exportCanvasBox_center:hover{
.generalMiniCanvas_btn{
// transform: translate(-50%,-101%);
// &.spread{
// transform: translate(-50%,0);
// }
}
}
}
.exportCanvasBox_submit{
margin-top: auto;
margin-left: 1rem;
text-align: center;
}
</style>