Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
yangkaifeng
uni-app
提交
f17e1c0f
U
uni-app
项目概览
yangkaifeng
/
uni-app
与 Fork 源项目一致
Fork自
DCloud / uni-app
通知
3
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
U
uni-app
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
f17e1c0f
编写于
7月 09, 2021
作者:
Q
qiang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat(App): cover-view, cover-image
上级
d77013f1
变更
4
显示空白变更内容
内联
并排
Showing
4 changed file
with
366 addition
and
0 deletion
+366
-0
packages/uni-app-plus/src/helpers/useCover.ts
packages/uni-app-plus/src/helpers/useCover.ts
+203
-0
packages/uni-app-plus/src/view/components/cover-image/index.tsx
...es/uni-app-plus/src/view/components/cover-image/index.tsx
+125
-0
packages/uni-app-plus/src/view/components/cover-view/index.tsx
...ges/uni-app-plus/src/view/components/cover-view/index.tsx
+37
-0
packages/uni-components/src/index.ts
packages/uni-components/src/index.ts
+1
-0
未找到文件。
packages/uni-app-plus/src/helpers/useCover.ts
0 → 100644
浏览文件 @
f17e1c0f
import
{
computed
,
Ref
,
reactive
,
watch
}
from
'
vue
'
import
{
CustomEventTrigger
}
from
'
@dcloudio/uni-components
'
import
{
Position
,
useNative
}
from
'
./useNative
'
let
id
=
0
export
function
useCover
(
rootRef
:
Ref
<
HTMLElement
|
null
>
,
trigger
:
CustomEventTrigger
,
content
:
{
src
?:
string
;
text
?:
string
}
)
{
const
{
position
,
hidden
,
onParentReady
}
=
useNative
(
rootRef
)
onParentReady
((
parentPosition
)
=>
{
const
viewPosition
=
computed
(()
=>
{
const
object
:
Position
=
{}
as
Position
for
(
const
key
in
position
)
{
let
val
=
position
[
key
as
keyof
Position
]
const
valNumber
=
parseFloat
(
val
)
const
parentValNumber
=
parseFloat
(
parentPosition
[
key
as
keyof
Position
]
)
if
(
key
===
'
top
'
||
key
===
'
left
'
)
{
val
=
Math
.
max
(
valNumber
,
parentValNumber
)
+
'
px
'
}
else
if
(
key
===
'
width
'
||
key
===
'
height
'
)
{
const
base
=
key
===
'
width
'
?
'
left
'
:
'
top
'
const
parentStart
=
parseFloat
(
parentPosition
[
base
])
const
viewStart
=
parseFloat
(
position
[
base
])
const
diff1
=
Math
.
max
(
parentStart
-
viewStart
,
0
)
const
diff2
=
Math
.
max
(
viewStart
+
valNumber
-
(
parentStart
+
parentValNumber
),
0
)
val
=
Math
.
max
(
valNumber
-
diff1
-
diff2
,
0
)
+
'
px
'
}
object
[
key
as
keyof
Position
]
=
val
as
any
}
return
object
})
const
baseStyle
:
Array
<
keyof
CSSStyleDeclaration
>
=
[
'
borderRadius
'
,
'
borderColor
'
,
'
borderWidth
'
,
'
backgroundColor
'
,
]
const
textStyle
:
Array
<
keyof
CSSStyleDeclaration
>
=
[
'
paddingTop
'
,
'
paddingRight
'
,
'
paddingBottom
'
,
'
paddingLeft
'
,
'
color
'
,
'
textAlign
'
,
'
lineHeight
'
,
'
fontSize
'
,
'
fontWeight
'
,
'
textOverflow
'
,
'
whiteSpace
'
,
]
const
imageStyle
:
Array
<
keyof
CSSStyleDeclaration
>
=
[]
const
textAlign
=
{
start
:
'
left
'
,
end
:
'
right
'
}
function
updateStyle
(
style
:
Record
<
keyof
CSSStyleDeclaration
,
any
>
)
{
const
computedStyle
=
getComputedStyle
(
rootRef
.
value
as
HTMLElement
)
baseStyle
.
concat
(
textStyle
,
imageStyle
).
forEach
((
key
)
=>
{
style
[
key
]
=
computedStyle
[
key
]
})
return
style
}
const
style
=
reactive
(
updateStyle
({}
as
CSSStyleDeclaration
))
let
request
:
null
|
number
=
null
function
requestStyleUpdate
()
{
if
(
request
)
{
cancelAnimationFrame
(
request
)
}
request
=
requestAnimationFrame
(()
=>
{
request
=
null
updateStyle
(
style
)
})
}
window
.
addEventListener
(
'
updateview
'
,
requestStyleUpdate
)
function
getTagPosition
()
{
const
position
:
Partial
<
Position
>
=
{}
for
(
const
key
in
position
)
{
let
val
=
position
[
key
as
keyof
Position
]
!
if
(
key
===
'
top
'
||
key
===
'
left
'
)
{
val
=
Math
.
min
(
parseFloat
(
val
)
-
parseFloat
(
parentPosition
[
key
]),
0
)
+
'
px
'
}
position
[
key
as
keyof
Position
]
=
val
as
any
}
return
position
}
const
tags
=
computed
(()
=>
{
const
position
:
Position
=
getTagPosition
()
as
Position
const
tags
:
PlusNativeObjViewDrawTagStyles
[]
=
[
{
tag
:
'
rect
'
,
position
,
rectStyles
:
{
color
:
style
.
backgroundColor
,
radius
:
style
.
borderRadius
,
borderColor
:
style
.
borderColor
,
borderWidth
:
style
.
borderWidth
,
},
},
]
if
(
'
src
'
in
content
)
{
if
(
content
.
src
)
{
tags
.
push
({
tag
:
'
img
'
,
position
,
src
:
content
.
src
,
})
}
}
else
{
const
lineSpacing
=
parseFloat
(
style
.
lineHeight
)
-
parseFloat
(
style
.
fontSize
)
let
width
=
parseFloat
(
position
.
width
)
-
parseFloat
(
style
.
paddingLeft
)
-
parseFloat
(
style
.
paddingRight
)
width
=
width
<
0
?
0
:
width
let
height
=
parseFloat
(
position
.
height
)
-
parseFloat
(
style
.
paddingTop
)
-
lineSpacing
/
2
-
parseFloat
(
style
.
paddingBottom
)
height
=
height
<
0
?
0
:
height
tags
.
push
({
tag
:
'
font
'
,
position
:
{
top
:
`
${
parseFloat
(
position
.
top
)
+
parseFloat
(
style
.
paddingTop
)
+
lineSpacing
/
2
}
px`
,
left
:
`
${
parseFloat
(
position
.
left
)
+
parseFloat
(
style
.
paddingLeft
)
}
px`
,
width
:
`
${
width
}
px`
,
height
:
`
${
height
}
px`
,
},
textStyles
:
{
align
:
textAlign
[
style
.
textAlign
as
keyof
typeof
textAlign
]
||
style
.
textAlign
,
color
:
style
.
color
,
decoration
:
'
none
'
,
lineSpacing
:
`
${
lineSpacing
}
px`
,
margin
:
'
0px
'
,
overflow
:
style
.
textOverflow
,
size
:
style
.
fontSize
,
verticalAlign
:
'
top
'
,
weight
:
style
.
fontWeight
,
whiteSpace
:
style
.
whiteSpace
,
},
text
:
content
.
text
,
})
}
return
tags
})
const
cover
=
new
plus
.
nativeObj
.
View
!
(
`cover-
${
Date
.
now
()}
-
${
id
++
}
`
,
viewPosition
.
value
,
tags
.
value
)
plus
.
webview
.
currentWebview
().
append
(
cover
)
if
(
hidden
.
value
)
{
cover
.
hide
()
}
cover
.
addEventListener
(
'
click
'
,
()
=>
{
trigger
(
'
click
'
,
{}
as
Event
,
{})
})
watch
(
()
=>
hidden
.
value
,
(
val
)
=>
{
cover
[
val
?
'
hide
'
:
'
show
'
]()
}
)
watch
(
()
=>
viewPosition
.
value
,
(
val
)
=>
{
cover
.
setStyle
(
val
)
},
{
deep
:
true
}
)
watch
(
()
=>
tags
.
value
,
()
=>
{
cover
.
reset
()
cover
.
draw
(
tags
.
value
)
},
{
deep
:
true
}
)
})
}
packages/uni-app-plus/src/view/components/cover-image/index.tsx
0 → 100644
浏览文件 @
f17e1c0f
import
{
Ref
,
ref
,
reactive
,
ExtractPropTypes
,
watch
,
onBeforeUnmount
,
}
from
'
vue
'
import
{
plusReady
}
from
'
@dcloudio/uni-shared
'
import
{
defineBuiltInComponent
,
useCustomEvent
,
CustomEventTrigger
,
EmitEvent
,
}
from
'
@dcloudio/uni-components
'
import
{
useCover
}
from
'
../../../helpers/useCover
'
import
{
getRealPath
}
from
'
../../../platform/getRealPath
'
// TODO 从 service 层传入
const
TEMP_PATH
=
'
_doc/uniapp_temp/
'
const
props
=
{
src
:
{
type
:
String
,
default
:
''
,
},
autoSize
:
{
type
:
[
Boolean
,
String
],
default
:
false
,
},
}
type
Props
=
ExtractPropTypes
<
typeof
props
>
function
useImageLoad
(
props
:
Props
,
content
:
{
src
:
string
},
trigger
:
CustomEventTrigger
)
{
const
style
=
ref
(
''
)
let
downloaTask
:
PlusDownloaderDownload
function
loadImage
()
{
content
.
src
=
''
style
.
value
=
props
.
autoSize
?
'
width:0;height:0;
'
:
''
const
realPath
=
props
.
src
?
getRealPath
(
props
.
src
)
:
''
if
(
realPath
.
indexOf
(
'
http://
'
)
===
0
||
realPath
.
indexOf
(
'
https://
'
)
===
0
)
{
plusReady
(()
=>
{
downloaTask
=
plus
.
downloader
.
createDownload
(
realPath
,
{
filename
:
TEMP_PATH
+
'
/download/
'
,
},
(
task
,
status
)
=>
{
if
(
status
===
200
)
{
getImageInfo
(
task
.
filename
!
)
}
else
{
trigger
(
'
error
'
,
{}
as
Event
,
{
errMsg
:
'
error
'
,
})
}
}
)
downloaTask
.
start
()
})
}
else
if
(
realPath
)
{
getImageInfo
(
realPath
)
}
}
function
getImageInfo
(
src
:
string
)
{
content
.
src
=
src
plusReady
(()
=>
{
plus
.
io
.
getImageInfo
({
src
,
success
:
({
width
,
height
})
=>
{
if
(
props
.
autoSize
)
{
style
.
value
=
`width:
${
width
}
px;height:
${
height
}
px;`
window
.
dispatchEvent
(
new
CustomEvent
(
'
updateview
'
))
}
trigger
(
'
load
'
,
{}
as
Event
,
{
width
,
height
})
},
fail
:
()
=>
{
trigger
(
'
error
'
,
{}
as
Event
,
{
errMsg
:
'
error
'
,
})
},
})
})
}
if
(
props
.
src
)
{
loadImage
()
}
watch
(()
=>
props
.
src
,
loadImage
)
onBeforeUnmount
(()
=>
{
if
(
downloaTask
)
{
downloaTask
.
abort
()
}
})
return
style
}
export
default
/*#__PURE__*/
defineBuiltInComponent
({
name
:
'
CoverImage
'
,
props
,
emits
:
[
'
click
'
,
'
load
'
,
'
error
'
],
setup
(
props
,
{
emit
})
{
const
rootRef
:
Ref
<
HTMLElement
|
null
>
=
ref
(
null
)
const
trigger
=
useCustomEvent
<
EmitEvent
<
typeof
emit
>>
(
rootRef
,
emit
)
let
content
=
reactive
({
src
:
''
})
const
style
=
useImageLoad
(
props
,
content
,
trigger
)
useCover
(
rootRef
,
trigger
,
content
)
return
()
=>
{
return
(
<
uni
-
cover
-
image
ref
=
{
rootRef
}
style
=
{
style
.
value
}
>
<
div
class
=
"uni-cover-image"
></
div
>
</
uni
-
cover
-
image
>
)
}
},
})
packages/uni-app-plus/src/view/components/cover-view/index.tsx
0 → 100644
浏览文件 @
f17e1c0f
import
{
Ref
,
ref
,
reactive
}
from
'
vue
'
import
{
defineBuiltInComponent
,
useCustomEvent
,
EmitEvent
,
flatVNode
,
Text
,
}
from
'
@dcloudio/uni-components
'
import
{
useCover
}
from
'
../../../helpers/useCover
'
export
default
/*#__PURE__*/
defineBuiltInComponent
({
name
:
'
CoverView
'
,
emits
:
[
'
click
'
],
setup
(
_
,
{
emit
,
slots
})
{
const
rootRef
:
Ref
<
HTMLElement
|
null
>
=
ref
(
null
)
const
trigger
=
useCustomEvent
<
EmitEvent
<
typeof
emit
>>
(
rootRef
,
emit
)
let
content
=
reactive
({
text
:
''
})
useCover
(
rootRef
,
trigger
,
content
)
return
()
=>
{
const
defaultSlots
=
slots
.
default
?
flatVNode
(
slots
.
default
())
:
[]
let
text
=
''
defaultSlots
.
forEach
((
node
)
=>
{
if
(
!
node
.
type
===
Text
)
{
text
+=
node
.
children
||
''
}
})
content
.
text
=
text
return
(
<
uni
-
cover
-
view
ref
=
{
rootRef
}
>
<
div
class
=
"uni-cover-view"
>
{
text
}
</
div
>
</
uni
-
cover
-
view
>
)
}
},
})
packages/uni-components/src/index.ts
浏览文件 @
f17e1c0f
...
...
@@ -20,5 +20,6 @@ export {
defineBuiltInComponent
,
defineSystemComponent
,
}
from
'
./helpers/component
'
export
{
flatVNode
}
from
'
./helpers/flatVNode
'
export
{
uniFormKey
}
from
'
./components/form
'
export
type
{
UniFormCtx
}
from
'
./components/form
'
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录