diff --git a/.gitignore b/.gitignore
index 61bc8e64..97c229d8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,3 +24,4 @@ dist.rar
*.sw?
.eslintrc-auto-import.json
components.d.ts
+.cursor
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 0e42a09e..c319c9a6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -34,6 +34,7 @@
"vue-draggable-plus": "^0.6.0",
"vue-i18n": "^9.6.1",
"vue-router": "^4.0.3",
+ "vue3-moveable": "^0.28.0",
"vuedraggable": "^4.1.0",
"vuex": "^4.0.0",
"x-sender": "^1.1.6"
@@ -232,6 +233,15 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@cfcs/core": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmmirror.com/@cfcs/core/-/core-0.0.6.tgz",
+ "integrity": "sha512-FxfJMwoLB8MEMConeXUCqtMGqxdtePQxRBOiGip9ULcYYam3WfCgoY6xdnMaSkYvRvmosp5iuG+TiPofm65+Pw==",
+ "license": "MIT",
+ "dependencies": {
+ "@egjs/component": "^3.0.2"
+ }
+ },
"node_modules/@ctrl/tinycolor": {
"version": "3.6.1",
"resolved": "https://registry.npmmirror.com/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz",
@@ -240,6 +250,39 @@
"node": ">=10"
}
},
+ "node_modules/@daybrush/utils": {
+ "version": "1.13.0",
+ "resolved": "https://registry.npmmirror.com/@daybrush/utils/-/utils-1.13.0.tgz",
+ "integrity": "sha512-ALK12C6SQNNHw1enXK+UO8bdyQ+jaWNQ1Af7Z3FNxeAwjYhQT7do+TRE4RASAJ3ObaS2+TJ7TXR3oz2Gzbw0PQ==",
+ "license": "MIT"
+ },
+ "node_modules/@egjs/agent": {
+ "version": "2.4.4",
+ "resolved": "https://registry.npmmirror.com/@egjs/agent/-/agent-2.4.4.tgz",
+ "integrity": "sha512-cvAPSlUILhBBOakn2krdPnOGv5hAZq92f1YHxYcfu0p7uarix2C6Ia3AVizpS1SGRZGiEkIS5E+IVTLg1I2Iog==",
+ "license": "MIT"
+ },
+ "node_modules/@egjs/children-differ": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/@egjs/children-differ/-/children-differ-1.0.1.tgz",
+ "integrity": "sha512-DRvyqMf+CPCOzAopQKHtW+X8iN6Hy6SFol+/7zCUiE5y4P/OB8JP8FtU4NxtZwtafvSL4faD5KoQYPj3JHzPFQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@egjs/list-differ": "^1.0.0"
+ }
+ },
+ "node_modules/@egjs/component": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmmirror.com/@egjs/component/-/component-3.0.5.tgz",
+ "integrity": "sha512-cLcGizTrrUNA2EYE3MBmEDt2tQv1joVP1Q3oDisZ5nw0MZDx2kcgEXM+/kZpfa/PAkFvYVhRUZwytIQWoN3V/w==",
+ "license": "MIT"
+ },
+ "node_modules/@egjs/list-differ": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/@egjs/list-differ/-/list-differ-1.0.1.tgz",
+ "integrity": "sha512-OTFTDQcWS+1ZREOdCWuk5hCBgYO4OsD30lXcOCyVOAjXMhgL5rBRDnt/otb6Nz8CzU0L/igdcaQBDLWc4t9gvg==",
+ "license": "MIT"
+ },
"node_modules/@element-plus/icons-vue": {
"version": "2.3.1",
"resolved": "https://registry.npmmirror.com/@element-plus/icons-vue/-/icons-vue-2.3.1.tgz",
@@ -1224,6 +1267,34 @@
"win32"
]
},
+ "node_modules/@scena/dragscroll": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmmirror.com/@scena/dragscroll/-/dragscroll-1.4.0.tgz",
+ "integrity": "sha512-3O8daaZD9VXA9CP3dra6xcgt/qrm0mg0xJCwiX6druCteQ9FFsXffkF8PrqxY4Z4VJ58fFKEa0RlKqbsi/XnRA==",
+ "license": "MIT",
+ "dependencies": {
+ "@daybrush/utils": "^1.6.0",
+ "@scena/event-emitter": "^1.0.2"
+ }
+ },
+ "node_modules/@scena/event-emitter": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmmirror.com/@scena/event-emitter/-/event-emitter-1.0.5.tgz",
+ "integrity": "sha512-AzY4OTb0+7ynefmWFQ6hxDdk0CySAq/D4efljfhtRHCOP7MBF9zUfhKG3TJiroVjASqVgkRJFdenS8ArZo6Olg==",
+ "license": "MIT",
+ "dependencies": {
+ "@daybrush/utils": "^1.1.1"
+ }
+ },
+ "node_modules/@scena/matrix": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/@scena/matrix/-/matrix-1.1.1.tgz",
+ "integrity": "sha512-JVKBhN0tm2Srl+Yt+Ywqu0oLgLcdemDQlD1OxmN9jaCTwaFPZ7tY8n6dhVgMEaR9qcR7r+kAlMXnSfNyYdE+Vg==",
+ "license": "MIT",
+ "dependencies": {
+ "@daybrush/utils": "^1.4.0"
+ }
+ },
"node_modules/@simonwep/pickr": {
"version": "1.8.2",
"resolved": "https://registry.npmmirror.com/@simonwep/pickr/-/pickr-1.8.2.tgz",
@@ -2904,6 +2975,52 @@
"node": ">= 0.10"
}
},
+ "node_modules/croact": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmmirror.com/croact/-/croact-1.0.4.tgz",
+ "integrity": "sha512-9GhvyzTY/IVUrMQ2iz/mzgZ8+NcjczmIo/t4FkC1CU0CEcau6v6VsEih4jkTa4ZmRgYTF0qXEZLObCzdDFplpw==",
+ "license": "MIT",
+ "dependencies": {
+ "@daybrush/utils": "^1.13.0",
+ "@egjs/list-differ": "^1.0.0"
+ }
+ },
+ "node_modules/croact-css-styled": {
+ "version": "1.1.9",
+ "resolved": "https://registry.npmmirror.com/croact-css-styled/-/croact-css-styled-1.1.9.tgz",
+ "integrity": "sha512-G7yvRiVJ3Eoj0ov2h2xR4312hpOzATay2dGS9clK8yJQothjH1sBXIyvOeRP5wBKD9mPcKcoUXPCPsl0tQog4w==",
+ "license": "MIT",
+ "dependencies": {
+ "@daybrush/utils": "^1.13.0",
+ "css-styled": "~1.0.8",
+ "framework-utils": "^1.1.0"
+ }
+ },
+ "node_modules/croact-moveable": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmmirror.com/croact-moveable/-/croact-moveable-0.9.0.tgz",
+ "integrity": "sha512-fc3bieV6CdqqZFtzsSLi9KmvUMFW3oakUfhPCls1BxKjOfUfn8rktteGED2341A/Qghy8tI3Hm6SdocIc68IKg==",
+ "license": "MIT",
+ "dependencies": {
+ "@daybrush/utils": "^1.13.0",
+ "@egjs/agent": "^2.2.1",
+ "@egjs/children-differ": "^1.0.1",
+ "@egjs/list-differ": "^1.0.0",
+ "@scena/dragscroll": "^1.4.0",
+ "@scena/event-emitter": "^1.0.5",
+ "@scena/matrix": "^1.1.1",
+ "croact-css-styled": "^1.1.9",
+ "css-to-mat": "^1.1.1",
+ "framework-utils": "^1.1.0",
+ "gesto": "^1.19.3",
+ "overlap-area": "^1.1.0",
+ "react-css-styled": "^1.1.9",
+ "react-moveable": "~0.56.0"
+ },
+ "peerDependencies": {
+ "croact": "^1.0.4"
+ }
+ },
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.6.tgz",
@@ -3014,6 +3131,25 @@
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
+ "node_modules/css-styled": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmmirror.com/css-styled/-/css-styled-1.0.8.tgz",
+ "integrity": "sha512-tCpP7kLRI8dI95rCh3Syl7I+v7PP+2JYOzWkl0bUEoSbJM+u8ITbutjlQVf0NC2/g4ULROJPi16sfwDIO8/84g==",
+ "license": "MIT",
+ "dependencies": {
+ "@daybrush/utils": "^1.13.0"
+ }
+ },
+ "node_modules/css-to-mat": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/css-to-mat/-/css-to-mat-1.1.1.tgz",
+ "integrity": "sha512-kvpxFYZb27jRd2vium35G7q5XZ2WJ9rWjDUMNT36M3Hc41qCrLXFM5iEKMGXcrPsKfXEN+8l/riB4QzwwwiEyQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@daybrush/utils": "^1.13.0",
+ "@scena/matrix": "^1.0.0"
+ }
+ },
"node_modules/css-tree": {
"version": "1.1.3",
"resolved": "https://registry.npmmirror.com/css-tree/-/css-tree-1.1.3.tgz",
@@ -4354,6 +4490,12 @@
"node": ">=0.10.0"
}
},
+ "node_modules/framework-utils": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/framework-utils/-/framework-utils-1.1.0.tgz",
+ "integrity": "sha512-KAfqli5PwpFJ8o3psRNs8svpMGyCSAe8nmGcjQ0zZBWN2H6dZDnq+ABp3N3hdUmFeMrLtjOCTXD4yplUJIWceg==",
+ "license": "MIT"
+ },
"node_modules/fs-extra": {
"version": "10.1.0",
"resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-10.1.0.tgz",
@@ -4485,6 +4627,16 @@
"node": ">=10"
}
},
+ "node_modules/gesto": {
+ "version": "1.19.4",
+ "resolved": "https://registry.npmmirror.com/gesto/-/gesto-1.19.4.tgz",
+ "integrity": "sha512-hfr/0dWwh0Bnbb88s3QVJd1ZRJeOWcgHPPwmiH6NnafDYvhTsxg+SLYu+q/oPNh9JS3V+nlr6fNs8kvPAtcRDQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@daybrush/utils": "^1.13.0",
+ "@scena/event-emitter": "^1.0.2"
+ }
+ },
"node_modules/get-intrinsic": {
"version": "1.3.0",
"resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
@@ -5695,6 +5847,24 @@
"setimmediate": "^1.0.5"
}
},
+ "node_modules/keycode": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmmirror.com/keycode/-/keycode-2.2.1.tgz",
+ "integrity": "sha512-Rdgz9Hl9Iv4QKi8b0OlCRQEzp4AgVxyCtz5S/+VIHezDmrDhkp2N2TqBWOLz0/gbeREXOOiI9/4b8BY9uw2vFg==",
+ "license": "MIT"
+ },
+ "node_modules/keycon": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmmirror.com/keycon/-/keycon-1.4.0.tgz",
+ "integrity": "sha512-p1NAIxiRMH3jYfTeXRs2uWbVJ1WpEjpi8ktzUyBJsX7/wn2qu2VRXktneBLNtKNxJmlUYxRi9gOJt1DuthXR7A==",
+ "license": "MIT",
+ "dependencies": {
+ "@cfcs/core": "^0.0.6",
+ "@daybrush/utils": "^1.7.1",
+ "@scena/event-emitter": "^1.0.2",
+ "keycode": "^2.2.0"
+ }
+ },
"node_modules/keyv": {
"version": "4.5.4",
"resolved": "https://registry.npmmirror.com/keyv/-/keyv-4.5.4.tgz",
@@ -6212,6 +6382,19 @@
"pathe": "^2.0.1"
}
},
+ "node_modules/moveable": {
+ "version": "0.53.0",
+ "resolved": "https://registry.npmmirror.com/moveable/-/moveable-0.53.0.tgz",
+ "integrity": "sha512-71jS9zIoQzMhnNvduhg4tUEdm23+fO/40FN7muVMbZvVwbTku2MIxxLhnU4qFvxI4oVxn75l79SbtgjuA+s7Pw==",
+ "license": "MIT",
+ "dependencies": {
+ "@daybrush/utils": "^1.13.0",
+ "@scena/event-emitter": "^1.0.5",
+ "croact": "^1.0.4",
+ "croact-moveable": "~0.9.0",
+ "react-moveable": "~0.56.0"
+ }
+ },
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz",
@@ -6650,6 +6833,15 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/overlap-area": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/overlap-area/-/overlap-area-1.1.0.tgz",
+ "integrity": "sha512-3dlJgJCaVeXH0/eZjYVJvQiLVVrPO4U1ZGqlATtx6QGO3b5eNM6+JgUKa7oStBTdYuGTk7gVoABCW6Tp+dhRdw==",
+ "license": "MIT",
+ "dependencies": {
+ "@daybrush/utils": "^1.7.1"
+ }
+ },
"node_modules/own-keys": {
"version": "1.0.1",
"resolved": "https://registry.npmmirror.com/own-keys/-/own-keys-1.0.1.tgz",
@@ -7037,6 +7229,46 @@
"safe-buffer": "^5.1.0"
}
},
+ "node_modules/react-css-styled": {
+ "version": "1.1.9",
+ "resolved": "https://registry.npmmirror.com/react-css-styled/-/react-css-styled-1.1.9.tgz",
+ "integrity": "sha512-M7fJZ3IWFaIHcZEkoFOnkjdiUFmwd8d+gTh2bpqMOcnxy/0Gsykw4dsL4QBiKsxcGow6tETUa4NAUcmJF+/nfw==",
+ "license": "MIT",
+ "dependencies": {
+ "css-styled": "~1.0.8",
+ "framework-utils": "^1.1.0"
+ }
+ },
+ "node_modules/react-moveable": {
+ "version": "0.56.0",
+ "resolved": "https://registry.npmmirror.com/react-moveable/-/react-moveable-0.56.0.tgz",
+ "integrity": "sha512-FmJNmIOsOA36mdxbrc/huiE4wuXSRlmon/o+/OrfNhSiYYYL0AV5oObtPluEhb2Yr/7EfYWBHTxF5aWAvjg1SA==",
+ "license": "MIT",
+ "dependencies": {
+ "@daybrush/utils": "^1.13.0",
+ "@egjs/agent": "^2.2.1",
+ "@egjs/children-differ": "^1.0.1",
+ "@egjs/list-differ": "^1.0.0",
+ "@scena/dragscroll": "^1.4.0",
+ "@scena/event-emitter": "^1.0.5",
+ "@scena/matrix": "^1.1.1",
+ "css-to-mat": "^1.1.1",
+ "framework-utils": "^1.1.0",
+ "gesto": "^1.19.3",
+ "overlap-area": "^1.1.0",
+ "react-css-styled": "^1.1.9",
+ "react-selecto": "^1.25.0"
+ }
+ },
+ "node_modules/react-selecto": {
+ "version": "1.26.3",
+ "resolved": "https://registry.npmmirror.com/react-selecto/-/react-selecto-1.26.3.tgz",
+ "integrity": "sha512-Ubik7kWSnZyQEBNro+1k38hZaI1tJarE+5aD/qsqCOA1uUBSjgKVBy3EWRzGIbdmVex7DcxznFZLec/6KZNvwQ==",
+ "license": "MIT",
+ "dependencies": {
+ "selecto": "~1.26.3"
+ }
+ },
"node_modules/readable-stream": {
"version": "2.3.8",
"resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.8.tgz",
@@ -7507,6 +7739,24 @@
"integrity": "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==",
"dev": true
},
+ "node_modules/selecto": {
+ "version": "1.26.3",
+ "resolved": "https://registry.npmmirror.com/selecto/-/selecto-1.26.3.tgz",
+ "integrity": "sha512-gZHgqMy5uyB6/2YDjv3Qqaf7bd2hTDOpPdxXlrez4R3/L0GiEWDCFaUfrflomgqdb3SxHF2IXY0Jw0EamZi7cw==",
+ "license": "MIT",
+ "dependencies": {
+ "@daybrush/utils": "^1.13.0",
+ "@egjs/children-differ": "^1.0.1",
+ "@scena/dragscroll": "^1.4.0",
+ "@scena/event-emitter": "^1.0.5",
+ "css-styled": "^1.0.8",
+ "css-to-mat": "^1.1.1",
+ "framework-utils": "^1.1.0",
+ "gesto": "^1.19.4",
+ "keycon": "^1.2.0",
+ "overlap-area": "^1.1.0"
+ }
+ },
"node_modules/semver": {
"version": "7.7.2",
"resolved": "https://registry.npmmirror.com/semver/-/semver-7.7.2.tgz",
@@ -9765,6 +10015,16 @@
"vue": "^3.0.0"
}
},
+ "node_modules/vue3-moveable": {
+ "version": "0.28.0",
+ "resolved": "https://registry.npmmirror.com/vue3-moveable/-/vue3-moveable-0.28.0.tgz",
+ "integrity": "sha512-vplQO0XkxVEtXMDh2/lZE+c5kMycGXAfYFMvbwFKi8UVYzVk8MTgVHr4fxO9Z+4i4Rb+U/IEIgkhHRMAbx8FJg==",
+ "license": "MIT",
+ "dependencies": {
+ "framework-utils": "^1.1.0",
+ "moveable": "~0.53.0"
+ }
+ },
"node_modules/vuedraggable": {
"version": "4.1.0",
"resolved": "https://registry.npmmirror.com/vuedraggable/-/vuedraggable-4.1.0.tgz",
diff --git a/package.json b/package.json
index 962ae9e0..d83dfe55 100644
--- a/package.json
+++ b/package.json
@@ -40,6 +40,7 @@
"vue-draggable-plus": "^0.6.0",
"vue-i18n": "^9.6.1",
"vue-router": "^4.0.3",
+ "vue3-moveable": "^0.28.0",
"vuedraggable": "^4.1.0",
"vuex": "^4.0.0",
"x-sender": "^1.1.6"
diff --git a/src/assets/images/award/arrow.png b/src/assets/images/award/arrow.png
new file mode 100644
index 00000000..9c9622e1
Binary files /dev/null and b/src/assets/images/award/arrow.png differ
diff --git a/src/assets/images/award/bloom_bg.png b/src/assets/images/award/bloom_bg.png
new file mode 100644
index 00000000..f40622f2
Binary files /dev/null and b/src/assets/images/award/bloom_bg.png differ
diff --git a/src/assets/images/award/bloom_logo.png b/src/assets/images/award/bloom_logo.png
new file mode 100644
index 00000000..3b27a4bf
Binary files /dev/null and b/src/assets/images/award/bloom_logo.png differ
diff --git a/src/assets/images/award/code_create_logo.png b/src/assets/images/award/code_create_logo.png
new file mode 100644
index 00000000..a0d6cf52
Binary files /dev/null and b/src/assets/images/award/code_create_logo.png differ
diff --git a/src/assets/images/award/design_bg.png b/src/assets/images/award/design_bg.png
new file mode 100644
index 00000000..4e163cf9
Binary files /dev/null and b/src/assets/images/award/design_bg.png differ
diff --git a/src/assets/images/award/timeline_bg.png b/src/assets/images/award/timeline_bg.png
new file mode 100644
index 00000000..eb170088
Binary files /dev/null and b/src/assets/images/award/timeline_bg.png differ
diff --git a/src/assets/images/award/timeline_line.png b/src/assets/images/award/timeline_line.png
new file mode 100644
index 00000000..38bb94a8
Binary files /dev/null and b/src/assets/images/award/timeline_line.png differ
diff --git a/src/assets/images/award/∞.png b/src/assets/images/award/∞.png
new file mode 100644
index 00000000..15042141
Binary files /dev/null and b/src/assets/images/award/∞.png differ
diff --git a/src/component/Detail/DesignDetail.vue b/src/component/Detail/DesignDetail.vue
index 4b63b4d4..99ccda39 100644
--- a/src/component/Detail/DesignDetail.vue
+++ b/src/component/Detail/DesignDetail.vue
@@ -50,7 +50,7 @@
-
+
{{$t('DesignPrintOperation.Preview')}}
@@ -61,7 +61,6 @@
isEditPattern.value = ''"
@@ -103,15 +102,14 @@
{{$t('DesignPrintOperation.Preview')}}
-
-
@@ -130,14 +128,13 @@ import canvasBox from './canvas/index.vue'
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { Https } from "@/tool/https";
import { Modal,message } from 'ant-design-vue';
-import {getUploadUrl,isMoible,setGradual} from '@/tool/util'
+import {getUploadUrl,segmentImage,setGradual,rgbToHsv,rgbaToHex} from '@/tool/util'
import { useStore } from "vuex";
import { openGuide,driverObj__ } from "@/tool/guide";
import { useI18n } from 'vue-i18n'
-import addDetails from '@/component/Detail/addDetails.vue'
export default defineComponent({
components:{
- detailLeft,model,detailRight,canvasBox,addDetails
+ detailLeft,model,detailRight,canvasBox
},
emits:['destroy'],
setup(props,{emit}) {
@@ -148,7 +145,6 @@ export default defineComponent({
canvasBox,
detailRight,
detailLeft:null as any,
- addDetails:null as any,
})
const userDetail = computed(()=>{
return store.state.UserHabit.userDetail
@@ -157,10 +153,12 @@ export default defineComponent({
selectObject:computed(()=>store.state.Workspace.probjects) as any,//选择的项目
designDetail:computed(()=>store.state.DesignDetail.designDetail),
currentDetailType:computed(()=>store.state.DesignDetail.currentDetailType),
+ frontBack:computed(()=>store.state.DesignDetail.frontBack),
selectDetail:computed(()=>store.state.DesignDetail.selectDetail),
designDetailShow:false,
loadingShow:false,
oppositeRevocationShow:-1,
+ imgDomIndex:-1,
revocationShow:-1,
isEditPattern:{
value:'' as any,
@@ -174,8 +172,13 @@ export default defineComponent({
},
positionKey:0,
isUndividedLayerWithSinglePrint:false,
+ detailLeftColorKey:0,
})
-
+ watch(()=>detailData.selectDetail,(newValue,oldValue)=>{
+ detailData.imgDomIndex = detailData.frontBack.front.findIndex((item:any)=>item.id == newValue.id)
+ if(newValue?.undividedLayer)newValue.undividedLayer_ = newValue.undividedLayer
+ // privewDetail(oldValue)
+ },{immediate: true})
provide('getCanvasIfEdit',detailData.getCanvasIfEdit)
provide('singleOveral',detailData.singleOveral)
@@ -320,13 +323,15 @@ export default defineComponent({
const setCurrentDetail = (str:string)=>{
store.commit('DesignDetail/setCurrentDetailType',str)
}
- const setClothes = async (list:any)=>{
+ const setClothes = async (list:any,str:string)=>{
let clothesList:any = []
await nextTick()
+ if(detailData.isEditPattern.value == 'editSketch')await detailDom.canvasBox.submitBase64Data().then((rv)=>{
+ detailData.selectDetail.sketchString = rv
+ })
for(let i = 0;i
{
let workspace = store.state.Workspace.probjects
- let clothes:any = await setClothes(detailData.designDetail.clothes)
+ let clothes:any = await setClothes(detailData.designDetail.clothes,'sub')
let data = {
designItemId:detailData.designDetail.designItemId,
designSingleItemDTOList:clothes,
@@ -466,9 +474,41 @@ export default defineComponent({
detailData.loadingShow = false
});
}
- const previwe = ()=>{
- let data = getSubmitData('preview')
- store.dispatch('DesignDetail/setSubmit',data)
+ const previwe = async ()=>{
+ if((detailData.currentDetailType == 'sketch' && !detailData.isEditPattern.value) || detailData.isEditPattern.value == 'editSketch'){
+ let data = getSubmitData('preview')
+ store.dispatch('DesignDetail/setSubmit',data)
+ }else{
+ //走画布合成图片并且直接分割
+ if(detailData.isEditPattern.value !== 'canvasEditor'){
+ if(detailDom.detailRight?.privewDetail)await (detailDom.detailRight as any).privewDetail()
+ let otherData = await updateOtherLayers('single')
+ await detailDom.canvasBox.updateOtherLayers(otherData)
+ }
+ await detailDom.canvasBox.privewDetail()
+ let img = new Image()
+ img.onload = ()=>{
+ let partialDesign = detailData.selectDetail.partialDesign.partialDesignBase64 || detailData.selectDetail.partialDesign.partialDesignPath
+ let size = {
+ width:img.width,
+ height:img.height,
+ }
+ segmentImage(detailData.selectDetail.maskUrl,partialDesign,size).then(async (rv)=>{
+ let front = detailData.frontBack.front[detailData.imgDomIndex]
+ let back = detailData.frontBack.back[detailData.imgDomIndex]
+ if(!front?.oldImageUrl)front.oldImageUrl = front.imageUrl
+ if(!front?.oldMaskUrl)front.oldMaskUrl = front.maskUrl
+ if(!back?.oldImageUrl)back.oldImageUrl = back.imageUrl
+ if(!front?.oldMaskUrl)store.commit('DesignDetail/updataDetailItem',{maskUrl:front.oldMaskUrl})
+
+ front.imageUrl = rv.targetFrontUrl
+ back.imageUrl = rv.targetBackUrl
+ detailData.selectDetail.undividedLayerWithSinglePrint = partialDesign
+ store.commit('DesignDetail/canvasPreviewUpdata',{type:detailData.isEditPattern.value?'all':detailData.currentDetailType,callBack:setRevocation})
+ })
+ }
+ img.src = detailData.selectDetail.path
+ }
}
const modelOnLoad = ()=>{
if(!detailData.isUndividedLayerWithSinglePrint)return
@@ -480,31 +520,132 @@ export default defineComponent({
const detailEdit = async (str:any)=>{
if(str){
if(detailData.isEditPattern.value && detailData.isEditPattern.value == str){
- await detailDom.canvasBox.saveCanvas()
+ // await detailDom.canvasBox.saveCanvas()
+ await (detailDom.canvasBox as any).privewDetail()
+ if(detailData.isEditPattern.value == 'canvasEditor')await uploadElement()
detailData.isEditPattern.value = ''
}else{
- if(detailData.isEditPattern.value){
- detailDom.canvasBox.editFront(str)
- }
+ // if(detailData.isEditPattern.value && (str == 'canvasEditor' || str == 'redGreenExample')){
+ // detailDom.canvasBox.editFront(str)
+ // }
+ detailDom.canvasBox.editFront(str)
+ let otherData = await updateOtherLayers('single')
+ await detailDom.canvasBox.updateOtherLayers(otherData)
detailData.isEditPattern.value = str
}
}else{
detailData.isEditPattern.value = ''
}
}
+ const getColorName = (color:any)=>{
+ let rgb:any = [color.r, color.g, color.b];
+ let hsv = rgbToHsv(rgb);
+ let data = [{
+ h: hsv[0],
+ s: hsv[1],
+ v: hsv[2],
+ }]
+ return new Promise((resolve, reject) => {
+ Https.axiosPost(Https.httpUrls.getRgbByHsvBatch, data)
+ .then((rv) => {
+ if (rv) {
+ resolve(rv[0])
+ }
+ })
+ .catch((res) => {
+ resolve({name:'--',tcx:'--'})
+ });
+ })
+ }
+ const updateOtherLayers = async (str:any='all')=>{//更新到画布图层
+ let otherData:any = {}
+ if(detailDom.detailRight?.privewDetail)await (detailDom.detailRight as any).privewDetail()
+ if(str == 'all'){
+ otherData = {
+ color: detailData.selectDetail.newDetail?.color.r?detailData.selectDetail.newDetail?.color:detailData.selectDetail.color,
+ printObject: detailData.selectDetail.newDetail?.print?.length>0?{prints:detailData.selectDetail.newDetail?.print}:detailData.selectDetail.printObject || null,
+ trims: detailData.selectDetail.newDetail?.element?.length>0?detailData.selectDetail.newDetail?.element:detailData.selectDetail.trims || null,
+ }
+ }else if(str == 'single'){
+ otherData = {
+ color: detailData.selectDetail.color,
+ printObject: detailData.selectDetail.printObject || null,
+ trims: detailData.selectDetail.trims || null,
+ }
+ if(detailData.currentDetailType == 'color'){
+ let color = detailData.selectDetail.newDetail?.color
+ console.log(color)
+ // let colorData:any = await getColorName(color?.rgba)
+ if(detailData.selectDetail.newDetail?.color?.rgba?.r){
+ color.rgba = {r:color.r,g:color.g,b:color.b,a:color.a}
+ otherData.color = color
+ }
+ }
+ if(detailData.currentDetailType == 'print'){
+ otherData.printObject = detailData.selectDetail.newDetail?.print?.length>0?{prints:detailData.selectDetail.newDetail?.print}:detailData.selectDetail.printObject || null
+ }
+ if(detailData.currentDetailType == 'element'){
+ otherData.trims = detailData.selectDetail.newDetail?.element?.length>0?detailData.selectDetail.newDetail?.element:detailData.selectDetail.trims || null
+ }
+ }
+ console.log(otherData,'=======',detailData.selectDetail)
+ return otherData
+ }
+ const uploadElement = async ()=>{//取出画布数据更新到detail
+ if(detailData.isEditPattern.value == 'canvasEditor'){
+ // await detailDom.canvasBox.saveCanvas()
+ const allInfo = await (detailDom.canvasBox as any).getCanvasElement()
+ console.log(allInfo,'allInfo')
+ if(allInfo.trims?.length > 0){
+ // detailData.selectDetail.trims.prints = allInfo.trims
+ let value = {
+ data:allInfo.trims,
+ str:'element'
+ }
+ store.commit('DesignDetail/setNewDetail',value)
+ }
+ if(allInfo.prints?.length > 0){
+ // detailData.selectDetail.printObject.prints = allInfo.prints
+ let value = {
+ data:allInfo.prints,
+ str:'print'
+ }
+ store.commit('DesignDetail/setNewDetail',value)
+ }
+ if(allInfo.color?.color?.rgba){
+ let canvasColor = allInfo.color.color
+ let colorData:any = await getColorName(allInfo.color.color?.rgba)
+ let value:any = {
+ data:{
+ hsv:{
+ h:colorData.h,
+ s:colorData.s,
+ v:colorData.v,
+ },
+ name:colorData.name,
+ tcx:colorData.tcx,
+ rgba:canvasColor.rgba,
+ hex:rgbaToHex([canvasColor.rgba.r,canvasColor.rgba.g,canvasColor.rgba.b]),
+ },
+ str:'color'
+ }
+ if(canvasColor.gradient){
+ value.data.gradient = canvasColor.gradient
+ }
+ store.commit('DesignDetail/setNewDetail',value)
+ if(allInfo.color.color.gradient)detailData.selectDetail.color.gradient = allInfo.color.color.gradient
+ if(detailData.currentDetailType == 'color'){
+ detailData.detailLeftColorKey++
+ }
+ }
+ }
+ }
const canvasReload = async ()=>{
if(detailData.isEditPattern.value){
await detailDom.canvasBox.saveCanvas()
}
detailData.canvasKey += 1
}
- let time = null as any
- const handleResize = ()=>{
- clearTimeout(time)
- time = setTimeout(()=>{
- store.commit('DesignDetail/setDesignDetail',detailData.designDetail)
- },1000)
- }
const sketchSysToLibrary = ()=>{//系统sketch添加到library更新library
coverRevocation()
detailDom.detailLeft.sketchSysToLibrary()
@@ -516,11 +657,6 @@ export default defineComponent({
sessionStorage.setItem('revocation', JSON.stringify(revocation));
sessionStorage.setItem('oppositeRevocation',JSON.stringify([]));
}
-
- const addDetail = () =>{
- let addDetails:any = detailDom.addDetails
- addDetails.init(detailData.selectDetail,'')
- }
const setSloganData = (data:any)=>{
detailData.selectDetail.sketchString = data
if(detailData.currentDetailType == 'sketch' && detailData.selectDetail?.newDetail?.sketch){
@@ -528,14 +664,12 @@ export default defineComponent({
}
}
onMounted(()=>{
- window.addEventListener('resize', handleResize);
})
onBeforeUnmount(()=>{
sessionStorage.removeItem('oppositeRevocation')
sessionStorage.removeItem('revocation')
store.commit('DesignDetail/clearDesignDetail')
- window.removeEventListener('resize', handleResize);
})
return{
@@ -553,8 +687,8 @@ export default defineComponent({
canvasReload,
modelOnLoad,
sketchSysToLibrary,
- addDetail,
setSloganData,
+ updateOtherLayers,//更新到画布图层 再canvasInit中执行
}
},
@@ -680,6 +814,24 @@ export default defineComponent({
flex: 1;
flex-direction: column;
overflow: hidden;
+ &.canvas{
+ opacity: 0;
+ position: absolute;
+ flex: auto;
+ width: 35vw;
+ height: 80vh;
+ pointer-events: none;
+ transform: translate(100vw,100vh);
+ }
+ &.active{
+ position: relative;
+ opacity: 1;
+ flex: 1;
+ width: auto;
+ height: auto;
+ pointer-events: auto;
+ transform: translate(0,0);
+ }
}
}
.btn{
diff --git a/src/component/Detail/addDetails.vue b/src/component/Detail/addDetails.vue
deleted file mode 100644
index 47544254..00000000
--- a/src/component/Detail/addDetails.vue
+++ /dev/null
@@ -1,98 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/component/Detail/canvas/index.vue b/src/component/Detail/canvas/index.vue
index 0f6216c7..2d59df2c 100644
--- a/src/component/Detail/canvas/index.vue
+++ b/src/component/Detail/canvas/index.vue
@@ -6,16 +6,15 @@
-
-
![]()
isSketchLoad = true">
-
-
+
isSketchLoad = true">
+
+
+
@@ -82,12 +102,15 @@
-
+
+
+
@@ -106,8 +129,13 @@ import { defineComponent,computed,ref,onMounted,nextTick,watch,toRefs, reactive,
// import setDesignItem from '@/component/Detail/setDesignItem2.vue'
import { useStore } from "vuex";
import { getMousePosition } from "@/tool/mdEvent";
+import { sketchToMask } from "@/tool/util";
+import pingpu from '@/component/Canvas/OverallCanvas/index.vue'
+import RepeatSetting from "./overallSetting/RepeatSetting.vue";
+import { useI18n } from 'vue-i18n'
export default defineComponent({
components:{
+ pingpu,RepeatSetting
},
props: {
type: {
@@ -116,6 +144,7 @@ export default defineComponent({
}
},
setup(props,{emit}) {
+ const { t } = useI18n()
const store = useStore();
const editPrintElementDom = reactive({
imgDom:null as any,
@@ -126,6 +155,15 @@ export default defineComponent({
currentDetailType:computed(()=>store.state.DesignDetail.currentDetailType),
currentPrintElement:computed(()=>store.state.DesignDetail.currentPrintElement),
systemDesignerPercentage:0,
+ overallDetail:{
+ url: '',
+ offsetX: 0, // px
+ offsetY: 0, // px
+ angle: 0, // 角度
+ scale: 100, // %
+ gapX: 0, // px
+ gapY: 0, // px
+ },
printStyleList:{
print:{
single:[],
@@ -215,6 +253,7 @@ export default defineComponent({
path:data.url,
priority:editPrintElementData.printZIndex,
scale,
+ globalCompositeOperation:'',
}
getItemPosition(item)
setItemPosition()
@@ -227,6 +266,7 @@ export default defineComponent({
let scale,location
let style = item.pattern.style
let sketchWH = editPrintElementData.sketchWH.scale
+ let overallDetail = {}
if(item.ifSingle){
scale = [style.width.replace(/px/g,'')/(editPrintElementData.sketchWH.width),(style.height.replace(/px/g,'')/(editPrintElementData.sketchWH.height))]
location = [style.left.replace(/px/g,'')*sketchWH[0],style.top.replace(/px/g,'')*sketchWH[1]]
@@ -237,6 +277,14 @@ export default defineComponent({
scale =[ editPrintElementData.systemDesignerPercentage/100, editPrintElementData.systemDesignerPercentage/100]
// scale = [item.pattern.style.width/item.pattern.style.height,item.pattern.style.height/item.pattern.style.width]
// location = [item.pattern.style.left,item.pattern.style.top]
+ overallDetail = {
+ offsetX: editPrintElementData.overallDetail.offsetX, // px
+ offsetY: editPrintElementData.overallDetail.offsetY, // px
+ angle: editPrintElementData.overallDetail.angle, // 角度
+ scale: editPrintElementData.overallDetail.scale, // %
+ gapX: editPrintElementData.overallDetail.gapX, // px
+ gapY: editPrintElementData.overallDetail.gapY, // px
+ }
}
let value ={
angle : item.pattern.transform.rotateZ,
@@ -249,6 +297,9 @@ export default defineComponent({
path:item.path,
minIOPath:item.minIOPath,
ifSingle:!!item.ifSingle,
+ globalCompositeOperation:'',
+ object:null,
+ // ...overallDetail,
}
return value
}
@@ -316,6 +367,15 @@ export default defineComponent({
editPrintElementData.printStyleList[props.type].single.push(item)
}else{
editPrintElementData.printStyleList[props.type].overall = []
+ editPrintElementData.overallDetail = {
+ url: item.path,
+ offsetX: 0, // px
+ offsetY: 0, // px
+ angle: 0, // 角度
+ scale: 100, // %
+ gapX: 0, // px
+ gapY: 0, // px
+ }
editPrintElementData.printStyleList[props.type].overall.push(item)
}
@@ -337,9 +397,9 @@ export default defineComponent({
if(!editPrintElementData.selectDetail.printObject.prints)return
let state = true
// editPrintElementData.stateOverallSingle = 'single'
- let arr:any = editPrintElementData.selectDetail.printObject.prints
+ let arr:any = editPrintElementData.selectDetail.newDetail?.print || editPrintElementData.selectDetail.printObject.prints
if(props.type == 'element'){
- arr = editPrintElementData.selectDetail.trims.prints
+ arr = editPrintElementData.selectDetail.newDetail?.element || editPrintElementData.selectDetail.trims.prints
}
if(editPrintElementData.selectDetail.newDetail?.[editPrintElementData.currentDetailType]){
arr = editPrintElementData.selectDetail.newDetail[editPrintElementData.currentDetailType]
@@ -384,8 +444,28 @@ export default defineComponent({
single:[],
overall:[],
}
+ if(!editPrintElementData.selectDetail.sketchMask){
+ sketchToMask(newVal).then((res:any)=>{
+ editPrintElementData.selectDetail.sketchMask = res
+ })
+ }
setPosition()
},{immediate: true,})
+ watch(()=>editPrintElementData.stateOverallSingle,(newVal)=>{
+ if(newVal == 'overall'){
+ let overallPrint = editPrintElementData.printStyleList[props.type][editPrintElementData.stateOverallSingle]?.[0]
+ if(!overallPrint?.path)return
+ editPrintElementData.overallDetail = {
+ url: overallPrint.path,
+ offsetX: overallPrint.offsetX || 0, // px
+ offsetY: overallPrint.offsetY || 0, // px
+ angle: overallPrint.angle || 0, // 角度
+ scale: overallPrint.scale || 100, // %
+ gapX: overallPrint.gapX || 0, // px
+ gapY: overallPrint.gapY || 0, // px
+ }
+ }
+ })
//设置移动
const itemMoveMousedown = (index:number,event:any)=>{
if (event.target.tagName === 'IMG' || event.target.nodeName === 'IMG')return
@@ -738,6 +818,20 @@ export default defineComponent({
collItemSize.prentWidth = (collItemSize.padding + remValue) * elArr.length + 'px'
moveItem()
}
+ const inputFillAngle = (angle:any)=>{
+ editPrintElementData.overallDetail.angle = angle
+ }
+ const inputFillOffset = (offset:any)=>{
+ editPrintElementData.overallDetail.offsetX = offset.left
+ editPrintElementData.overallDetail.offsetY = offset.top
+ }
+ const inputFillScale = (scale:any)=>{
+ editPrintElementData.overallDetail.scale = scale
+ }
+ const inputFill_Gap = (x:any,y:any)=>{
+ editPrintElementData.overallDetail.gapX = x
+ editPrintElementData.overallDetail.gapY = y
+ }
onMounted(()=>{
if(props.type == 'element'){
editPrintElementData.stateOverallSingle = 'single'
@@ -747,6 +841,7 @@ export default defineComponent({
previewDetailPrintData()
})
return{
+ t,
getMousePosition,
...toRefs(editPrintElementDom),
...toRefs(editPrintElementData),
@@ -760,6 +855,10 @@ export default defineComponent({
clearOverall,
designMousedown,
navDelete,
+ inputFillAngle,
+ inputFillOffset,
+ inputFillScale,
+ inputFill_Gap,
}
},
directives:{
@@ -983,7 +1082,13 @@ export default defineComponent({
// height: 100%;
max-width: 100%;
// width: 100%;
-
+ &.designOpenrtion_sketchMask{
+ position: absolute;
+ z-index: 3;
+ top: 0;
+ left: 0;
+ pointer-events: none;
+ }
}
.designOpenrtion_sketch_mask{
z-index: 2;
@@ -1013,8 +1118,13 @@ export default defineComponent({
}
}
}
+ .designOpenrtion_pingpu{
+ width: 100%;
+ height: 100%;
+ z-index: 2;
+ }
.designOpenrtion_btn{
- z-index: 3;
+ z-index: 99;
>div{
width: 100%;
height: 100%;
diff --git a/src/component/Detail/detailRight/overallSetting/RepeatSetting.vue b/src/component/Detail/detailRight/overallSetting/RepeatSetting.vue
new file mode 100644
index 00000000..b2f4f3c3
--- /dev/null
+++ b/src/component/Detail/detailRight/overallSetting/RepeatSetting.vue
@@ -0,0 +1,124 @@
+
+
+
+
{{ t("Canvas.angle") }}
+
emit('inputFillAngle', e)"
+ />
+
+
+
+ {{ t("Canvas.scale") }}
+
+
+
+
+ Gap X
+ emit('inputFill_Gap', e, gapY)"
+ @change="(e) => emit('changeFill_Gap', e, gapY)"
+ />
+
+
+
+ Gap Y
+ emit('inputFill_Gap', gapX, e)"
+ @change="(e) => emit('changeFill_Gap', gapX, e)"
+ />
+
+
+
+ {{ t("Canvas.offset") }}
+ emit('inputFillOffset', e)"
+ @change="(e) => emit('changeFillOffset', e)"
+ />
+
+
+
+
+
+
+
diff --git a/src/component/Detail/detailRight/overallSetting/tools/AngleTool.vue b/src/component/Detail/detailRight/overallSetting/tools/AngleTool.vue
new file mode 100644
index 00000000..c024a38e
--- /dev/null
+++ b/src/component/Detail/detailRight/overallSetting/tools/AngleTool.vue
@@ -0,0 +1,122 @@
+
+
+
+
+
+
+
diff --git a/src/component/Detail/detailRight/overallSetting/tools/MySelect.vue b/src/component/Detail/detailRight/overallSetting/tools/MySelect.vue
new file mode 100644
index 00000000..146a7d8d
--- /dev/null
+++ b/src/component/Detail/detailRight/overallSetting/tools/MySelect.vue
@@ -0,0 +1,66 @@
+
+
+ {{ v.label }}
+
+
+
+
diff --git a/src/component/Detail/detailRight/overallSetting/tools/OffsetTool.vue b/src/component/Detail/detailRight/overallSetting/tools/OffsetTool.vue
new file mode 100644
index 00000000..00288da3
--- /dev/null
+++ b/src/component/Detail/detailRight/overallSetting/tools/OffsetTool.vue
@@ -0,0 +1,190 @@
+
+
+
+
+
+
+
diff --git a/src/component/Detail/detailRight/overallSetting/tools/Slider.vue b/src/component/Detail/detailRight/overallSetting/tools/Slider.vue
new file mode 100644
index 00000000..d3de2145
--- /dev/null
+++ b/src/component/Detail/detailRight/overallSetting/tools/Slider.vue
@@ -0,0 +1,160 @@
+
+
+
+
+
+
+
diff --git a/src/component/Detail/model/index.vue b/src/component/Detail/model/index.vue
index 79cf2097..585d1ec5 100644
--- a/src/component/Detail/model/index.vue
+++ b/src/component/Detail/model/index.vue
@@ -4,9 +4,9 @@
-
$emit('canvasReload')" @addSketch="()=>$emit('addSketch')" @sketchSysToLibrary="()=>$emit('sketchSysToLibrary')" @deleteItem="deleteItem">
+
$emit('canvasReload')" @addSketch="()=>$emit('addSketch')" @sketchSysToLibrary="()=>$emit('sketchSysToLibrary')" @deleteItem="deleteItem">
-
+
@@ -14,7 +14,7 @@
-
$emit('addDetail')">
+
@@ -51,7 +51,7 @@ export default defineComponent({
components:{
position,modelNav
},
- emits:['detailEdit','canvasReload','addSketch','revocation','oppositeRevocation','modelOnLoad','sketchSysToLibrary','addDetail'],
+ emits:['detailEdit','canvasReload','addSketch','revocation','oppositeRevocation','modelOnLoad','sketchSysToLibrary'],
setup(props,{emit}) {
const {t} = useI18n()
const store = useStore();
@@ -68,36 +68,40 @@ export default defineComponent({
const getDetailListDom = reactive({
libraryList:null as any,
position:null as any,
+ modelindexRight:null as any,
+ modelNav:null as any,
})
const getSubmitData = (value:any,boolean)=>{
return getDetailListDom.position.getSubmitData(value,boolean)
}
const showDesignImgDetail = (str:any)=>{
- new Promise((resolve, reject) => {
- if(
- getDetailListData.isEditPattern.value&&
- detailData?.getCanvasIfEdit?.fun&&detailData?.getCanvasIfEdit?.fun() > 0
- ){
- Modal.confirm({
- title: t('collectionModal.jsContent2'),
- icon: createVNode(ExclamationCircleOutlined),
- okText: 'Yes',
- cancelText: 'No',
- mask:false,
- centered:true,
- onOk() {
- resolve(true)
- emit('detailEdit',str)
- },
- onCancel(){
- resolve(false)
- }
- });
- }else{
- resolve(true)
- emit('detailEdit',str)
- }
- })
+ emit('detailEdit',str)
+
+ // new Promise((resolve, reject) => {
+ // if(
+ // getDetailListData.isEditPattern.value&&
+ // detailData?.getCanvasIfEdit?.fun&&detailData?.getCanvasIfEdit?.fun() > 0
+ // ){
+ // Modal.confirm({
+ // title: t('collectionModal.jsContent2'),
+ // icon: createVNode(ExclamationCircleOutlined),
+ // okText: 'Yes',
+ // cancelText: 'No',
+ // mask:false,
+ // centered:true,
+ // onOk() {
+ // resolve(true)
+ // emit('detailEdit',str)
+ // },
+ // onCancel(){
+ // resolve(false)
+ // }
+ // });
+ // }else{
+ // resolve(true)
+ // emit('detailEdit',str)
+ // }
+ // })
}
const deleteItem = ()=>{
setRevocation()
@@ -117,22 +121,29 @@ export default defineComponent({
}
let time = null as any
- const handleResize = ()=>{
+ const handleResize = ()=>{
clearTimeout(time)
time = setTimeout(()=>{
store.commit('DesignDetail/setDesignDetail',getDetailListData.designDetail)
- getDetailListDom.position.updataPosition()
-
- },1000)
+ getDetailListDom.position?.updataPosition?.()
+ getDetailListDom.modelNav?.setItemPosition?.()
+ getDetailListDom.position?.updateRect?.()
+ },500)
}
const setBack = ()=>{
- emit('detailEdit')
+ showDesignImgDetail(getDetailListData.isEditPattern.value)
}
+ let observers = null as any
onMounted(()=>{
- window.addEventListener('resize', handleResize);
+ observers = new ResizeObserver(entries => {
+ for (let entry of entries) {
+ handleResize()
+ }
+ });
+ observers.observe(getDetailListDom.modelindexRight);
})
onBeforeUnmount(()=>{
- window.removeEventListener('resize', handleResize);
+ observers.disconnect();
})
return{
...toRefs(detailData),
diff --git a/src/component/Detail/model/modelNav.vue b/src/component/Detail/model/modelNav.vue
index 0b94e180..67398f72 100644
--- a/src/component/Detail/model/modelNav.vue
+++ b/src/component/Detail/model/modelNav.vue
@@ -268,17 +268,8 @@ export default defineComponent({
let allPostition = store.state.Workspace.workspaceAllPosition
return allPostition.find(item => item.value === type)?.name
}
- let observers = null as any
- onMounted(()=>{
- observers = new ResizeObserver(entries => {
- for (let entry of entries) {
- setItemPosition()
- }
- });
- observers.observe(detailData.modelNavBox);
- })
+
onBeforeUnmount(()=>{
- observers.disconnect();
})
return{
...toRefs(detailData),
diff --git a/src/component/Detail/model/modelPosition.vue b/src/component/Detail/model/modelPosition.vue
index 4153bae7..05b9a1d9 100644
--- a/src/component/Detail/model/modelPosition.vue
+++ b/src/component/Detail/model/modelPosition.vue
@@ -1,21 +1,17 @@
-
+
![]()
-
![]()
@@ -40,8 +36,10 @@ import { Https } from "@/tool/https";
import { useStore } from "vuex";
import { useI18n } from 'vue-i18n'
import { getMousePosition } from "@/tool/mdEvent";
-import { Modal,message } from 'ant-design-vue';
-import newFollowVue from '@/component/Account/message/newFollow.vue';
+import Vue3Moveable from 'vue3-moveable';
+import Moveable from 'moveable';
+import { parse } from 'vue/compiler-sfc';
+import { scale } from 'echarts/types/src/scale/helper.js';
export default defineComponent({
components:{
},
@@ -75,10 +73,7 @@ export default defineComponent({
imgDom:null as any,
direction:'',
})
- watch(()=>selectItem.selectDetail,(newValue,oldValue)=>{
- if(!newValue && newValue?.id == oldValue?.id)return
- selectItem.imgDomIndex = detailData.frontBack.front.findIndex((item:any)=>item.id == newValue.id)
- },{immediate: true,})
+
watch(()=>detailData.frontBack?.body?.path,(newVal)=>{
setPrintSize()
})
@@ -99,7 +94,6 @@ export default defineComponent({
if(entries[0].contentRect.width == 0)return
detailData.observerWH.width = Math.floor(entries[0].contentRect.width)
detailData.observerWH.height = Math.floor(entries[0].contentRect.height)
- console.log(detailData.observerWH)
})
detailData.observer.observe(dom)
@@ -131,6 +125,7 @@ export default defineComponent({
}
for (const key in detailData.frontBack.back[index].style) {
if(key == 'zIndex')return
+ if(key == 'transform')return
let value = detailData.frontBack.back[index].style[key]
if(typeof value !== 'number'){
value = value.replace('px','')
@@ -143,6 +138,7 @@ export default defineComponent({
});
setTimeout(() => {
emit('modelOnLoad')
+ initMoveableForSelected()
},500);
};
img.src = detailData.frontBack?.body?.path;
@@ -150,203 +146,280 @@ export default defineComponent({
}
const getDetailListDom = reactive({
libraryList:null as any,
+ moveableContainer:null as any,//控件层
})
-
- //设置尺寸
- const itemSizeMousedown = (direction:any,event:any)=>{
- selectItem.direction = direction
- selectItem.imgDom = document.getElementsByClassName('molepositon')[0].getElementsByClassName("detail_modal_item_front")[selectItem.imgDomIndex]
- detailData.frontBack.front[selectItem.imgDomIndex].designOpenrtionBtn = true
- let imgDomWH = selectItem.imgDom.getBoundingClientRect()
- let li = (document.getElementsByClassName('molepositon')[0].getElementsByClassName("designOpenrtion_btn_top")[0] as any).offsetWidth/2
- if(selectItem.direction == 'right' || selectItem.direction == 'bottom'){
- detailData.frontBack.front[selectItem.imgDomIndex].centers.left = imgDomWH.x+event.offsetX-li
- detailData.frontBack.front[selectItem.imgDomIndex].centers.top = imgDomWH.y+event.offsetY-li
- }else{
- detailData.frontBack.front[selectItem.imgDomIndex].centers.left = imgDomWH.x+event.offsetX+imgDomWH.width-li
- detailData.frontBack.front[selectItem.imgDomIndex].centers.top = imgDomWH.y+event.offsetY+imgDomWH.height-li
+
+ const elementRefs = ref([]) as any;
+ const moveableInstance = ref(null) as any;
+ const setElementRef = (el, index) => {
+ elementRefs.value[index] = el;
+ };
+ const updateRect = ()=>{
+ setTimeout(() => {
+ moveableInstance.value.updateRect()
+ }, 500);
+ }
+ const initMoveableForSelected = () => {
+ // 销毁旧的实例
+ if(selectItem.imgDomIndex == -1)return
+ if (moveableInstance.value) {
+ moveableInstance.value.destroy();
}
- document.addEventListener('mousemove', sizeMouseMove);
- document.addEventListener('touchmove', sizeTouchmove);
- document.addEventListener('mouseup', sizeMouseup);
- document.addEventListener('touchend', sizeMouseup);
- }
- const sizeMouseMove = (event:any)=>{
- let e = getMousePosition(event,false)
- sizeMouseMoveOperation(e)
- }
- const sizeTouchmove = (event:any)=>{
- let e = getMousePosition(event,true)
- sizeMouseMoveOperation(e)
-
- }
- const sizeMouseup = (e:any)=>{
- detailData.frontBack.front[selectItem.imgDomIndex].style={
- right:'auto',
- left:selectItem.imgDom.offsetLeft+'px',
- bottom:'auto',
- top:selectItem.imgDom.offsetTop+'px',
- height:selectItem.imgDom.offsetHeight+'px',
- width:selectItem.imgDom.offsetWidth+'px',
- zIndex:selectItem.imgDom.style.zIndex,
- // zIndex:selectItem.printZIndex
+ const selectedEl = elementRefs.value[selectItem.imgDomIndex];
+ if (!selectedEl) return;
+ if(!selectedEl.style.left)return
+ moveableInstance.value = new Moveable(getDetailListDom.moveableContainer, {
+ target: selectedEl,
+ draggable: true,
+ scalable: true,
+ rotatable: true,
+ keepRatio: false, // 等比缩放
+ snappable: true,
+ snapThreshold: 5,
+ edge: false,
+ });
+ let startPosition = {//记录初始位置
+ left: 0,
+ top: 0,
}
- // detailData.frontBack.back[selectItem.imgDomIndex].style.zIndex = selectItem.printZIndex
- document.removeEventListener('mousemove',sizeMouseMove)
- document.removeEventListener('touchmove',sizeTouchmove)
- document.removeEventListener('mouseup',sizeMouseup)
- document.removeEventListener('touchend',sizeMouseup)
- //鼠标抬起
- setRevocation()
- }
- let isMove = false//表示是否移动,是否需要在鼠标抬起的时候保存数据
+ moveableInstance.value.on('scaleStart', ({ target, direction }) => {
+ const frontStyle = detailData.frontBack.front[selectItem.imgDomIndex];
+ if (!frontStyle.mirror){
+ let scaleX = frontStyle.style.transform.match(/scaleX\(([-\d.]+)\)/);
+ let scaleY = frontStyle.style.transform.match(/scaleY\(([-\d.]+)\)/);
+ frontStyle.mirror = { x: scaleX[1] == '-1' ? true : false, y: scaleY[1] == '-1' ? true : false };
+ }
+ });
+ moveableInstance.value.on('rotateStart', ({ target, direction }) => {
+ const frontStyle = detailData.frontBack.front[selectItem.imgDomIndex];
+ if (!frontStyle.mirror){
+ let scaleX = frontStyle.style.transform.match(/scaleX\(([-\d.]+)\)/);
+ let scaleY = frontStyle.style.transform.match(/scaleY\(([-\d.]+)\)/);
+ frontStyle.mirror = { x: scaleX[1] == '-1' ? true : false, y: scaleY[1] == '-1' ? true : false };
+ }
+ });
+ moveableInstance.value.on('dragStart', ({ target, clientX, clientY }) => {
+ startPosition = {
+ left:parseFloat(selectedEl.style.left.replace('px','')) || 0,
+ top:parseFloat(selectedEl.style.top.replace('px','')) || 0,
+ }
+ });
+ // 拖拽
+ moveableInstance.value.on('drag', ({ target, beforeTranslate }) => {
+ let x = startPosition.left + beforeTranslate[0]
+ let y = startPosition.top + beforeTranslate[1]
+ detailData.frontBack.front[selectItem.imgDomIndex].style.left = x + 'px'
+ detailData.frontBack.front[selectItem.imgDomIndex].style.top = y + 'px'
+ });
+ const updateElementTransform = (element, rotateDeg = null) => {
+
+ const currentTransform = element.style?.transform || '';
+ // 1. 提取当前的所有rotate
+ const currentRotates = (currentTransform.match(/rotate[XYZ]?\([^)]+\)/g) || []);
+ // 2. 获取除镜像和rotate外的其他所有变换
+ let otherTransforms = currentTransform
+ .replace(/scaleX\(-1\)|scaleY\(-1\)/g, '') // 移除镜像
+ .replace(/rotate[XYZ]?\([^)]+\)/g, '') // 移除rotate
+ .replace(/\s+/g, ' ')
+ .trim();
+ // 3. 构建新transform
+ const transforms = [];
+ // 镜像部分
+ if (element.mirror.x) transforms.push('scaleX(-1)');
+ if (element.mirror.y) transforms.push('scaleY(-1)');
+ if (otherTransforms) transforms.push(otherTransforms);
+ if (rotateDeg !== null) {
+ transforms.push(`rotate(${rotateDeg}deg)`);
+ } else if (currentRotates.length > 0) {
+ transforms.push(...currentRotates);
+ }
+ element.style.transform = transforms.join(' ').trim();
+ };
+
+ moveableInstance.value.on('scale', ({ target, delta, direction }) => {
+ const frontStyle = detailData.frontBack.front[selectItem.imgDomIndex];
+ if (!frontStyle.mirror) frontStyle.mirror = { x: false, y: false };
+
+ const width = parseFloat(frontStyle.style.width);
+ const height = parseFloat(frontStyle.style.height);
+ let left = parseFloat(frontStyle.style.left) || 0;
+ let top = parseFloat(frontStyle.style.top) || 0;
+ let rotation = 0;
+ // 获取原始比例
+ const originalRatio = width / height;
+ if (frontStyle.style.transform) {
+ const transform = frontStyle.style.transform;
+ const match = transform.match(/rotate\(([-\d.]+)deg\)/);
+ if (match) {
+ rotation = parseFloat(match[1]);
+ }
+ }
+ // 根据旋转角度重新计算控制点的方向
+ function getAdjustedCorner(originalCorner, rotationAngle) {
+ const angleRad = rotationAngle * (Math.PI / 180);
+ const cosA = Math.cos(angleRad);
+ const sinA = Math.sin(angleRad);
+ const newX = originalCorner.x * cosA - originalCorner.y * sinA;
+ const newY = originalCorner.x * sinA + originalCorner.y * cosA;
+ const threshold = 0.5;
+ return {
+ x: Math.abs(newX) > threshold ? (newX > 0 ? 1 : -1) : 0,
+ y: Math.abs(newY) > threshold ? (newY > 0 ? 1 : -1) : 0
+ };
+ }
+
+ if (rotation !== 0) {
+ direction = getAdjustedCorner({x: direction[0], y: direction[1]}, rotation);
+ direction = [direction.x, direction.y];
+ }
+
+ // 判断是否是对角线方向(需要等比缩放)
+ const isDiagonal = Math.abs(direction[0]) === 1 && Math.abs(direction[1]) === 1;
+
+ // 处理轴缩放,包含镜像翻转逻辑
+ const processAxis = (axis, val, deltaVal, dir, originalPosition, originalSize, keepRatio = false, otherAxisResult = null) => {
+ let newVal = val * deltaVal;
+ const mirrorKey = axis === 'width' ? 'x' : 'y';
+ const isWidth = axis === 'width';
+
+ // 检查是否需要镜像翻转(当值小于等于0时)
+ if (newVal <= 0) {
+ frontStyle.mirror[mirrorKey] = !frontStyle.mirror[mirrorKey];
+ newVal = Math.abs(newVal);
+
+ updateElementTransform(frontStyle);
+
+ // 镜像翻转后,位置需要根据原始锚点调整
+ if (dir === -1) {
+ // 从左上/右上缩放时,位置保持不变
+ return {
+ newVal,
+ adjustPos: originalPosition,
+ shouldFlip: true
+ };
+ } else {
+ // 从左下/右下缩放时,位置需要调整
+ const newPosition = originalPosition + (originalSize - newVal) * (frontStyle.mirror[mirrorKey] ? -1 : 1);
+ return {
+ newVal,
+ adjustPos: newPosition,
+ shouldFlip: true
+ };
+ }
+ }
+ const shouldMove = (!frontStyle.mirror[mirrorKey] && dir === -1) ||
+ (frontStyle.mirror[mirrorKey] && dir === 1);
+ if (keepRatio && otherAxisResult) {
+ newVal = isWidth ?
+ otherAxisResult.newVal * originalRatio :
+ otherAxisResult.newVal / originalRatio;
+ }
+ let adjustPos;
+ if (shouldMove) {
+ adjustPos = originalPosition - (newVal - originalSize);
+ } else {
+ adjustPos = originalPosition;
+ }
+ return {
+ newVal,
+ adjustPos,
+ shouldFlip: false
+ };
+ };
+
+ // 自由缩放
+ const widthResult = processAxis('width', width, delta[0], direction[0], left, width);
+ const heightResult = processAxis('height', height, delta[1], direction[1], top, height);
+
+ frontStyle.style.left = widthResult.adjustPos + 'px';
+ frontStyle.style.top = heightResult.adjustPos + 'px';
+ frontStyle.style.width = widthResult.newVal + 'px';
+ frontStyle.style.height = heightResult.newVal + 'px';
+ // }
+ });
+
+ // 旋转
+ moveableInstance.value.on('rotate', ({ target, beforeRotate }) => {
+ let frontStyle = detailData.frontBack.front[selectItem.imgDomIndex];
+ // 确保镜像状态存在
+ if (!frontStyle.mirror) frontStyle.mirror = { x: false, y: false };
+
+ const { x: isMirroredX, y: isMirroredY } = frontStyle.mirror;
+
+ // 计算实际旋转角度
+ let actualRotate = beforeRotate;
+
+ // 关键逻辑:当镜像状态不同时(一个true一个false),旋转方向反转
+ if (isMirroredX !== isMirroredY) {
+ actualRotate = -beforeRotate;
+ }
+
+ // 确保角度在 0-360 度范围内
+ actualRotate = actualRotate % 360;
+
+ // 如果角度为负数,转换为正数
+ if (actualRotate < 0) {
+ actualRotate += 360;
+ }
+
+ // 确保角度在 [0, 360) 范围内
+ actualRotate = ((actualRotate % 360) + 360) % 360;
+
+ updateElementTransform(frontStyle, actualRotate.toFixed(2));
+ });
+ // 调整大小
+ moveableInstance.value.on('resize', ({ target, width, height }) => {
+ // console.log(width, height)
+ // detailData.frontBack.front[selectItem.imgDomIndex].style.width = width
+ // detailData.frontBack.front[selectItem.imgDomIndex].style.height = height
+ });
+ moveableInstance.value.on('dragEnd', ({ target, clientX, clientY }) => {
+ startPosition = {
+ left:0,
+ top:0,
+ }
+ upDataDetail()
+ });
+ moveableInstance.value.on('scaleEnd', () => {
+ upDataDetail()
+ });
+ moveableInstance.value.on('rotateEnd', () => {
+ upDataDetail()
+ });
+ };
+ watch(()=>selectItem.selectDetail,(newValue,oldValue)=>{
+ if(!newValue && newValue?.id == oldValue?.id)return
+ selectItem.imgDomIndex = detailData.frontBack.front.findIndex((item:any)=>item.id == newValue.id)
+ initMoveableForSelected()
+ },{immediate: true,})
+
const setRevocation = ()=>{
- if(!isMove)return
- isMove = false
let frontBack = JSON.parse(JSON.stringify(detailData.frontBack))
- console.log(frontBack)
let revocation:any = JSON.parse((sessionStorage.getItem("revocation") as any))
revocation.push({designData:null,position:frontBack})
sessionStorage.setItem('revocation', JSON.stringify(revocation));
-
}
- const sizeMouseMoveOperation = (e:any)=> {
- isMove = true
- let imgDomWH = selectItem.imgDom.getBoundingClientRect()
- let parentNode =selectItem.imgDom.parentNode
- let width = imgDomWH.width
- let height = imgDomWH.height
- let w,h
- let num = height/width
- //判断移动四个边
- if(selectItem.direction == 'right'){
- w = (e.clientX - detailData.frontBack.front[selectItem.imgDomIndex].centers.left)
- h = (e.clientX - detailData.frontBack.front[selectItem.imgDomIndex].centers.left)*num
- width = w+'px'
- // height = w*num+'px'
- }else if(selectItem.direction == 'top'){
- num = width/height
- detailData.frontBack.front[selectItem.imgDomIndex].style.top = 'auto'
- // this.printStyleList[selectItem.imgDomIndex].style.left = 'auto'
- detailData.frontBack.front[selectItem.imgDomIndex].style.bottom = parentNode.offsetHeight -imgDomWH.height - selectItem.imgDom.offsetTop+'px'
- w = (e.clientX - detailData.frontBack.front[selectItem.imgDomIndex].centers.left)*num
- h = (detailData.frontBack.front[selectItem.imgDomIndex].centers.top - e.clientY)
-
- height = h+'px'
- // width = h*num+'px'
- }else if(selectItem.direction == 'bottom'){
- num = width/height
- h = (e.clientY - detailData.frontBack.front[selectItem.imgDomIndex].centers.top)
- height = h+'px'
- // width = h*num+'px'
- }else if(selectItem.direction == 'left'){
- detailData.frontBack.front[selectItem.imgDomIndex].style.left = 'auto'
- detailData.frontBack.front[selectItem.imgDomIndex].style.right = parentNode.offsetWidth -imgDomWH.width - selectItem.imgDom.offsetLeft+'px'
- w = (detailData.frontBack.front[selectItem.imgDomIndex].centers.left - e.clientX)
-
- width = w+'px'
- // height = w*num+'px'
- }
- //判断尺寸是否到边
- detailData.frontBack.front[selectItem.imgDomIndex].style.width = width
- detailData.frontBack.front[selectItem.imgDomIndex].style.height = height
- }
- // 设置移动
- const mouseMove = (event:any)=>{
- let e = getMousePosition(event,false)
- mouseMoveOperation(e)
- }
- const touchmove=(event:any)=>{
- let e = getMousePosition(event,true)
- mouseMoveOperation(e)
- }
- const mouseup = (e:any)=> {
- document.removeEventListener('mousemove',mouseMove)
- document.removeEventListener('touchmove',touchmove)
- document.removeEventListener('mouseup',mouseup)
- document.removeEventListener('touchend',mouseup)
- ///鼠标抬起
+ const upDataDetail = async ()=>{
+ //同步到selectDetail数据中,
+ // getDetailListData.designDetail
+ let {scale,offset,priority,transpose,rotate,position,imageSize} = await getSubmitData(selectItem.selectDetail,false)
+ selectItem.selectDetail.layersObject[0].scale = scale
+ selectItem.selectDetail.layersObject[1].scale = scale
+ selectItem.selectDetail.layersObject[0].offset = offset
+ selectItem.selectDetail.layersObject[1].offset = offset
+ selectItem.selectDetail.layersObject[0].priority = priority
+ selectItem.selectDetail.layersObject[1].priority = priority
+ selectItem.selectDetail.layersObject[0].rotate = rotate
+ selectItem.selectDetail.layersObject[1].rotate = rotate
+ selectItem.selectDetail.layersObject[0].transpose = transpose
+ selectItem.selectDetail.layersObject[1].transpose = transpose
+ selectItem.selectDetail.layersObject[0].position = position
+ selectItem.selectDetail.layersObject[1].position = position
+ selectItem.selectDetail.layersObject[0].imageSize = imageSize
+ selectItem.selectDetail.layersObject[1].imageSize = imageSize
setRevocation()
}
- const mouseMoveOperation = (e:any)=>{
- isMove = true
- let imgDomWH = selectItem.imgDom.getBoundingClientRect()
- let parentNode = document.getElementsByClassName('molepositon')[0].getElementsByClassName("designOpenrtion_imgMask")[0].getBoundingClientRect()
- let x = (e.clientX - detailData.frontBack.front[selectItem.imgDomIndex].centers.left)+'px'
- let y = ( e.clientY - detailData.frontBack.front[selectItem.imgDomIndex].centers.top)+'px'
- detailData.frontBack.front[selectItem.imgDomIndex].style.left = x
- detailData.frontBack.front[selectItem.imgDomIndex].style.top = y
- }
- const clothesOpenActive = (index:number)=>{
- // this.designItemDetail.clothes.forEach((item)=>{
- // item.clothesOpenItem = false
- // })
- // if(index != -1){
- // this.designItemDetail.clothes[index].clothesOpenItem = true
- // }
- }
- const itemMoveMousedown = async (index:any,e:any)=>{
- if(detailData.selectDetail.id != detailData.frontBack.front[index].id)return
- let isModal = false
- await new Promise((resolve, reject) => {
- // if(
- // detailData.isEditPattern.value &&
- // selectItem.selectDetail?.id &&
- // (detailData.frontBack.front[index].id != selectItem.selectDetail.id)
- // ){
- // isModal = true
- // Modal.confirm({
- // title: t('collectionModal.jsContent2'),
- // icon: createVNode(ExclamationCircleOutlined),
- // okText: 'Yes',
- // cancelText: 'No',
- // mask:false,
- // centered:true,
- // onOk() {
- // resolve(true)
- // isOpen = true
- // },
- // onCancel(){
- // resolve(false)
- // isOpen = false
- // }
- // });
- // }else{
- // if(detailData.frontBack.front[index].id != selectItem.selectDetail.id){
- // isOpen = true
- // }
- // resolve(true)
- // isModal = false
- // }
- resolve(true)
- }).then((rv)=>{
- })
- // emit('canvasReload')
- // store.commit('DesignDetail/setDesignColthes',detailData.frontBack.front[index].id)
- if(isModal)return
- store.commit('DesignDetail/setDesignColthes',detailData.frontBack.front[index].id)
- selectItem.imgDomIndex = index
- detailData.frontBack.front.forEach((v:any)=>{
- v.designOpenrtionBtn = false
- })
- clothesOpenActive(index)
- let event = e||window.event
- selectItem.imgDom = document.getElementsByClassName('molepositon')[0].getElementsByClassName("detail_modal_item_front")[selectItem.imgDomIndex]
- detailData.frontBack.front[index].designOpenrtionBtn = true
- // detailData.frontBack.front[index].style.zIndex = selectItem.printZIndex++
- // detailData.frontBack.back[index].style.zIndex = selectItem.printZIndex
- let imgDomWH = selectItem.imgDom.getBoundingClientRect()
- let left = Number(detailData.frontBack.front[index].style.left.replace(/px/g,''))
- let top = Number(detailData.frontBack.front[index].style.top.replace(/px/g,''))
- detailData.frontBack.front[index].centers.left = imgDomWH.x+event.offsetX-left
- detailData.frontBack.front[index].centers.top = imgDomWH.y+event.offsetY-top
-
- document.addEventListener('mousemove', mouseMove);
- document.addEventListener('touchmove', touchmove);
- document.addEventListener('mouseup', mouseup);
- document.addEventListener('touchend', mouseup);
- }
const sort = (arr:any)=>{
arr.sort((a:any, b:any) => {
var a_num = a.style.zIndex;
@@ -355,7 +428,7 @@ export default defineComponent({
});
return arr
}
- const getSubmitData = (value:any,isNoComputed)=>{
+ const getSubmitData = async (value:any,isNoComputed)=>{
let parentNode = document.getElementsByClassName('molepositon')[0].getElementsByClassName("designOpenrtion_imgMask")[0].getBoundingClientRect()
if(!detailData.frontBack?.body?.layersObject?.[0]?.imageSize || isNoComputed){
return{
@@ -365,6 +438,17 @@ export default defineComponent({
}
}
let ratio = detailData.frontBack.body.layersObject[0].imageSize[0]/parentNode.width
+
+ let scale = 0
+ let dom:any = document.querySelector('.molepositon .perview_img')
+ const img = new Image();
+ img.src = detailData.frontBack?.body?.path;
+ await new Promise
((resolve, reject) => {
+ img.onload = () => {
+ scale = dom.parentNode.offsetWidth / img.width
+ resolve()
+ };
+ })
// let arr:any = sort(detailData.frontBack.front)
let arr:any = sort(JSON.parse(JSON.stringify(detailData.frontBack.front)))
let num = 10
@@ -377,6 +461,8 @@ export default defineComponent({
priority:'',
maskUrl:'',
maskMinioUrl:'',
+ position:null,
+ imageSize:null,
}
let state = false
for (let index = 0; index < arr.length; index++) {
@@ -384,13 +470,27 @@ export default defineComponent({
state = true
let y = ((arr[index]?.style?.top.replace(/px/g,'')*ratio).toFixed(0) as any - arr[index]?.position[0])
let x = ((arr[index]?.style?.left.replace(/px/g,'')*ratio).toFixed(0) as any - arr[index]?.position[1])
+ let positionX = Number((arr[index]?.style?.left.replace(/px/g,'')/scale)).toFixed(2)
+ let positionY = Number((arr[index]?.style?.top.replace(/px/g,'')/scale)).toFixed(2)
+ let imageSizeW = Number((arr[index]?.style?.width.replace(/px/g,'')/scale)).toFixed(2)
+ let imageSizeH = Number((arr[index]?.style?.height.replace(/px/g,'')/scale)).toFixed(2)
+
let scaleWidth = arr[index]?.imageSize?Number(((arr[index]?.style?.width.replace(/px/g,'')*ratio)/(arr[index]?.imageSize[0]/arr[index].scale[0])).toFixed(2)):1
let scaleHeight = arr[index]?.imageSize?Number(((arr[index]?.style?.height.replace(/px/g,'')*ratio)/(arr[index]?.imageSize[1]/arr[index].scale[1])).toFixed(2)):1
// let widthScale = (arr[index].style.width.replace(/px/g,'')/arr[index].style.height.replace(/px/g,'')).toFixed(2)
+
+ let transformStr = arr[index]?.style?.transform
+ let scaleX = transformStr.match(/scaleX\(([-\d.]+)\)/)
+ let scaleY = transformStr.match(/scaleY\(([-\d.]+)\)/)
+ let rotate = transformStr.match(/rotate\(([-\d.]+)deg\)/);
+ data.transpose = [parseFloat(scaleX?.[1] || 1),parseFloat(scaleY?.[1] || 1)]
+ data.rotate = parseFloat(rotate?.[1] || 0)
data.scale = [scaleWidth,scaleHeight]
let top = y == 0 ? value.layersObject[0].offset[1]:y+value.layersObject[0].offset[1]
let left = x == 0 ? value.layersObject[0].offset[0]:x+value.layersObject[0].offset[0]
data.offset = [left?left:0,top?top:0]
+ data.position = [positionY,positionX]
+ data.imageSize = [imageSizeW,imageSizeH]
// data.offset = [left?left:0,top?top:0]
data.maskUrl = arr[index].maskUrl
data.maskMinioUrl = arr[index].maskMinioUrl
@@ -410,15 +510,6 @@ export default defineComponent({
}
const deleteNav = ()=>{
- }
- const setpitch = (item:any,index:any)=>{
- detailData.frontBack.front.forEach((v:any)=>{
- v.designOpenrtionBtn = false
- })
- detailData.frontBack.front[index].designOpenrtionBtn = true
- // detailData.frontBack.front[index].style.zIndex = selectItem.printZIndex++
- // detailData.frontBack.back[index].style.zIndex = selectItem.printZIndex
- clothesOpenActive(index)
}
const updataPosition = ()=>{
let url = detailData.frontBack?.body?.path
@@ -431,10 +522,12 @@ export default defineComponent({
detailData.frontBack.front.forEach((item:any,index:number) => {
for (const key in item.style) {
if(key == 'zIndex')return
+ if(key == 'transform')return
item.style[key] = item.style[key]*sacle+'px'
}
for (const key in detailData.frontBack.back[index].style) {
if(key == 'zIndex')return
+ if(key == 'transform')return
detailData.frontBack.back[index].style[key] = detailData.frontBack.back[index].style[key]*sacle+'px'
}
});
@@ -445,20 +538,22 @@ export default defineComponent({
if (detailData.observer) {
detailData.observer.disconnect()
}
+ if (moveableInstance.value) {
+ moveableInstance.value.destroy();
+ }
})
return{
...toRefs(detailData),
...toRefs(selectItem),
...toRefs(getDetailListDom),
-
+ setElementRef,
+
setPrintSize,
- itemSizeMousedown,
- itemMoveMousedown,
deleteNav,
- setpitch,
getSubmitData,
getMousePosition,
updataPosition,
+ updateRect,
}
},
@@ -541,6 +636,11 @@ export default defineComponent({
}
}
}
+ .moveableContainer{
+ :deep(.moveable-origin){
+ opacity: 0;
+ }
+ }
> .designOpenrtion_imgMask{
width: auto;
height: auto;
@@ -561,10 +661,15 @@ export default defineComponent({
position: absolute;
top: 0;
}
+
.detail_modal_item_front,.designOpenrtion_print{
z-index: 2;
height: 100%;
width: 100%;
+ pointer-events: none;
+ &.active{
+ pointer-events: auto;
+ }
img{
width: 100%;
// height: ;
@@ -583,94 +688,6 @@ export default defineComponent({
.designOpenrtion_print{
z-index: 1 !important;
}
- > .designOpenrtion_btnBox{
- z-index: 99;
- width: 100%;
- height: 100%;
- left: 0;
- ul{
- list-style: none;
- // width: 100%;
- // height: 100%;
- position: absolute;
- top: 0;
- left: 0;
- box-sizing: border-box;
- border: 2px solid rgb(20, 188, 255);
- padding: 0;
- -webkit-user-drag: none;
- user-select:none;
- opacity: 0;
- margin: 0;
-
- li{
- cursor: pointer;
- // border-radius: 50%;
- width: calc(2rem*1.2);
- height: calc(2rem*1.2);
- background-color: rgb(20, 188, 255);
- position: absolute;
- pointer-events: none;
- }
- &.active{
- opacity: 1;
- z-index: 999 !important;
- li{
- pointer-events: auto;
- }
- }
- .designOpenrtion_btn_top,.designOpenrtion_btn_bottom{
- left: 50%;
- transform: translate(-50%,-50%) ;
- cursor: n-resize;
- }
- .designOpenrtion_btn_top{
- top: 0;
- }
- .designOpenrtion_btn_bottom{
- top: 100%;
- }
- .designOpenrtion_btn_left,.designOpenrtion_btn_right{
- top: 50%;
- transform: translate(-50%,-50%) ;
- cursor: e-resize;
- }
- .designOpenrtion_btn_left{
- left: 0;
- }
- .designOpenrtion_btn_right{
- left: 100%;
- }
- .designOpenrtion_rotote{
- top: 50%;
- left: 50%;
- transform: translate(-50%,-50%);
- width: 0;
- height: 0;
- }
- .designOpenrtion_rotote::after{
- position: absolute;
- content: "";
- background-color: #14bcff;
- width: 2px;
- height: 30px;
- left: 50%;
- bottom: 0;
- transform: translateX(-50%);
- }
- .designOpenrtion_rotote::before{
- position: absolute;
- content: "";
- background-color: #14bcff;
- top: calc(50% - 30px);
- left: 50%;
- transform: translate(-50%,-50%) ;
- width: calc(1.5rem*1.2);
- height: calc(1.5rem*1.2);
- border-radius: 50%;
- }
- }
- }
}
}
\ No newline at end of file
diff --git a/src/component/home/design/collection/more.vue b/src/component/home/design/collection/more.vue
index 153b64e9..3dc0a2fb 100644
--- a/src/component/home/design/collection/more.vue
+++ b/src/component/home/design/collection/more.vue
@@ -132,7 +132,25 @@ export default defineComponent({
url:rv.url,
designType:props.item.resData.designType || props.item.designType,
}
- props.list.unshift(rv)
+ rv.type_ = {
+ type1: "material",
+ type2: props.level1Type
+ }
+ if(props.level1Type == 'Printboard'){
+ let list = props.list.filter((v:any)=> v.type_?.type1 == "material")
+ list.unshift(rv)
+ store.commit("setPrintboardMaterialFiles", list);
+ }else if(props.level1Type == 'Sketchboard'){
+ let list = props.list.filter((v:any)=> v.type_?.type1 == "material")
+ list.unshift(rv)
+ store.commit("setSketchboardMaterialFiles", list);
+ }else if(props.level1Type == 'Moodleboard'){
+ let list = props.list.filter((v:any)=> v.type_?.type1 == "material")
+ list.unshift(rv)
+ store.commit("setMoodleboardMaterialFiles", list);
+ }else{
+ props.list.unshift(rv)
+ }
}
}
).catch(res=>{
diff --git a/src/component/modules/generalMiniCanvas.vue b/src/component/modules/generalMiniCanvas.vue
index 15c579d3..7c8cb384 100644
--- a/src/component/modules/generalMiniCanvas.vue
+++ b/src/component/modules/generalMiniCanvas.vue
@@ -9,7 +9,7 @@
:isBackgroundChangeable="false"
ref="editCanvas">
-
+
{{ $t('exportModel.Save') }}
{{ $t('exportModel.Export') }}
@@ -46,7 +46,11 @@ export default defineComponent({
isSubmitCanvasJSON:{
type:Boolean,
default:false
- }
+ },
+ btnShow:{
+ type:Boolean,
+ default:true
+ },
},
emits:['submitBase64Data','canvasChangeGetJSON'],
setup(props,{emit}) {
@@ -99,6 +103,9 @@ export default defineComponent({
}
}
+ const submitBase64Data = (base64Data)=>{
+ return dataDom.editCanvas.exportImage({isContainBg:true,isContainFixed:true,isCropByBg:true})
+ }
const exportElement = ()=>{
dataDom.editCanvas.exportImage({isContainBg:true,isContainFixed:false,isCropByBg:true}).then((rv)=>{
downloadBase64Image(rv,'canvas')
@@ -174,6 +181,7 @@ export default defineComponent({
canvasInit,
exportElement,
changeCanvas,
+ submitBase64Data,
};
},
data(prop) {
diff --git a/src/router/index.ts b/src/router/index.ts
index 11e44375..5d6eea99 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -418,6 +418,14 @@ const routes: Array
= [
},
component: () => import("@/views/userManual.vue"),
},
+ {
+ path: "/award",
+ name: "award",
+ meta: {
+ enter: "all",
+ },
+ component: () => import("@/views/AwardPage/index.vue"),
+ },
{
path: "/:catchAll(.*)",
redirect: "/404",
diff --git a/src/store/Detail/designDetail.ts b/src/store/Detail/designDetail.ts
index 82b9c575..a5b40f08 100644
--- a/src/store/Detail/designDetail.ts
+++ b/src/store/Detail/designDetail.ts
@@ -1,6 +1,7 @@
import {Module} from 'vuex'
import {RootState} from '../index'
import { forEach } from 'jszip'
+import { transform } from 'typescript'
interface DesignDetail{
designDetail:any,
@@ -59,6 +60,7 @@ const DesignDetail : Module = {
left:v.layersObject[i].position?.[1],
width:v.layersObject[i].imageSize?.[0],
height:v.layersObject[i].imageSize?.[1],
+ transform:`rotate(${v.layersObject[i]?.rotate || 0}deg) scaleX(${v.layersObject[i].transpose?.[0] || 1}) scaleY(${v.layersObject[i].transpose?.[1] || 1})`,
}
v.layersObject[i].centers={
left:0,
@@ -69,7 +71,7 @@ const DesignDetail : Module = {
v.layersObject[i].designOpenrtionBtn = false
if(v.layersObject[i].imageCategory.indexOf("back") == -1){
front[index] = v.layersObject[i]
- // front[index].style.zIndex = v.priority
+ front[index].style.zIndex = v.priority + 10
front[index].id = v.id
front[index].undividedLayer = v.undividedLayer
front[index].undividedLayerWithSinglePrint = v?.undividedLayerWithSinglePrint
@@ -199,6 +201,9 @@ const DesignDetail : Module = {
trims:null,
type:null,
undividedLayer:null,
+ undividedLayer_:null,
+ transpose:[1,1],
+ rotate:0,
undividedLayerWithSinglePrint:null,
}
if(!state.currentDetailType)state.currentDetailType = 'sketch'
@@ -209,6 +214,28 @@ const DesignDetail : Module = {
});
state.selectDetail = data
},
+ canvasPreviewUpdata(state,{type,callBack}){
+ console.log(state.selectDetail,type)
+ // state.selectDetail.newDetail?.print?.forEach((item:any) => {
+ // state.selectDetail.printObject.prints = []
+ // state.selectDetail.printObject.push({
+ // })
+ // });
+ if(type == 'print' || type == 'all')state.selectDetail.printObject.prints = state.selectDetail.newDetail?.print
+ if(type == 'color' || type == 'all')state.selectDetail.color = {
+ ...state.selectDetail.newDetail?.color,
+ ...state.selectDetail.newDetail?.color?.rgba,
+ ...state.selectDetail.newDetail?.color?.hsv,
+ }
+ console.log(state.selectDetail,type,state.selectDetail.newDetail)
+ if(type == 'element' || type == 'all')state.selectDetail.trims.prints = state.selectDetail.newDetail?.element
+ if(type == 'all'){
+ state.selectDetail.newDetail = {}
+ }else{
+ state.selectDetail.newDetail[type] = null
+ }
+ callBack()
+ },
async setPraeview(state,value){//preview
let data = value?.rv || value
let currentType = value?.currentType
@@ -228,7 +255,6 @@ const DesignDetail : Module = {
}else{
id_ = item.id
}
- console.log(id_)
let el:any = document.querySelector('.molepositon .perview_img')
await new Promise((resolve, reject) => {
if(!state.frontBack?.body?.path){
@@ -252,7 +278,8 @@ const DesignDetail : Module = {
left:item.layersObject[i].position?.[1] * scale + 'px',
width:item.layersObject[i].imageSize?.[0] * scale + 'px',
height:item.layersObject[i].imageSize?.[1] * scale + 'px',
- zIndex:v?.style?.zIndex?v.style.zIndex:v.priority?v.priority:state.frontBack.front.length
+ zIndex:v?.style?.zIndex?v.style.zIndex:v.priority?v.priority:state.frontBack.front.length,
+ transform:`rotate(${item.layersObject?.[i]?.rotate || 0}deg) scaleX(${item.layersObject[i].transpose?.[0] || 1}) scaleY(${item.layersObject[i].transpose?.[1] || 1})`,
}
item.layersObject[i].centers={
left:0,
@@ -293,6 +320,8 @@ const DesignDetail : Module = {
detailItem.minIOPath = item.minIOPath
detailItem.scale = [1,1]
detailItem.offset = [0,0]
+ detailItem.transpose = item.transpose || [1,1]
+ detailItem.rotate = item.rotate || 0
detailItem.printObject = item.printObject
detailItem.trims = item.trims
detailItem.type = item.type
diff --git a/src/tool/util.js b/src/tool/util.js
index 8d69b9d0..b8f095c7 100644
--- a/src/tool/util.js
+++ b/src/tool/util.js
@@ -618,6 +618,60 @@ function segmentImage(markerImage,fullImage,size){
}
})
}
+
+/**
+ * 处理PNG图片:透明度转白色,其他颜色转透明
+ * @param {string} sketchImage - 原始图片
+ * @returns {Promise} 处理后的ase64
+ */
+function sketchToMask(sketchImage) {
+ return new Promise((resolve, reject) => {
+ const img = new Image();
+ img.crossOrigin = 'anonymous';
+ img.onload = function() {
+ try {
+ const canvas = document.createElement('canvas');
+ const ctx = canvas.getContext('2d');
+ canvas.width = img.width;
+ canvas.height = img.height;
+ ctx.drawImage(img, 0, 0);
+ const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
+ const data = imageData.data;
+
+ for (let i = 0; i < data.length; i += 4) {
+ const r = data[i];
+ const g = data[i + 1];
+ const b = data[i + 2];
+ const a = data[i + 3];
+ if (a > 0) {
+ data[i] = 0;
+ data[i + 1] = 0;
+ data[i + 2] = 0;
+ data[i + 3] = 0;
+ } else {
+ // 完全透明的像素 -> 纯白色
+ data[i] = 255;
+ data[i + 1] = 255;
+ data[i + 2] = 255;
+ data[i + 3] = 255;
+ }
+ }
+ ctx.putImageData(imageData, 0, 0);
+ const base64 = canvas.toDataURL('image/png');
+ resolve(base64);
+
+ } catch (error) {
+ reject(error);
+ }
+ };
+
+ img.onerror = function() {
+ reject(new Error('图片加载失败'));
+ };
+
+ img.src = sketchImage;
+ });
+}
export {
isEmail,
getUploadUrl,
@@ -640,5 +694,6 @@ export {
setGradual,
calculateGradientCoordinate,
segmentImage,
- UrlToFile
+ UrlToFile,
+ sketchToMask
}
\ No newline at end of file
diff --git a/src/views/AwardPage/index.vue b/src/views/AwardPage/index.vue
new file mode 100644
index 00000000..f04e0d4f
--- /dev/null
+++ b/src/views/AwardPage/index.vue
@@ -0,0 +1,251 @@
+
+
+
+
+
+
+
{{ item.number }}
+
{{ item.label }}
+
+
+
+
+

+
+
Possibilites
+
+
+
+
Bloom Your Creativity
+

+
Theme of 2026
+
+ Where imagination meets innovation, creativity blooms. This theme celebrates AI as
+ a catalyst for fashion design, allowing your vision to flourish beyond traditional
+ boundaries. Let your ideas blossom into extraordinary designs that merge human
+ artistry with artificial intelligence.
+
+
+
+
Design Without Borders
+
+

+
+
Global Opportunity
+
+ Open to visionary designers across the globe. From Seoul to Singapore, New York to
+ Shanghai, we're seeking the next generation of fashion innovators who dare to
+ reimagine the future of design.
+
+
+
+
+
Competition Timeline
+

+
Shaping the Future
+
+
+
+
+
+
+