Merge pull request #101 from JeremyYu-cn/feat-upgrade-vue3

Merge: merge main branch
This commit is contained in:
Jeremy Yu 2024-03-26 20:15:37 +00:00 committed by GitHub
commit 391f9c264f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 141 additions and 107 deletions

1
.gitignore vendored
View File

@ -2,6 +2,7 @@
node_modules node_modules
/dist /dist
config.json config.json
/.vite
screenshot/node_modules/ screenshot/node_modules/
screenshot/dist/ screenshot/dist/

View File

@ -26,9 +26,14 @@ body {
border-style: solid; border-style: solid;
border-color: #e5e7eb; border-color: #e5e7eb;
// font-size: 14px; // font-size: 14px;
scrollbar-width: none; /* 火狐滚动条无法自定义宽度,只能通过此属性使滚动条宽度变细 */ // scrollbar-width: none; /* 火狐滚动条无法自定义宽度,只能通过此属性使滚动条宽度变细 */
-ms-overflow-style: none; /* 隐藏滚动条在IE和Edge两个浏览器中很难更改样式固采取隐藏方式 */ -ms-overflow-style: none; /* 隐藏滚动条在IE和Edge两个浏览器中很难更改样式固采取隐藏方式 */
} }
@-moz-document url-prefix() {
* {
scrollbar-width: none;
}
}
// html ::-webkit-scrollbar { // html ::-webkit-scrollbar {
// display: none; /* Chrome Safari */ // display: none; /* Chrome Safari */
// } // }
@ -40,12 +45,13 @@ body {
} }
&::-webkit-scrollbar-thumb { &::-webkit-scrollbar-thumb {
border-radius: 3px; border-radius: 3px;
background-color: #ccd4de; background-color: #d9dcdf;
cursor: pointer;
// box-shadow: 0 0 1px hsl(0deg 0% 100% / 50%); // box-shadow: 0 0 1px hsl(0deg 0% 100% / 50%);
} }
&::-webkit-scrollbar-track { &::-webkit-scrollbar-track {
background-color: #f0f1f3; // background-color: #f0f1f3;
// background-color: transparent; background-color: transparent;
// border-radius: 3px; // border-radius: 3px;
} }
@ -129,6 +135,7 @@ p {
position: fixed; position: fixed;
z-index: 99999; z-index: 99999;
pointer-events: none; pointer-events: none;
opacity: .9;
} }
.hide { .hide {
opacity: 0 !important; opacity: 0 !important;

View File

@ -2,8 +2,8 @@
* @Author: ShawnPhang * @Author: ShawnPhang
* @Date: 2022-02-22 15:06:14 * @Date: 2022-02-22 15:06:14
* @Description: * @Description:
* @LastEditors: ShawnPhang <site: book.palxp.com> * @LastEditors: ShawnPhang <https://m.palxp.cn>
* @LastEditTime: 2023-07-03 10:10:53 * @LastEditTime: 2024-03-22 16:00:17
*/ */
// import store from '@/store' // import store from '@/store'
// import { getImage } from '../getImgDetail' // import { getImage } from '../getImgDetail'
@ -31,7 +31,6 @@ export default async function(type: string, item: TCommonItemData, data: Record<
setting.width = img.width setting.width = img.width
setting.height = img.height // parseInt(100 / item.value.ratio, 10) setting.height = img.height // parseInt(100 / item.value.ratio, 10)
setting.imgUrl = item.value.url setting.imgUrl = item.value.url
console.log("setting", setting)
} }
if (type === 'mask') { if (type === 'mask') {
setting.mask = item.value.url setting.mask = item.value.url

View File

@ -364,10 +364,13 @@ export default defineComponent({
if (this.resizeTempData) { if (this.resizeTempData) {
this.$store.commit('resize', this.resizeTempData) this.$store.commit('resize', this.resizeTempData)
this.resizeTempData = null this.resizeTempData = null
setTimeout(async () => { // await this.$nextTick()
await this.$nextTick() this.moveable.updateRect()
this.moveable.updateRect() // 线
}, 10) this.$store.commit('setShowMoveable', false)
setTimeout(() => {
this.$store.commit('setShowMoveable', true)
}, 10);
} }
try { try {
if (this.dActiveElement.type === 'w-text') { if (this.dActiveElement.type === 'w-text') {

View File

@ -1,61 +1,61 @@
<template> <template>
<div id="page-design" ref="page_design" :style="{ paddingTop: dPaddingTop + 'px' }"> <div id="main">
<!-- <el-scrollbar> --> <div id="page-design" ref="page_design" :style="{ paddingTop: dPaddingTop + 'px', minWidth: (dPage.width * dZoom) / 100 + 120 + 'px' }" >
<div
id="out-page"
class="out-page"
:style="{
width: (dPage.width * dZoom) / 100 + 120 + 'px',
height: (dPage.height * dZoom) / 100 + 120 + 'px',
opacity: 1 - (dZoom < 100 ? dPage.tag : 0),
}"
>
<slot />
<div <div
:id="pageDesignCanvasId" id="out-page"
class="design-canvas" class="out-page"
:data-type="dPage.type"
:data-uuid="dPage.uuid"
:style="{ :style="{
width: dPage.width + 'px', width: (dPage.width * dZoom) / 100 + 120 + 'px',
height: dPage.height + 'px', height: (dPage.height * dZoom) / 100 + 120 + 'px',
transform: 'scale(' + dZoom / 100 + ')', opacity: 1 - (dZoom < 100 ? dPage.tag : 0),
transformOrigin: (dZoom >= 100 ? 'center' : 'left') + ' top',
backgroundColor: dPage.backgroundColor,
backgroundImage: `url(${dPage?.backgroundImage})`,
backgroundSize: dPage?.backgroundTransform?.x ? 'auto' : 'cover',
backgroundPositionX: (dPage?.backgroundTransform?.x || 0) + 'px',
backgroundPositionY: (dPage?.backgroundTransform?.y || 0) + 'px',
opacity: dPage.opacity + (dZoom < 100 ? dPage.tag : 0),
}" }"
@mousemove="dropOver($event)"
@drop="drop($event)"
@mouseup="drop($event)"
> >
<!-- <grid-size /> --> <slot />
<div
:id="pageDesignCanvasId"
class="design-canvas"
:data-type="dPage.type"
:data-uuid="dPage.uuid"
:style="{
width: dPage.width + 'px',
height: dPage.height + 'px',
transform: 'scale(' + dZoom / 100 + ')',
transformOrigin: (dZoom >= 100 ? 'center' : 'left') + ' top',
backgroundColor: dPage.backgroundColor,
backgroundImage: `url(${dPage?.backgroundImage})`,
backgroundSize: dPage?.backgroundTransform?.x ? 'auto' : 'cover',
backgroundPositionX: (dPage?.backgroundTransform?.x || 0) + 'px',
backgroundPositionY: (dPage?.backgroundTransform?.y || 0) + 'px',
opacity: dPage.opacity + (dZoom < 100 ? dPage.tag : 0),
}"
@mousemove="dropOver($event)"
@drop="drop($event)"
@mouseup="drop($event)"
>
<!-- <grid-size /> -->
<!-- :class="{ <!-- :class="{
layer: true, layer: true,
'layer-active': getIsActive(layer.uuid), 'layer-active': getIsActive(layer.uuid),
'layer-hover': layer.uuid === dHoverUuid || dActiveElement.parent === layer.uuid, 'layer-hover': layer.uuid === dHoverUuid || dActiveElement.parent === layer.uuid,
}" --> }" -->
<component :is="layer.type" v-for="layer in getlayers()" :id="layer.uuid" :key="layer.uuid" :class="['layer', { 'layer-hover': layer.uuid === dHoverUuid || dActiveElement.parent === layer.uuid, 'layer-no-hover': dActiveElement.uuid === layer.uuid }]" :data-title="layer.type" :params="layer" :parent="dPage" :data-type="layer.type" :data-uuid="layer.uuid"> <component :is="layer.type" v-for="layer in getlayers()" :id="layer.uuid" :key="layer.uuid" :class="['layer', { 'layer-hover': layer.uuid === dHoverUuid || dActiveElement.parent === layer.uuid, 'layer-no-hover': dActiveElement.uuid === layer.uuid }]" :data-title="layer.type" :params="layer" :parent="dPage" :data-type="layer.type" :data-uuid="layer.uuid">
<template v-if="layer.isContainer"> <template v-if="layer.isContainer">
<!-- :class="{ <!-- :class="{
layer: true, layer: true,
'layer-active': getIsActive(widget.uuid), 'layer-active': getIsActive(widget.uuid),
'layer-no-hover': dActiveElement.uuid !== widget.parent && dActiveElement.parent !== widget.parent, 'layer-no-hover': dActiveElement.uuid !== widget.parent && dActiveElement.parent !== widget.parent,
'layer-hover': widget.uuid === dHoverUuid, 'layer-hover': widget.uuid === dHoverUuid,
}" --> }" -->
<component :is="widget.type" v-for="widget in getChilds(layer.uuid)" :key="widget.uuid" child :class="['layer', { 'layer-no-hover': dActiveElement.uuid !== widget.parent && dActiveElement.parent !== widget.parent }]" :data-title="widget.type" :params="widget" :parent="layer" :data-type="widget.type" :data-uuid="widget.uuid" /> <component :is="widget.type" v-for="widget in getChilds(layer.uuid)" :key="widget.uuid" child :class="['layer', { 'layer-no-hover': dActiveElement.uuid !== widget.parent && dActiveElement.parent !== widget.parent }]" :data-title="widget.type" :params="widget" :parent="layer" :data-type="widget.type" :data-uuid="widget.uuid" />
</template> </template>
</component> </component>
<!-- <ref-line v-if="dSelectWidgets.length === 0" /> --> <!-- <ref-line v-if="dSelectWidgets.length === 0" /> -->
<!-- <size-control v-if="dSelectWidgets.length === 0" /> --> <!-- <size-control v-if="dSelectWidgets.length === 0" /> -->
</div>
</div> </div>
</div> </div>
<!-- </el-scrollbar> -->
</div> </div>
</template> </template>
@ -333,13 +333,17 @@ function getChilds(uuid: string) {
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
#main {
overflow: auto; position: relative;
}
#page-design { #page-design {
height: 100%; scrollbar-width: none;
min-height: 100%;
// display: flex; // display: flex;
// align-items: center; // align-items: center;
overflow: auto; overflow: auto;
position: relative; position: relative;
width: 100%; // width: 100%;
.out-page { .out-page {
margin: 0 auto; margin: 0 auto;
padding: 60px; padding: 60px;

View File

@ -34,7 +34,7 @@ export const ZoomList: TZoomData[] = [
value: 200, value: 200,
}, },
{ {
text: '最佳尺寸', text: '适应屏幕',
value: -1, value: -1,
// icon: 'icon-best-size', // icon: 'icon-best-size',
}, },

View File

@ -248,10 +248,9 @@ async function autoFixTop() {
const presetPadding = 60 const presetPadding = 60
const el = document.getElementById('out-page') const el = document.getElementById('out-page')
if (!el) return if (!el) return
// const clientHeight = document.body.clientHeight - 54 const clientHeight = window.innerHeight - 54
// const parentHeight = (el.offsetParent as HTMLElement).offsetHeight - 54
const parentHeight = (el.offsetParent as HTMLElement).offsetHeight - 54 let padding = (clientHeight - el.offsetHeight) / 2
let padding = (parentHeight - el.offsetHeight) / 2
if (typeof curAction.value === 'undefined') { if (typeof curAction.value === 'undefined') {
padding += presetPadding / 2 padding += presetPadding / 2
} }

View File

@ -78,23 +78,23 @@ function layerChange(newLayer: Record<string, any>[]) {
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
@color0: #ffffff; // Appears 5 times @color0: #ffffff;
@color1: #999999; // Appears 3 times @color1: #999999;
@color2: #d7d7d7; // Appears 2 times @background-color-transparent: rgba(0,0,0,.08);
#style-panel ::-webkit-scrollbar { #style-panel ::-webkit-scrollbar {
display: none; /* Chrome Safari */ display: none; /* Chrome Safari */
} }
#style-panel { #style-panel {
background-color: @color0; background-color: @color0;
border-left: 1px solid @color2; border-left: 1px solid @background-color-transparent;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%; height: 100%;
position: relative; position: relative;
width: 280px; width: 280px;
.style-tab { .style-tab {
box-shadow: 0px 1px 5px 1px rgba(0, 0, 0, 0.1); box-shadow: 0px 2px 0px 0px rgba(0, 0, 0, 0.1);
display: flex; display: flex;
flex-direction: row; flex-direction: row;
text-align: center; text-align: center;

View File

@ -257,6 +257,11 @@ defineExpose({
.infinite-list { .infinite-list {
height: 100%; height: 100%;
padding-bottom: 150px; padding-bottom: 150px;
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* IE 10+ */
}
.infinite-list::-webkit-scrollbar {
display: none; /* Chrome Safari */
} }
.list { .list {
width: 100%; width: 100%;

View File

@ -213,6 +213,11 @@ async function dragStart(e: any, item: any) {
.infinite-list { .infinite-list {
height: 100%; height: 100%;
padding-bottom: 150px; padding-bottom: 150px;
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* IE 10+ */
}
.infinite-list::-webkit-scrollbar {
display: none; /* Chrome Safari */
} }
.list { .list {
width: 100%; width: 100%;

View File

@ -2,7 +2,7 @@
* @Author: ShawnPhang * @Author: ShawnPhang
* @Date: 2021-08-27 15:16:07 * @Date: 2021-08-27 15:16:07
* @Description: 模板列表 * @Description: 模板列表
* @LastEditors: ShawnPhang <https://m.palxp.cn>, Jeremy Yu <https://github.com/JeremyYu-cn> * @LastEditors: ShawnPhang <https://m.palxp.cn>
* @Date: 2024-03-06 21:16:00 * @Date: 2024-03-06 21:16:00
--> -->
<template> <template>
@ -192,6 +192,11 @@ defineExpose({
height: 100%; height: 100%;
margin-top: 1rem; margin-top: 1rem;
padding-bottom: 150px; padding-bottom: 150px;
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* IE 10+ */
}
.infinite-list::-webkit-scrollbar {
display: none; /* Chrome Safari */
} }
// .list { // .list {
// width: 100%; // width: 100%;

View File

@ -11,7 +11,6 @@
}" }"
draggable="true" draggable="true"
@click="selectBasicText(item)" @click="selectBasicText(item)"
@dragstart="dragStart($event, item)"
> >
{{ item.text }} {{ item.text }}
</div> </div>
@ -25,7 +24,7 @@
<script lang="ts" setup> <script lang="ts" setup>
// const NAME = 'text-list-wrap' // const NAME = 'text-list-wrap'
import wText from '../../widgets/wText/wText.vue' import { wTextSetting } from '../../widgets/wText/wTextSetting'
import { useStore } from 'vuex' import { useStore } from 'vuex'
@ -40,7 +39,7 @@ const store = useStore()
const selectBasicText = (item: TBasicTextData) => { const selectBasicText = (item: TBasicTextData) => {
store.commit('setShowMoveable', false) // store.commit('setShowMoveable', false) //
let setting = JSON.parse(JSON.stringify(wText.setting)) let setting = JSON.parse(JSON.stringify(wTextSetting))
setting.text = '双击编辑文字' // item.text setting.text = '双击编辑文字' // item.text
setting.width = item.fontSize * setting.text.length setting.width = item.fontSize * setting.text.length
setting.fontSize = item.fontSize setting.fontSize = item.fontSize
@ -49,13 +48,12 @@ const selectBasicText = (item: TBasicTextData) => {
setting.left = pW / 2 - item.fontSize * 3 setting.left = pW / 2 - item.fontSize * 3
setting.top = pH / 2 - item.fontSize / 2 setting.top = pH / 2 - item.fontSize / 2
store.dispatch('addWidget', setting) store.dispatch('addWidget', setting)
// addWidget(setting)
} }
const dragStart = (_: MouseEvent, item: any) => { // const dragStart = (_: MouseEvent, item: any) => {
store.commit('setDraging', true) // store.commit('setDraging', true)
store.commit('selectItem', { data: { value: item }, type: 'text' }) // store.commit('selectItem', { data: { value: item }, type: 'text' })
} // }
const basicTextList: TBasicTextData[] = [ const basicTextList: TBasicTextData[] = [
// { // {
@ -86,7 +84,6 @@ const basicTextList: TBasicTextData[] = [
] ]
defineExpose({ defineExpose({
selectBasicText, selectBasicText,
dragStart,
}) })
// ...mapActions(['addWidget']) // ...mapActions(['addWidget'])
@ -106,7 +103,7 @@ defineExpose({
.basic-text-item { .basic-text-item {
color: #33383e; color: #33383e;
background-color: #f1f2f4; background-color: #f1f2f4;
cursor: grab; cursor: pointer;
user-select: none; user-select: none;
border-bottom: 1px solid rgba(255, 255, 255, 0); border-bottom: 1px solid rgba(255, 255, 255, 0);
border-top: 1px solid rgba(255, 255, 255, 0); border-top: 1px solid rgba(255, 255, 255, 0);

View File

@ -27,7 +27,7 @@ export type TClassHeaderTypeData = {
} }
type TProps = { type TProps = {
types: TClassHeaderTypeData[] types?: TClassHeaderTypeData[]
isBack?: boolean isBack?: boolean
} }
@ -56,6 +56,11 @@ defineExpose({ select, back })
height: 100%; height: 100%;
overflow: auto; overflow: auto;
padding-bottom: 100px; padding-bottom: 100px;
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* IE 10+ */
}
&__wrap::-webkit-scrollbar {
display: none; /* Chrome Safari */
} }
} }
.types { .types {

View File

@ -218,6 +218,11 @@ defineExpose({
.img-list-wrap { .img-list-wrap {
height: 100%; height: 100%;
overflow: auto; overflow: auto;
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* IE 10+ */
}
.img-list-wrap::-webkit-scrollbar {
display: none; /* Chrome Safari */
} }
.img { .img {
transform-origin: center; transform-origin: center;

View File

@ -65,9 +65,7 @@ let first = true
// }) // })
onMounted(() => { onMounted(() => {
if (props.modelValue) { checkColorLength()
state.innerColor = props.modelValue + (props.modelValue.length === 7 ? 'ff' : '')
}
}) })
const dropColor = async (color: string) => { const dropColor = async (color: string) => {
@ -90,6 +88,7 @@ watch(
() => props.modelValue, () => props.modelValue,
(val) => { (val) => {
val !== state.innerColor && (state.innerColor = val) val !== state.innerColor && (state.innerColor = val)
checkColorLength()
}, },
) )
@ -105,12 +104,12 @@ const onChange = () => {
emit('finish', state.innerColor) emit('finish', state.innerColor)
} }
// const addHistory = debounce(300, false, async (value) => { function checkColorLength() {
// store.dispatch('pushColorToHistory', value) if (!props.modelValue) {
// }) return
// const colorChange = debounce(150, false, async (e) => { }
// state.innerColor = e + (e.length === 7 ? 'ff' : '') state.innerColor = props.modelValue + (props.modelValue.length === 7 ? 'ff' : '')
// }) }
const inputBlur = (color: string) => { const inputBlur = (color: string) => {
state.innerColor = color state.innerColor = color

View File

@ -50,6 +50,7 @@ const props = withDefaults(defineProps<TProps>(), {
const emit = defineEmits<TEmits>() const emit = defineEmits<TEmits>()
const innerValue = ref<number>(props.minValue) const innerValue = ref<number>(props.minValue)
innerValue.value = props.modelValue
watch( watch(
() => innerValue.value, () => innerValue.value,
@ -67,10 +68,6 @@ watch(
} }
) )
onMounted(() => {
innerValue.value = props.modelValue
})
function changeValue(value: number | number[]) { function changeValue(value: number | number[]) {
emit('finish', value) emit('finish', value)
} }

View File

@ -3,7 +3,7 @@
* @Date: 2021-08-09 11:41:53 * @Date: 2021-08-09 11:41:53
* @Description: * @Description:
* @LastEditors: ShawnPhang <https://m.palxp.cn> * @LastEditors: ShawnPhang <https://m.palxp.cn>
* @LastEditTime: 2023-10-09 00:59:44 * @LastEditTime: 2024-03-22 16:14:48
--> -->
<template> <template>
<div id="w-image-style"> <div id="w-image-style">
@ -71,7 +71,7 @@
<script lang="ts" setup> <script lang="ts" setup>
// //
// const NAME = 'w-image-style' // const NAME = 'w-image-style'
import { nextTick, reactive, ref, watch } from 'vue' import { nextTick, reactive, ref, watch, onBeforeUnmount } from 'vue'
import { useStore } from 'vuex' import { useStore } from 'vuex'
import numberInput from '../../settings/numberInput.vue' import numberInput from '../../settings/numberInput.vue'
import iconItemSelect, { TIconItemSelectData } from '../../settings/iconItemSelect.vue' import iconItemSelect, { TIconItemSelectData } from '../../settings/iconItemSelect.vue'
@ -142,14 +142,18 @@ let lastUuid: string | undefined = undefined
let tag: boolean let tag: boolean
let toolBarStyle: { left: string, top: string } | null = null let toolBarStyle: { left: string, top: string } | null = null
onBeforeUnmount(() => {
imgCrop(false)
cropHandle()
})
watch( watch(
() => dActiveElement.value, () => dActiveElement.value,
(newValue, oldValue) => { (newValue, oldValue) => {
change() change()
// //
if (newValue.uuid != lastUuid && typeof lastUuid !== 'undefined') { if (newValue.uuid != lastUuid && typeof lastUuid !== 'undefined') {
state.innerElement.cropEdit = false imgCrop(false)
store.commit('setShowRotatable', true) //
} }
lastUuid = newValue.uuid lastUuid = newValue.uuid
}, },

View File

@ -13,7 +13,7 @@ export default {
// API_URL: isDev ? 'http://localhost:9998' : '${API}', // API_URL: isDev ? 'http://localhost:9998' : '${API}',
API_URL: 'https://palxp.cn:8887', // 服务端地址 API_URL: 'https://palxp.cn:8887', // 服务端地址
SCREEN_URL: isDev ? 'http://localhost:7001' : '#{SCREEN_URL}', // 截图服务地址 SCREEN_URL: isDev ? 'http://localhost:7001' : '#{SCREEN_URL}', // 截图服务地址
IMG_URL: 'https://store.palxp.com/', // 七牛云资源地址 IMG_URL: 'https://store.palxp.cn/', // 七牛云资源地址
// ICONFONT_URL: '//at.alicdn.com/t/font_3223711_74mlzj4jdue.css', // ICONFONT_URL: '//at.alicdn.com/t/font_3223711_74mlzj4jdue.css',
ICONFONT_URL: '//at.alicdn.com/t/font_2717063_ypy8vprc3b.css?display=swap', ICONFONT_URL: '//at.alicdn.com/t/font_2717063_ypy8vprc3b.css?display=swap',
ICONFONT_EXTRA: '//at.alicdn.com/t/c/font_3228074_42xym3extur.css', ICONFONT_EXTRA: '//at.alicdn.com/t/c/font_3228074_42xym3extur.css',

View File

@ -337,8 +337,7 @@ export default {
store.state.dSelectWidgets = [] store.state.dSelectWidgets = []
}, 10) }, 10)
} else { } else {
// TODO: 不清空会引起mask的bug原因还不清楚.. // store.state.dActiveElement = {}
store.state.dActiveElement = {}
setTimeout(() => { setTimeout(() => {
store.state.dActiveElement = widget store.state.dActiveElement = widget
}, 10) }, 10)

View File

@ -186,8 +186,8 @@ function loadData() {
if (!optionsRef.value) return if (!optionsRef.value) return
optionsRef.value.load(id, tempid, tempType, async () => { optionsRef.value.load(id, tempid, tempType, async () => {
if (!zoomControlRef.value) return if (!zoomControlRef.value) return
zoomControlRef.value.screenChange() // await nextTick()
await nextTick() // zoomControlRef.value.screenChange()
// page // page
store.dispatch('selectWidget', { uuid: '-1' }) store.dispatch('selectWidget', { uuid: '-1' })
// selectWidget({ // selectWidget({