@shijiu/jsview-vue 2.2.35 → 2.2.128
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/browser/BrowserApic.vue.mjs +2 -1
- package/bin/browser/BrowserApic2.vue.mjs +2 -1
- package/bin/browser/BrowserApicLib.mjs +2 -1
- package/bin/browser/BrowserQrcode.vue.mjs +3 -1
- package/bin/browser/BrowserTextureAnim.vue.mjs +7 -6
- package/bin/jsview-vue.mjs +1557 -894
- package/bin/types/JsViewEngineWidget/MetroWidget/Slide.d.ts +21 -0
- package/bin/types/JsViewEngineWidget/TemplateParser/MetroTemplate.d.ts +2 -8
- package/bin/types/JsViewEngineWidget/WidgetCommon.d.ts +9 -3
- package/bin/types/JsViewVueTools/ConstSymbol.d.ts +2 -0
- package/bin/types/JsViewVueTools/ForgeConstDefine.d.ts +11 -0
- package/bin/types/JsViewVueTools/JsvRuntimeBridge.d.ts +113 -57
- package/bin/types/JsViewVueTools/JsvTextureStore/CapturedTexture/CapturedTexture.d.ts +11 -0
- package/bin/types/JsViewVueTools/JsvTextureStore/Texture.d.ts +8 -0
- package/bin/types/JsViewVueWidget/JsvConnectLine/JsvConnectLine.vue.d.ts +1 -1
- package/bin/types/JsViewVueWidget/JsvFreeMoveActor/ActionRefObject.d.ts +4 -0
- package/bin/types/JsViewVueWidget/JsvFreeMoveActor/ActorControl.d.ts +65 -0
- package/bin/types/JsViewVueWidget/JsvFreeMoveActor/ActorState.d.ts +6 -0
- package/bin/types/JsViewVueWidget/JsvFreeMoveActor/CallbackManager.d.ts +11 -0
- package/bin/types/JsViewVueWidget/JsvFreeMoveActor/ForgeTypeDefine.d.ts +15 -0
- package/bin/types/JsViewVueWidget/JsvFreeMoveActor/FreeMoveActor.vue.d.ts +6 -0
- package/bin/types/JsViewVueWidget/JsvFreeMoveActor/SetAction.d.ts +71 -0
- package/bin/types/JsViewVueWidget/JsvFreeMoveActor/SetCondition.d.ts +95 -0
- package/bin/types/JsViewVueWidget/JsvFreeMoveActor/SetState.d.ts +62 -0
- package/bin/types/JsViewVueWidget/JsvFreeMoveActor/index.d.ts +2 -1
- package/bin/types/JsViewVueWidget/JsvLine/JsvLine.vue.d.ts +1 -1
- package/bin/types/JsViewVueWidget/JsvNativeSharedDiv.vue.d.ts +66 -28
- package/bin/types/JsViewVueWidget/JsvNinePatch.vue.d.ts +1 -0
- package/bin/types/JsViewVueWidget/JsvScrollBox/JsvScrollBox.vue.d.ts +176 -0
- package/bin/types/JsViewVueWidget/JsvScrollBox/ScrollSymbol.d.ts +7 -0
- package/bin/types/JsViewVueWidget/JsvScrollBox/index.d.ts +1 -0
- package/bin/types/JsViewVueWidget/JsvTextBox.vue.d.ts +3 -3
- package/bin/types/JsViewVueWidget/index.d.ts +1 -0
- package/package.json +1 -1
- package/utils/JsViewEngineWidget/MetroWidget/MetroWidget.vue +10 -1
- package/utils/JsViewEngineWidget/MetroWidget/MetroWidgetSetup.js +398 -309
- package/utils/JsViewEngineWidget/MetroWidget/RenderItem.ts +2 -1
- package/utils/JsViewEngineWidget/MetroWidget/Slide.ts +56 -0
- package/utils/JsViewEngineWidget/MetroWidget/TaskManager.ts +51 -10
- package/utils/JsViewEngineWidget/MetroWidget/TokenGenerator.ts +10 -0
- package/utils/JsViewEngineWidget/TemplateParser/ListMetroTemplate.ts +9 -3
- package/utils/JsViewEngineWidget/TemplateParser/MetroTemplate.ts +25 -35
- package/utils/JsViewEngineWidget/WidgetCommon.ts +20 -7
- package/utils/JsViewPlugin/JsvPlayer/BrowserJsvPlayer.vue +13 -1
- package/utils/JsViewPlugin/JsvPlayer/JsvPlayer.vue +470 -338
- package/utils/JsViewVueTools/ConstSymbol.ts +3 -0
- package/utils/JsViewVueTools/ForgeConstDefine.ts +11 -0
- package/utils/JsViewVueTools/JsvRuntimeBridge.js +172 -50
- package/utils/JsViewVueTools/JsvTextureStore/CapturedTexture/CapturedTexture.ts +62 -0
- package/utils/JsViewVueTools/JsvTextureStore/JsvTextureStore.ts +41 -7
- package/utils/JsViewVueTools/JsvTextureStore/Texture.ts +15 -1
- package/utils/JsViewVueTools/index.js +2 -0
- package/utils/JsViewVueWidget/JsvApic/JsvApic/BrowserApic.vue +6 -6
- package/utils/JsViewVueWidget/JsvApic/JsvApic2/BrowserApic2.vue +5 -6
- package/utils/JsViewVueWidget/JsvApic/JsvBrowserApicLib/ApicDataBase.js +5 -1
- package/utils/JsViewVueWidget/JsvFreeMoveActor/ActionRefObject.ts +1 -1
- package/utils/JsViewVueWidget/JsvFreeMoveActor/ActorControl.ts +23 -1
- package/utils/JsViewVueWidget/JsvFreeMoveActor/ActorState.ts +4 -4
- package/utils/JsViewVueWidget/JsvFreeMoveActor/CallbackManager.ts +6 -6
- package/utils/JsViewVueWidget/JsvFreeMoveActor/ForgeTypeDefine.ts +1 -1
- package/utils/JsViewVueWidget/JsvFreeMoveActor/FreeMoveActor.vue +43 -9
- package/utils/JsViewVueWidget/JsvFreeMoveActor/SetAction.ts +24 -0
- package/utils/JsViewVueWidget/JsvFreeMoveActor/SetCondition.ts +50 -1
- package/utils/JsViewVueWidget/JsvFreeMoveActor/SetState.ts +56 -0
- package/utils/JsViewVueWidget/JsvFreeMoveActor/index.js +3 -0
- package/utils/JsViewVueWidget/JsvMaskClipDiv.vue +6 -1
- package/utils/JsViewVueWidget/JsvNativeSharedDiv.vue +121 -68
- package/utils/JsViewVueWidget/JsvNinePatch.vue +4 -1
- package/utils/JsViewVueWidget/JsvPosterImage.vue +22 -9
- package/utils/JsViewVueWidget/JsvQrcode/BrowserQrcode.vue +6 -2
- package/utils/JsViewVueWidget/JsvScrollBox/JsvScrollBox.vue +309 -0
- package/utils/JsViewVueWidget/JsvScrollBox/ScrollSymbol.ts +15 -0
- package/utils/JsViewVueWidget/JsvScrollBox/index.js +2 -0
- package/utils/JsViewVueWidget/JsvTextBox.vue +12 -4
- package/utils/JsViewVueWidget/JsvTextureAnim/BrowserTextureAnim.vue +9 -6
- package/utils/JsViewVueWidget/JsvTextureAnim/JsvTextureAnim.vue +2 -0
- package/utils/JsViewVueWidget/index.js +1 -0
|
@@ -5,84 +5,109 @@
|
|
|
5
5
|
* getId {function} 回调函数,用于接收ID信息,ID信息用于Native端对该view进行跟踪的标识
|
|
6
6
|
* setId {String} 给定命名ID,避免同进程不同context重名要和Context相关,
|
|
7
7
|
* 例如`${window.JsView?.getJsContextId()}_${you_name}`
|
|
8
|
+
* corner {Number} 圆角的尺寸,默认为0
|
|
9
|
+
*
|
|
8
10
|
-->
|
|
9
11
|
|
|
10
|
-
<script>
|
|
12
|
+
<script setup>
|
|
11
13
|
import { Forge } from "@shijiu/jsview/dom/jsv-forge-define";
|
|
12
14
|
import ForgeHandles from "../JsViewVueTools/ForgeHandles";
|
|
15
|
+
import { JsvTextureStoreApi } from "../JsViewVueTools/JsvTextureStore/JsvTextureStore";
|
|
16
|
+
import { onUnmounted, shallowRef } from "vue";
|
|
17
|
+
import JsvNinePatch from "./JsvNinePatch.vue";
|
|
13
18
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
return {};
|
|
20
|
-
},
|
|
21
|
-
},
|
|
22
|
-
getId: Function,
|
|
23
|
-
setId: String,
|
|
24
|
-
seeThrough: {
|
|
25
|
-
type: Boolean,
|
|
26
|
-
default: true,
|
|
19
|
+
const props = defineProps({
|
|
20
|
+
style: {
|
|
21
|
+
type: Object,
|
|
22
|
+
default: () => {
|
|
23
|
+
return {};
|
|
27
24
|
},
|
|
28
25
|
},
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
};
|
|
26
|
+
getId: Function,
|
|
27
|
+
setId: String,
|
|
28
|
+
corner: {
|
|
29
|
+
type: Number,
|
|
30
|
+
default: 0,
|
|
35
31
|
},
|
|
36
|
-
|
|
37
|
-
if (this.isBrowserDebug) {
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
32
|
+
});
|
|
40
33
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
ForgeHandles.TextureManager.GetColorTexture("rgba(0,0,0,0)");
|
|
49
|
-
textureSetting = new Forge.TextureSetting(
|
|
50
|
-
seeThroughTexture,
|
|
51
|
-
null,
|
|
52
|
-
null,
|
|
53
|
-
false
|
|
54
|
-
);
|
|
55
|
-
}
|
|
34
|
+
let isBrowserDebug = window.jsvIsBrowserDebug;
|
|
35
|
+
let jsvMainView = undefined;
|
|
36
|
+
let innerViewId = -1;
|
|
37
|
+
let ninePatchSet = null;
|
|
38
|
+
|
|
39
|
+
if (!isBrowserDebug) {
|
|
40
|
+
// 创建JsView图层穿透的texture,抠洞处理
|
|
56
41
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
42
|
+
// 有圆角
|
|
43
|
+
if (props.corner > 0) {
|
|
44
|
+
let presetGap = 1; // 外延距离,以保证圆角光滑
|
|
45
|
+
ninePatchSet = {
|
|
46
|
+
imageSize: (props.corner + presetGap) * 2, // 半径 + 中心点1像素
|
|
47
|
+
textureName: null,
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
// 用 JsvTextureStoreApi 绘制半径对等的圆形
|
|
51
|
+
let sampleImageWidth = ninePatchSet.imageSize;
|
|
52
|
+
let innerRadius2 = sampleImageWidth; // 内直径
|
|
53
|
+
let circleLineWidth = 1.5 * props.corner + presetGap - props.corner; // 线粗要把四角盖上
|
|
54
|
+
let canvasRef;
|
|
55
|
+
|
|
56
|
+
// 创建画布
|
|
57
|
+
canvasRef = JsvTextureStoreApi.canvasTexture(
|
|
58
|
+
sampleImageWidth,
|
|
59
|
+
sampleImageWidth
|
|
61
60
|
);
|
|
62
61
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
62
|
+
let circleRadius =
|
|
63
|
+
Math.floor(innerRadius2 / 2) +
|
|
64
|
+
Math.floor(circleLineWidth / 2) -
|
|
65
|
+
presetGap; // 圆环绘制路径是粗线的中心线,所以要减去一半的线宽
|
|
66
|
+
let customPath = canvasRef.circlePath(
|
|
67
|
+
Math.floor(sampleImageWidth / 2),
|
|
68
|
+
Math.floor(sampleImageWidth / 2),
|
|
69
|
+
circleRadius
|
|
70
|
+
); // 创建圆环绘制路径,圆形在画布的中心点位置
|
|
71
|
+
canvasRef.drawColor("rgba(0,0,0,0)"); // 画布绘制透明底色
|
|
72
|
+
customPath.stroke(circleLineWidth, "#FF0000FF"); // 绘制alpha=1的边缘留色
|
|
69
73
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
74
|
+
// 获取填入url的内容
|
|
75
|
+
// 进行.9拉伸以适配目标尺寸
|
|
76
|
+
// 通过 alphaOverride 进行alpah叠加
|
|
77
|
+
ninePatchSet.textureName = canvasRef.commit();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// 通过内置函数构造定制的NativeSharedView
|
|
81
|
+
jsvMainView = new Forge.NativeSharedView();
|
|
82
|
+
innerViewId = Forge.sViewStore.add(new Forge.ViewInfo(jsvMainView));
|
|
77
83
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
84
|
+
// 更新宽高
|
|
85
|
+
if (typeof jsvMainView != "undefined" && jsvMainView) {
|
|
86
|
+
if (props.setId) {
|
|
87
|
+
// 使用设置进来的track id,而非自动生成
|
|
88
|
+
jsvMainView.SetTrackId(props.setId);
|
|
83
89
|
}
|
|
84
|
-
|
|
85
|
-
|
|
90
|
+
|
|
91
|
+
props.getId?.(jsvMainView.GetTrackId());
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
onUnmounted(() => {
|
|
96
|
+
if (isBrowserDebug) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// 清理View管理缓存
|
|
101
|
+
if (innerViewId !== -1) {
|
|
102
|
+
Forge.sViewStore.remove(innerViewId);
|
|
103
|
+
innerViewId = -1;
|
|
104
|
+
jsvMainView = null;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (ninePatchSet != null) {
|
|
108
|
+
JsvTextureStoreApi.deleteTexture(ninePatchSet.textureName); // 释放texture资源
|
|
109
|
+
}
|
|
110
|
+
});
|
|
86
111
|
</script>
|
|
87
112
|
|
|
88
113
|
<template>
|
|
@@ -91,14 +116,42 @@ export default {
|
|
|
91
116
|
:style="{
|
|
92
117
|
left: style.left,
|
|
93
118
|
top: style.top,
|
|
94
|
-
width: style.width,
|
|
95
|
-
height: style.height,
|
|
96
119
|
}"
|
|
97
|
-
:data-jsv-vw-innerview="innerViewId"
|
|
98
120
|
>
|
|
99
|
-
<
|
|
121
|
+
<jsv-nine-patch
|
|
122
|
+
v-if="ninePatchSet != null"
|
|
123
|
+
:style="{
|
|
124
|
+
width: style.width,
|
|
125
|
+
height: style.height,
|
|
126
|
+
}"
|
|
127
|
+
:imageUrl="`jsvtexturestore://${ninePatchSet.textureName}`"
|
|
128
|
+
:imageWidth="ninePatchSet.imageSize"
|
|
129
|
+
:centerWidth="1"
|
|
130
|
+
:borderOutset="0"
|
|
131
|
+
:waitForInit="false"
|
|
132
|
+
imageBlendType="alphaOverride"
|
|
133
|
+
/>
|
|
134
|
+
<div
|
|
135
|
+
v-else
|
|
136
|
+
:style="{
|
|
137
|
+
width: style.width,
|
|
138
|
+
height: style.height,
|
|
139
|
+
backgroundColor: 'rgba(0,0,0,0)',
|
|
140
|
+
JsvImageBlendType: 'alphaOverride',
|
|
141
|
+
}"
|
|
142
|
+
/>
|
|
143
|
+
<div
|
|
144
|
+
:style="{
|
|
145
|
+
width: style.width,
|
|
146
|
+
height: style.height,
|
|
147
|
+
}"
|
|
148
|
+
:data-jsv-vw-innerview="innerViewId"
|
|
149
|
+
>
|
|
150
|
+
<slot />
|
|
151
|
+
</div>
|
|
100
152
|
</div>
|
|
153
|
+
|
|
101
154
|
<div v-else :style="{ ...style }">
|
|
102
155
|
<slot />
|
|
103
156
|
</div>
|
|
104
|
-
</template>
|
|
157
|
+
</template>
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* animTime {int} (必填)缩放动画的时长(单位秒)
|
|
16
16
|
* waitForInit {boolean} (选填)尺寸为0时是否进行描画(例如: 首次显示不展示动画的场合,设置为true),默认值为true
|
|
17
17
|
* onTransitionEnd { Function } (选填)transition动画结束的回调
|
|
18
|
+
* imageBlendType {String} (选填) alpha合并模式,默认为普通合成,可设置"alphaOverride", 用于Video挖洞操作
|
|
18
19
|
-->
|
|
19
20
|
|
|
20
21
|
<script setup>
|
|
@@ -39,7 +40,8 @@ const props = defineProps({
|
|
|
39
40
|
borderOutset: { type: Number, required: true },
|
|
40
41
|
animTime: { type: Number, default: 0 },
|
|
41
42
|
onTransitionEnd: { type: Function },
|
|
42
|
-
animation: { type: String }
|
|
43
|
+
animation: { type: String },
|
|
44
|
+
imageBlendType: { type: String, default: null },
|
|
43
45
|
});
|
|
44
46
|
|
|
45
47
|
const isReady = () => {
|
|
@@ -102,6 +104,7 @@ watchEffect(() => {
|
|
|
102
104
|
borderImage: `url(${imageUrl}) ${sliceWidth} fill`,
|
|
103
105
|
borderImageWidth: `${borderDspWidth}px`,
|
|
104
106
|
borderImageOutset: `${convertedBorderOutset}px`,
|
|
107
|
+
JsvImageBlendType: props.imageBlendType,
|
|
105
108
|
}"
|
|
106
109
|
@transitionend="props.onTransitionEnd"
|
|
107
110
|
/>
|
|
@@ -2,9 +2,12 @@
|
|
|
2
2
|
* 【模块 export 内容】
|
|
3
3
|
* JsvPosterImage:Vue高阶组件,海报描画,可设置color space 和 texture size
|
|
4
4
|
* props说明:
|
|
5
|
-
* colorSpace {String} 颜色空间,默认RGBA_8888
|
|
6
5
|
* style {Object} 包含left/top/width/height/border-radius的style设置
|
|
6
|
+
* colorSpace {String} 颜色空间,调整其他颜色空间可以节省内存,默认RGBA_8888
|
|
7
7
|
* imageCompress {boolean} 是否压缩图片, 默认打开
|
|
8
|
+
* src {string} 图片的加载地址
|
|
9
|
+
* fadeIn: {boolean} 图片加载完成是否有淡入效果,默认为打开
|
|
10
|
+
* isPosterImage: 标识是否用于海报位,对于海报位的内容,可以有下载线程控制等策略来优化整体体验
|
|
8
11
|
-->
|
|
9
12
|
|
|
10
13
|
<script setup>
|
|
@@ -14,25 +17,25 @@ import { JsvPerformance } from "../JsViewVueTools/JsvPerformance.ts";
|
|
|
14
17
|
const props = defineProps({
|
|
15
18
|
colorSpace: {
|
|
16
19
|
type: String,
|
|
17
|
-
default: "RGBA_8888"
|
|
20
|
+
default: "RGBA_8888",
|
|
18
21
|
},
|
|
19
22
|
imageCompress: {
|
|
20
23
|
type: Boolean,
|
|
21
|
-
default: true
|
|
24
|
+
default: true,
|
|
22
25
|
},
|
|
23
26
|
isPosterImage: {
|
|
24
27
|
type: Boolean,
|
|
25
|
-
default: true
|
|
28
|
+
default: true,
|
|
26
29
|
},
|
|
27
30
|
fadeIn: {
|
|
28
31
|
type: Boolean,
|
|
29
|
-
default: true
|
|
32
|
+
default: true,
|
|
30
33
|
},
|
|
31
34
|
src: {
|
|
32
35
|
type: String,
|
|
33
|
-
default: null
|
|
36
|
+
default: null,
|
|
34
37
|
},
|
|
35
|
-
style: Object
|
|
38
|
+
style: Object,
|
|
36
39
|
});
|
|
37
40
|
|
|
38
41
|
const scaleddown = computed(() => {
|
|
@@ -40,7 +43,9 @@ const scaleddown = computed(() => {
|
|
|
40
43
|
});
|
|
41
44
|
|
|
42
45
|
const isPosterImage = computed(() => {
|
|
43
|
-
return JsvPerformance.getPosterSingleThreadDecode() || props.isPosterImage
|
|
46
|
+
return JsvPerformance.getPosterSingleThreadDecode() || props.isPosterImage
|
|
47
|
+
? "true"
|
|
48
|
+
: "false";
|
|
44
49
|
});
|
|
45
50
|
|
|
46
51
|
let common_style = reactive({});
|
|
@@ -50,7 +55,15 @@ let show_background_holder = !!window.JsView; // PC浏览器模拟时, 不显示
|
|
|
50
55
|
watchEffect(() => {
|
|
51
56
|
if (props.style) {
|
|
52
57
|
// 提取left, top, width, height, 并去掉干扰项 backgroundImage backgroundColor(会引起同位置重复图片绘制)
|
|
53
|
-
let {
|
|
58
|
+
let {
|
|
59
|
+
left,
|
|
60
|
+
top,
|
|
61
|
+
width,
|
|
62
|
+
height,
|
|
63
|
+
backgroundImage,
|
|
64
|
+
backgroundColor,
|
|
65
|
+
...others
|
|
66
|
+
} = props.style;
|
|
54
67
|
|
|
55
68
|
// 承接x,y偏移和动画设置, 规避默认淡出动画被影响
|
|
56
69
|
common_style.left = left;
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
import { onMounted, ref } from "vue";
|
|
3
3
|
import QRCode from "qr.js";
|
|
4
4
|
|
|
5
|
+
const renderDocument = window.JsvCode.Dom.RenderDocument
|
|
6
|
+
? window.JsvCode.Dom.RenderDocument
|
|
7
|
+
: window.JsvCode.Dom.BrowserDocument;
|
|
8
|
+
|
|
5
9
|
const props = defineProps({
|
|
6
10
|
value: String,
|
|
7
11
|
size: Number,
|
|
@@ -147,7 +151,7 @@ const qrcodeRes = renderQrcode();
|
|
|
147
151
|
onMounted(() => {
|
|
148
152
|
svgRoot.value.jsvGetProxyView().RegisterOnProxyReady(() => {
|
|
149
153
|
const root = svgRoot.value.jsvGetProxyView().HtmlGetElement();
|
|
150
|
-
const doc =
|
|
154
|
+
const doc = renderDocument;
|
|
151
155
|
const svg = doc.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
152
156
|
svg.setAttribute("type", "qrcode");
|
|
153
157
|
svg.setAttribute("shapeRendering", "crispEdges");
|
|
@@ -182,4 +186,4 @@ onMounted(() => {
|
|
|
182
186
|
<div ref="svgRoot" :style="{ width: 100, height: 100 }"></div>
|
|
183
187
|
<div :style="imageStyle"></div>
|
|
184
188
|
</div>
|
|
185
|
-
</template>
|
|
189
|
+
</template>
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
* 【模块 export 内容】
|
|
3
|
+
* JsvScrollBox:Vue高阶组件,支持触控拖动的滚动型组件。
|
|
4
|
+
* props说明:
|
|
5
|
+
* style {Object} (必填,响应式) 其中的width/height为必填项目, 决定scroll固定的底座的尺寸
|
|
6
|
+
* sliderSize {Object} (必填,响应式) 滑动区域的尺寸,滑块的尺寸在非滑动方向不能大于组件尺寸
|
|
7
|
+
* {
|
|
8
|
+
* width {number}, 当VERTICAL滑动模式时为选填,HORIZONTAL为必填
|
|
9
|
+
* height {number}, 当HORIZONTAL滑动模式时为选填,VERTICAL为必填
|
|
10
|
+
* }
|
|
11
|
+
* mode {ScrollStyle.DrawerMode/ScrollStyle.PinMode}
|
|
12
|
+
* 选填, 非响应式, 默认为 PinMode
|
|
13
|
+
* 运动模式选择, DrawerMode: 抽屉模式,内容尺寸大于固定底座
|
|
14
|
+
* PinMode: 滚动杆模式,内容尺寸小于固定底座
|
|
15
|
+
* direction {import VERTICAL/HORIZONTAL} (必填,非响应式) 滑动方向
|
|
16
|
+
* enableFling {boolean} (选填,非响应式) 是否需要支持fling,默认为false
|
|
17
|
+
* initPercent {Number} (选填,非响应式) 滑块起始位置,等同于mount后进行updatePercent()
|
|
18
|
+
*
|
|
19
|
+
* template说明:
|
|
20
|
+
* FfixedBox={boxWidth, boxHeight}: 以本组件底座左上角0,0对齐的一个slot
|
|
21
|
+
* SliderBox={boxWidth, boxHeight}: 以滑块div的左上角0,0对齐的一个slot,
|
|
22
|
+
*
|
|
23
|
+
* expose函数说明:
|
|
24
|
+
* setSensor(sensitivity:number, callback:Function<percent:number, x:number, y:number>) 设置运动后触发的回调
|
|
25
|
+
* sensitivity为回调敏感度, 每移动多少像素进行回调,适当放大(推荐10以上)可以极大减小对js回调过多引起的性能降低
|
|
26
|
+
* updatePercent(percent:number) 设置滚动调位置(百分比),百分比 = (SliderTop - 底座Top) / Slider可滑动总区域
|
|
27
|
+
* Slider可滑动总区域 = 底座Height - SliderHeight
|
|
28
|
+
* 当为横向运动时,Top被Left代换,Height被Width代换
|
|
29
|
+
* syncWith(otherScrollBox: JsvScrollBox, syncMode: ScrollStyle)
|
|
30
|
+
* 本滚动条的进度跟随给定的滚动条的进度移动
|
|
31
|
+
* otherScrollBox: 控制者
|
|
32
|
+
* syncMode: 同步模式,有 SyncParallel, SyncRevert
|
|
33
|
+
* addSubSync(view: div|JsvNinePatch, syncMode: ScrollStyle)
|
|
34
|
+
* 将外部的div或者JsvNinePatch加入到同步尺寸同步改动器中。
|
|
35
|
+
* view只能是div或者JsvNinePatch, 并且不能有style.animation的控制
|
|
36
|
+
* 当SyncParallel模式时, 这个div的初始位置要和本组件的0,0对齐
|
|
37
|
+
* 当SyncRevert模式时, 这个div的初始位置要和本组件尾部位置(0, height/width)对齐
|
|
38
|
+
*
|
|
39
|
+
*
|
|
40
|
+
-->
|
|
41
|
+
|
|
42
|
+
<template>
|
|
43
|
+
<div
|
|
44
|
+
:style="{
|
|
45
|
+
top: rProps.style?.top,
|
|
46
|
+
left: rProps.style?.left,
|
|
47
|
+
}"
|
|
48
|
+
>
|
|
49
|
+
<div
|
|
50
|
+
ref="rFixedViewRef"
|
|
51
|
+
:style="{
|
|
52
|
+
width: rFixedBoxWidth,
|
|
53
|
+
height: rFixedBoxHeight,
|
|
54
|
+
}"
|
|
55
|
+
>
|
|
56
|
+
<slot
|
|
57
|
+
name="FixedBox"
|
|
58
|
+
:boxWidth="rFixedBoxWidth"
|
|
59
|
+
:boxHeight="rFixedBoxHeight"
|
|
60
|
+
/>
|
|
61
|
+
<div
|
|
62
|
+
ref="rSliderViewRef"
|
|
63
|
+
:style="{
|
|
64
|
+
width: rSliderWidth,
|
|
65
|
+
height: rSliderHeight,
|
|
66
|
+
}"
|
|
67
|
+
>
|
|
68
|
+
<slot
|
|
69
|
+
name="SliderBox"
|
|
70
|
+
:boxWidth="rSliderWidth"
|
|
71
|
+
:boxHeight="rSliderHeight"
|
|
72
|
+
/>
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
76
|
+
</template>
|
|
77
|
+
|
|
78
|
+
<script setup lang="ts">
|
|
79
|
+
import {
|
|
80
|
+
shallowRef,
|
|
81
|
+
watchEffect,
|
|
82
|
+
onMounted,
|
|
83
|
+
defineExpose,
|
|
84
|
+
defineProps,
|
|
85
|
+
} from "vue";
|
|
86
|
+
import ActControl from "../../JsViewVueWidget/JsvFreeMoveActor/ActorControl";
|
|
87
|
+
import { VERTICAL, HORIZONTAL } from "../../JsViewVueTools/ConstSymbol";
|
|
88
|
+
import { ScrollStyle } from "./ScrollSymbol";
|
|
89
|
+
import { ForgeConst } from "../../JsViewVueTools/ForgeConstDefine";
|
|
90
|
+
|
|
91
|
+
let rProps = defineProps({
|
|
92
|
+
// 底座的尺寸
|
|
93
|
+
style: {
|
|
94
|
+
type: Object,
|
|
95
|
+
require: true,
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
// 滑动允许方向(VERTICAL / HORIZONTAL)
|
|
99
|
+
direction: {
|
|
100
|
+
type: Symbol,
|
|
101
|
+
require: true,
|
|
102
|
+
},
|
|
103
|
+
|
|
104
|
+
// 滑块的尺寸,垂直于direction的轴不用设置
|
|
105
|
+
sliderSize: {
|
|
106
|
+
type: Object, // {width, height}
|
|
107
|
+
require: true,
|
|
108
|
+
},
|
|
109
|
+
|
|
110
|
+
// 滑块模式
|
|
111
|
+
// ScrollStyle.PinMode: 滑块小于底座
|
|
112
|
+
// ScrollStyle.DrawerMode: 滑块大于底座
|
|
113
|
+
mode: {
|
|
114
|
+
type: Symbol,
|
|
115
|
+
default: ScrollStyle.PinMode,
|
|
116
|
+
},
|
|
117
|
+
|
|
118
|
+
// 初始进度条的进度
|
|
119
|
+
initPercent: {
|
|
120
|
+
type: Number,
|
|
121
|
+
default: 0,
|
|
122
|
+
},
|
|
123
|
+
|
|
124
|
+
enableFling: {
|
|
125
|
+
type: Boolean,
|
|
126
|
+
default: false,
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
/** 本地常量 **/
|
|
131
|
+
const cDirection = rProps.direction;
|
|
132
|
+
const cMode = rProps.mode;
|
|
133
|
+
const cInitPercent = rProps.initPercent;
|
|
134
|
+
const cEnableFling = rProps.enableFling;
|
|
135
|
+
const cSliderActor = new ActControl();
|
|
136
|
+
const cFixedBoxActor = cMode == ScrollStyle.PinMode ? new ActControl() : null;
|
|
137
|
+
|
|
138
|
+
// Actor condition group id(1~9可任意用)
|
|
139
|
+
const cWallConditionGroup = 1;
|
|
140
|
+
const cSensorConditionGroup = 2;
|
|
141
|
+
|
|
142
|
+
/** 本地非响应式变量 **/
|
|
143
|
+
let vMounted = false;
|
|
144
|
+
let vHorizontalGap = 0;
|
|
145
|
+
let vVerticalGap = 0;
|
|
146
|
+
let vSubSyncList = [];
|
|
147
|
+
|
|
148
|
+
/** 本地响应式变量 **/
|
|
149
|
+
let rFixedBoxWidth = shallowRef(NaN);
|
|
150
|
+
let rFixedBoxHeight = shallowRef(NaN);
|
|
151
|
+
let rFixedViewRef = shallowRef(null);
|
|
152
|
+
let rSliderWidth = shallowRef(NaN);
|
|
153
|
+
let rSliderHeight = shallowRef(NaN);
|
|
154
|
+
let rSliderViewRef = shallowRef(null);
|
|
155
|
+
|
|
156
|
+
watchEffect(() => {
|
|
157
|
+
let fixedBoxSize = {
|
|
158
|
+
width: rProps.style!.width,
|
|
159
|
+
height: rProps.style!.height,
|
|
160
|
+
}; // 从响应式props中复制值
|
|
161
|
+
|
|
162
|
+
let sliderSize = {
|
|
163
|
+
width: rProps.sliderSize!.width,
|
|
164
|
+
height: rProps.sliderSize!.height,
|
|
165
|
+
}; // 从响应式props中复制值
|
|
166
|
+
|
|
167
|
+
// 补正slider另一个不需要设置的边
|
|
168
|
+
if (cDirection == VERTICAL) {
|
|
169
|
+
sliderSize.width = fixedBoxSize.width;
|
|
170
|
+
} else {
|
|
171
|
+
sliderSize.height = fixedBoxSize.height;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// 合理性校验
|
|
175
|
+
if (
|
|
176
|
+
cMode == ScrollStyle.PinMode &&
|
|
177
|
+
(sliderSize.height > fixedBoxSize.height ||
|
|
178
|
+
sliderSize.width > fixedBoxSize.width)
|
|
179
|
+
) {
|
|
180
|
+
// PinMode检测错误,滑块大于了底座
|
|
181
|
+
console.error(
|
|
182
|
+
`slider oversize in pin-mode bw=${fixedBoxSize.width} bh=${fixedBoxSize.height} sw=${sliderSize.width} sh=${sliderSize.height}`
|
|
183
|
+
);
|
|
184
|
+
return;
|
|
185
|
+
} else if (
|
|
186
|
+
cMode == ScrollStyle.DrawerMode &&
|
|
187
|
+
(sliderSize.height < fixedBoxSize.height ||
|
|
188
|
+
sliderSize.width < fixedBoxSize.width)
|
|
189
|
+
) {
|
|
190
|
+
console.error(
|
|
191
|
+
`box oversize in drawer-mode bw=${fixedBoxSize.width} bh=${fixedBoxSize.height} sw=${sliderSize.width} sh=${sliderSize.height}`
|
|
192
|
+
);
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// 变更检查,尽量减少触发template的响应式
|
|
197
|
+
if (
|
|
198
|
+
sliderSize.width != rSliderWidth.value ||
|
|
199
|
+
sliderSize.height != rSliderHeight.value ||
|
|
200
|
+
fixedBoxSize.width != rFixedBoxWidth.value ||
|
|
201
|
+
fixedBoxSize.height != rFixedBoxHeight.value
|
|
202
|
+
) {
|
|
203
|
+
// 更新template
|
|
204
|
+
rSliderWidth.value = sliderSize.width;
|
|
205
|
+
rSliderHeight.value = sliderSize.height;
|
|
206
|
+
rFixedBoxWidth.value = fixedBoxSize.width;
|
|
207
|
+
rFixedBoxHeight.value = fixedBoxSize.height;
|
|
208
|
+
|
|
209
|
+
rebuildSliderSet();
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
function rebuildSliderSet() {
|
|
214
|
+
if (vMounted) {
|
|
215
|
+
// 计算slider的活动区域
|
|
216
|
+
// 运动区域无论正负都通用的算法
|
|
217
|
+
vHorizontalGap = rFixedBoxWidth.value - rSliderWidth.value;
|
|
218
|
+
vVerticalGap = rFixedBoxHeight.value - rSliderHeight.value;
|
|
219
|
+
|
|
220
|
+
cSliderActor.run([
|
|
221
|
+
cSliderActor.state().removeConditionByGroup(cWallConditionGroup),
|
|
222
|
+
cSliderActor
|
|
223
|
+
.condition(cWallConditionGroup, true)
|
|
224
|
+
.boxPosition(
|
|
225
|
+
vHorizontalGap > 0 ? 0 : vHorizontalGap, // left
|
|
226
|
+
vVerticalGap > 0 ? 0 : vVerticalGap, // top
|
|
227
|
+
vHorizontalGap < 0 ? 0 : vHorizontalGap, // right
|
|
228
|
+
vVerticalGap < 0 ? 0 : vVerticalGap // bottom
|
|
229
|
+
)!
|
|
230
|
+
.then([cSliderActor.action().stopMoving(true)]),
|
|
231
|
+
]);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// setSensor 函数声明
|
|
236
|
+
function setSensor(callback: Function, sensitivity: number) {
|
|
237
|
+
cSliderActor.run([
|
|
238
|
+
cSliderActor.state().removeConditionByGroup(cSensorConditionGroup),
|
|
239
|
+
]);
|
|
240
|
+
if (callback != null) {
|
|
241
|
+
cSliderActor.run([
|
|
242
|
+
cSliderActor
|
|
243
|
+
.condition(cSensorConditionGroup, true)
|
|
244
|
+
.onMovement(sensitivity) // 设置x或y移动超过12时才触发回调,以此减少回调的频次,规避js的性能影响
|
|
245
|
+
.then([
|
|
246
|
+
(pointInfo: any) => {
|
|
247
|
+
let percent =
|
|
248
|
+
cDirection == HORIZONTAL
|
|
249
|
+
? pointInfo.xPos / vHorizontalGap
|
|
250
|
+
: pointInfo.yPos / vVerticalGap;
|
|
251
|
+
callback(percent, pointInfo.xPos, pointInfo.yPos);
|
|
252
|
+
},
|
|
253
|
+
]),
|
|
254
|
+
]);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// updatePercent 函数声明
|
|
259
|
+
function updatePercent(percent: number) {
|
|
260
|
+
let xPos: number = 0;
|
|
261
|
+
let yPos: number = 0;
|
|
262
|
+
if (cDirection == HORIZONTAL) {
|
|
263
|
+
xPos = Math.floor(percent * vHorizontalGap);
|
|
264
|
+
} else {
|
|
265
|
+
yPos = Math.floor(percent * vVerticalGap);
|
|
266
|
+
}
|
|
267
|
+
cSliderActor.run([cSliderActor.action().teleportTo(xPos, yPos)]);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
onMounted(() => {
|
|
271
|
+
vMounted = true;
|
|
272
|
+
|
|
273
|
+
// 构建slider的FreeMove控制对象
|
|
274
|
+
let sliderView = (rSliderViewRef.value as any).jsvGetProxyView();
|
|
275
|
+
cSliderActor.bindForgeView(sliderView, true);
|
|
276
|
+
sliderView.DragEnables?.(
|
|
277
|
+
ForgeConst.DragFlags.TOUCH_RECV_MOVE_BIT |
|
|
278
|
+
(cEnableFling ? ForgeConst.DragFlags.TOUCH_RECV_FLING_BIT : 0) |
|
|
279
|
+
ForgeConst.DragFlags.TOUCH_RECV_FIRST_START |
|
|
280
|
+
ForgeConst.DragFlags.TOUCH_RECV_LAST_END
|
|
281
|
+
); // 激活 Move | TouchDown | TouchEnd
|
|
282
|
+
|
|
283
|
+
// 设置初始进度
|
|
284
|
+
if (cInitPercent != 0) {
|
|
285
|
+
updatePercent(cInitPercent);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
if (cFixedBoxActor != null) {
|
|
289
|
+
// 父节点激活 touchDown 和 touchAttractChild
|
|
290
|
+
// 用于点击滑动区域时,将子节点拖过来
|
|
291
|
+
let fixedBoxView = (rFixedViewRef.value as any).jsvGetProxyView();
|
|
292
|
+
cFixedBoxActor.bindForgeView(fixedBoxView, true);
|
|
293
|
+
fixedBoxView.DragEnables?.(ForgeConst.DragFlags.TOUCH_RECV_FIRST_START); // 仅激活touchDown即可捕获并触发 TouchAttractChild
|
|
294
|
+
cFixedBoxActor.run([
|
|
295
|
+
cFixedBoxActor.state().setTouchAttractChild(cSliderActor),
|
|
296
|
+
]);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// 设置滑动区域和关联区域
|
|
300
|
+
rebuildSliderSet();
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
defineExpose({
|
|
304
|
+
setSensor,
|
|
305
|
+
updatePercent,
|
|
306
|
+
});
|
|
307
|
+
</script>
|
|
308
|
+
|
|
309
|
+
<style lang="scss" scoped></style>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
const ScrollStyle = {
|
|
4
|
+
// 运动模式
|
|
5
|
+
DrawerMode: Symbol("DrawerMode"),
|
|
6
|
+
PinMode: Symbol("PinMode"),
|
|
7
|
+
|
|
8
|
+
// 同步模式
|
|
9
|
+
SyncParallel: Symbol("AckParallel"), // 百分比完全对齐的同步模式
|
|
10
|
+
SyncRevert: Symbol("SyncRevert"), // (1-百分比)的同步模式
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export {
|
|
14
|
+
ScrollStyle
|
|
15
|
+
}
|