Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
pptist
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
viitto
pptist
Commits
33ebc45a
Commit
33ebc45a
authored
Jun 17, 2024
by
zhengke
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
处理图片清晰度
parent
5b0ea80d
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
310 additions
and
6 deletions
+310
-6
imgArticContr.vue
src/components/CloudDisk/imgArticContr.vue
+230
-0
ImageStylePanel.vue
...iews/Editor/Toolbar/ElementStylePanel/ImageStylePanel.vue
+77
-3
ElementColorMask.vue
src/views/Editor/Toolbar/common/ElementColorMask.vue
+3
-3
No files found.
src/components/CloudDisk/imgArticContr.vue
0 → 100644
View file @
33ebc45a
<
template
>
<el-dialog
v-model=
"dialogFormVisible"
:show-close=
"false"
:title=
"dialogTitle"
:close-on-press-escape=
"false"
:close-on-click-modal=
"false"
:width=
"width+40+'px'"
>
<div
class=
"PictureComparison"
:style=
"'width:' + width + 'px;height:' + height + 'px'"
>
<div
class=
"before-image"
:style=
"'width:' + data.x + 'px'"
@
click
.
stop=
"goLeft"
>
<div
:style=
"'width:' + width + 'px;height:' + height + 'px'"
>
<slot
name=
"left"
></slot>
</div>
</div>
<div
class=
"after-image"
@
click
.
stop=
"goRight"
>
<div
:style=
"'width:' + width + 'px;height:' + height + 'px'"
>
<slot
name=
"right"
></slot>
</div>
</div>
<div
class=
"divider-bar"
:style=
"'left:' + data.x + 'px'"
@
mousedown
.
prevent=
"onmouseDown($event)"
></div>
<span
class=
"spanHandle"
:style=
"
{ left: data.x - 24+'px' }"
@mousedown.prevent="onmouseDown($event)">
</span>
</div>
<template
#
footer
>
<div
class=
"dialog-footer"
>
<el-button
@
click=
"close"
:disabled=
"setLoading"
>
取消
</el-button>
<el-button
type=
"primary"
@
click=
"submit"
:loading=
"setLoading"
>
确认替换
</el-button>
</div>
</
template
>
</el-dialog>
</template>
<
script
lang=
"ts"
setup
>
import
{
reactive
,
ref
,
onMounted
}
from
"vue"
;
import
{
storeToRefs
}
from
'pinia'
import
AliyunUpload
from
'@/utils/upload/aliyun'
import
{
useSlidesStore
,
useMainStore
}
from
'@/store'
const
mainStore
=
useMainStore
()
const
slidesStore
=
useSlidesStore
()
const
{
handleElement
,
handleElementId
}
=
storeToRefs
(
mainStore
)
const
dialogFormVisible
=
ref
(
true
)
const
dialogTitle
=
ref
(
'原图/清晰图对比'
)
const
setLoading
=
ref
(
false
)
const
props
=
defineProps
({
width
:
{
type
:
String
,
default
:
"500"
},
height
:
{
type
:
String
,
default
:
"300"
},
newImg
:
{
type
:
String
,
default
:
""
}
})
const
data
=
reactive
({
isDown
:
false
,
//鼠标是否正按住
moveX
:
0
,
//鼠标移动的位置
x
:
props
.
width
/
2
,
//设置位置
})
const
upperImg
=
'data:image/png;base64,'
+
props
.
newImg
;
// 上层图
const
emit
=
defineEmits
<
{
(
event
:
'close'
):
void
,
(
event
:
'success'
):
void
,
}
>
()
const
onmouseDown
=
(
event
)
=>
{
data
.
isDown
=
true
;
data
.
x
=
event
.
target
.
offsetLeft
;
var
disX
=
event
.
clientX
-
event
.
target
.
offsetLeft
;
document
.
onmousemove
=
function
(
event
)
{
if
(
data
.
isDown
==
false
)
{
return
;
}
data
.
x
=
event
.
clientX
-
disX
;
if
(
data
.
x
>=
props
.
width
)
{
data
.
x
=
props
.
width
;
}
else
if
(
data
.
x
<=
0
)
{
data
.
x
=
0
;
}
};
document
.
onmouseup
=
function
()
{
data
.
isDown
=
false
;
document
.
onmousemove
=
document
.
onmouseup
=
null
;
return
false
;
};
}
const
goLeft
=
()
=>
{
data
.
x
=
0
;
}
const
goRight
=
()
=>
{
data
.
x
=
props
.
width
;
}
const
close
=
()
=>
{
dialogFormVisible
.
value
=
false
emit
(
'close'
)
}
const
submit
=
()
=>
{
let
text
=
'此操作将替换原图,请谨慎处理!'
ElMessageBox
.
confirm
(
`
${
text
}
`
,
'提示'
,
{
confirmButtonText
:
'确定'
,
cancelButtonText
:
'取消'
,
type
:
'warning'
,
}
).
then
(()
=>
{
setImg
()
}).
catch
(()
=>
{})
}
const
setImg
=
async
()
=>
{
setLoading
.
value
=
true
let
name
=
new
Date
().
getTime
()
+
".png"
const
file
=
dataURLtoFile
(
upperImg
,
name
)
let
url
=
await
AliyunUpload
.
UploadAsync
(
file
,
`pptist/desgin/
${
name
}
`
)
if
(
url
!=
''
){
const
props
=
{
src
:
url
}
slidesStore
.
updateElement
({
id
:
handleElementId
.
value
,
props
})
emit
(
'success'
)
}
setLoading
.
value
=
false
}
const
dataURLtoFile
=
(
dataurl
:
string
,
filename
:
string
)
=>
{
let
arr
=
dataurl
.
split
(
","
)
let
mime
=
arr
[
0
].
match
(
/:
(
.*
?)
;/
)[
1
],
bstr
=
atob
(
arr
[
1
]),
n
=
bstr
.
length
,
u8arr
=
new
Uint8Array
(
n
);
while
(
n
--
)
{
u8arr
[
n
]
=
bstr
.
charCodeAt
(
n
);
}
return
new
File
([
u8arr
],
filename
,
{
type
:
mime
});
}
</
script
>
<
style
scoped
>
.PictureComparison
{
position
:
relative
;
display
:
inline-block
;
margin
:
0
auto
;
min-height
:
273px
;
overflow
:
hidden
;
}
.before-image
{
position
:
absolute
;
top
:
0
;
left
:
0
;
z-index
:
1
;
width
:
50%
;
overflow
:
hidden
;
}
.after-image
{
position
:
absolute
;
top
:
0
;
left
:
0
;
z-index
:
0
;
}
.divider-bar
{
cursor
:
move
;
position
:
absolute
;
width
:
1px
;
left
:
40%
;
top
:
0
;
bottom
:
0px
;
background
:
white
;
height
:
100%
;
display
:
block
;
z-index
:
2
;
/* box-shadow: 0 0 10px 1px rgba(0, 0, 0, 0.4); */
}
.divider-bar
::after
{
/*
content
:
"
<
-
>
";
position: absolute;
color: #000;
font-weight: bold;
text-align: center;
line-height: 32px;
width: 50px;
height: 30px;
background: #fff;
border-radius: 15px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%); */
}
.spanHandle {
cursor: move;
position: absolute; /*决定定位还是一样的*/
z-index: 2; /* 样式很多,都不是关键的,只有这里,需要注意层次要低于inputRange*/
height: 48px;
width: 48px;
position: center;
font-size: 24px;
border: 1px;
border-radius: 50%;
top: calc(50% - 24px);
background-color: rgb(255, 255, 255, 0.5);
}
.spanHandle:before {
left: 5px;
transform: rotate(-45deg);
}
.spanHandle:after {
right: -5px;
transform: rotate(135deg);
}
.spanHandle:after,
.spanHandle:before {
border-left: 2px solid;
border-top: 2px solid;
content: "
"
;
height
:
10px
;
position
:
absolute
;
top
:
50
%;
transform-origin
:
0
0
;
width
:
10px
;
}
</
style
>
\ No newline at end of file
src/views/Editor/Toolbar/ElementStylePanel/ImageStylePanel.vue
View file @
33ebc45a
...
...
@@ -4,13 +4,13 @@
class=
"origin-image"
:style=
"
{ backgroundImage: `url(${handleImageElement.src})` }"
>
</div>
<Button
class=
"full-width-btn"
@
click=
"getImgVis()"
:style=
"
{'margin-bottom': mode==1?0:''}">
<IconTransform
class=
"btn-icon"
/>
替换图片
</Button>
<Button
class=
"full-width-btn"
@
click=
"getImgVis()"
><IconTransform
class=
"btn-icon"
/>
替换图片
</Button>
<Button
class=
"full-width-btn"
@
click=
"getPictDef()"
:style=
"
{'margin-bottom': mode==1?0:''}">处理图清晰度
</Button>
<Divider
v-if=
"mode==1"
/>
<div
v-if=
"mode==1"
class=
"row items-center"
>
<div
class=
"col"
>
图层名称:
</div>
<el-input
style=
"width:60%;"
v-model=
"layerName"
@
input=
"updateLayerName"
></el-input>
</div>
<Divider
v-if=
"mode==1"
/>
<ElementFlip
/>
...
...
@@ -74,11 +74,30 @@
<Button
class=
"full-width-btn"
@
click=
"setBackgroundImage()"
><IconTheme
class=
"btn-icon"
/>
设为背景
</Button>
<!-- 上传图片 -->
<UploadPicture
v-show=
"imgReplaceVisible"
></UploadPicture>
<!-- 图片处理对比 -->
<!-- <imgArticContr1 v-if="DefinitionDatas"
:oldImg="handleImageElement.src"
:newImg="DefinitionDatas"
@close="DefinitionDatas=null"
@success="DefinitionDatas=null"></imgArticContr1> -->
<imgArticContr
v-if=
"DefinitionDatas"
:width=
"imgWidth"
:height=
"imgHeigth"
:newImg=
"DefinitionDatas"
@
close=
"DefinitionDatas=null"
@
success=
"DefinitionDatas=null"
>
<
template
#
left
>
<span
style=
"position: absolute;left: 10px;top:10px;background: #fff;border-radius: 3px;padding:0 5px;width: 38px;"
>
原图
</span>
<img
:src=
"handleImageElement.src"
class=
"images"
:style=
"
{width: imgWidth+'px'}" />
</
template
>
<
template
#
right
>
<img
:src=
"'data:image/png;base64,'+DefinitionDatas"
class=
"images"
:style=
"
{width: imgWidth+'px'}" />
</
template
>
</imgArticContr>
</div>
</template>
<
script
lang=
"ts"
setup
>
import
{
type
Ref
,
ref
,
provide
}
from
'vue'
import
{
type
Ref
,
ref
,
provide
,
reactive
}
from
'vue'
import
{
storeToRefs
}
from
'pinia'
import
{
useMainStore
,
useSlidesStore
,
useScreenStore
,
useKeyboardStore
}
from
'@/store'
import
type
{
PPTImageElement
,
SlideBackground
}
from
'@/types/slides'
...
...
@@ -99,6 +118,13 @@ import ButtonGroup from '@/components/ButtonGroup.vue'
import
Popover
from
'@/components/Popover.vue'
import
UploadPicture
from
'../../CanvasTool/UploadPicture.vue'
import
imgArticContr
from
'@/components/CloudDisk/imgArticContr.vue'
import
CloudDiskService
from
'@/services/CloudDiskService'
import
{
ApiResult
}
from
"@/configs/axios"
;
import
AliyunUpload
from
'@/utils/upload/aliyun'
import
{
ElLoading
}
from
"element-plus"
;
import
FileService
from
'@/services/FileService'
const
shapeClipPathOptions
=
CLIPPATHS
const
ratioClipOptions
=
[
{
...
...
@@ -153,6 +179,54 @@ const mode = model.value??1
provide
(
'imgType'
,
2
)
const
DefinitionLoading
=
ref
(
false
)
const
DefinitionDatas
=
ref
(
''
as
any
)
const
DefinParams
=
reactive
({
basestr
:
''
,
extname
:
''
,
url
:
''
,
})
const
imgWidth
=
ref
(
500
)
const
imgHeigth
=
ref
(
0
)
const
getPictDef
=
async
()
=>
{
if
(
handleImageElement
.
value
.
src
.
startsWith
(
"data:image"
)){
let
name
=
new
Date
().
getTime
()
+
".jpg"
const
file
=
dataURLtoFile
(
handleImageElement
.
value
.
src
,
name
)
let
url
=
await
AliyunUpload
.
UploadAsync
(
file
,
`Feature/CoverImg_
${
name
}
`
)
DefinParams
.
url
=
url
}
else
DefinParams
.
url
=
handleImageElement
.
value
.
src
let
files
=
DefinParams
.
url
.
split
(
'/'
)
DefinParams
.
extname
=
files
[
files
.
length
-
1
]
DefinitionImg
()
}
const
DefinitionImg
=
async
()
=>
{
if
(
DefinitionLoading
.
value
)
return
DefinitionLoading
.
value
=
true
const
loadingObj
=
ElLoading
.
service
({
text
:
'正在处理图的清晰度'
,
lock
:
true
})
try
{
const
datasRes
=
await
CloudDiskService
.
BaiduImageDefinition
(
DefinParams
);
if
(
datasRes
.
data
.
resultCode
==
ApiResult
.
SUCCESS
)
{
DefinitionDatas
.
value
=
datasRes
.
data
.
data
}
DefinitionLoading
.
value
=
false
loadingObj
.
close
()
}
catch
(
error
)
{
DefinitionLoading
.
value
=
false
loadingObj
.
close
()
}
}
const
getImgSize
=
async
()
=>
{
let
TempSize
=
await
FileService
.
getImageSizeWithoutDownloading
(
handleImageElement
.
value
.
src
)
let
ratio
=
TempSize
.
width
/
imgWidth
.
value
imgHeigth
.
value
=
TempSize
.
height
/
ratio
}
getImgSize
()
const
getLockCutRatio
=
()
=>
{
keyboardStore
.
setCtrlKeyState
(
ctrlKeyState
.
value
)
}
...
...
src/views/Editor/Toolbar/common/ElementColorMask.vue
View file @
33ebc45a
<
template
>
<div
class=
"element-color-mask"
>
<div
class=
"row"
>
<div
style=
"width:
40%
;"
>
着色(蒙版):
</div>
<div
class=
"switch-wrapper"
style=
"width: 60%;"
>
<div
class=
"row
flex-between
"
>
<div
style=
"width:
auto
;"
>
着色(蒙版):
</div>
<div
class=
"switch-wrapper"
>
<Switch
:value=
"hasColorMask"
@
update:value=
"value => toggleColorMask(value)"
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment