@shijiu/jsview-vue-samples 2.1.25 → 2.1.200
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/Basic/components/div/DivBackground.vue +53 -24
- package/BreakRender/App.vue +69 -0
- package/BreakRender/Item.vue +77 -0
- package/BreakRender/assets/imageList.json +237 -0
- package/BreakRender/data.js +18 -0
- package/ClassDynamicSwitching/App.vue +83 -0
- package/ClassDynamicSwitching/components/ClassItem.vue +257 -0
- package/ClassDynamicSwitching/components/ClassShow.vue +78 -0
- package/ClassDynamicSwitching/components/StyleItem.vue +165 -0
- package/ClassDynamicSwitching/components/StyleShow.vue +68 -0
- package/DemoHomepage/router.js +67 -13
- package/DemoHomepage/views/Homepage.vue +13 -2
- package/DynamicClass/App.vue +115 -0
- package/DynamicClass/components/FloorItem.vue +55 -0
- package/DynamicClass/components/FloorList.vue +210 -0
- package/DynamicClass/style1.json +163 -0
- package/DynamicClass/style2.json +164 -0
- package/FilterDemo/App.vue +1 -1
- package/FocusMoveStyle/App.vue +10 -2
- package/FreeMove/App.vue +291 -0
- package/GetBoundingClientRect/App.vue +177 -0
- package/GiftRain/App.vue +3 -3
- package/JsvLine/App.vue +116 -0
- package/JsvLine/bgimage.jpg +0 -0
- package/JsvPreDownloader/App.vue +17 -10
- package/LatexDemo/App.vue +66 -0
- package/LatexFormula/App.vue +65 -0
- package/Marquee/App.vue +711 -183
- package/MetroWidgetDemos/PingPong/App.vue +0 -9
- package/MetroWidgetDemos/PingPong/AppPage.vue +2 -1
- package/MetroWidgetDemos/PingPong/WidgetItem.vue +0 -5
- package/MetroWidgetDemos/SkeletonDiagram/App.vue +3 -1
- package/MetroWidgetDemos/SkeletonDiagram/Item.vue +5 -0
- package/MetroWidgetDemos/itemSizeUpdate/App.vue +11 -4
- package/MetroWidgetDemos/itemSizeUpdate/backward/Backward.vue +6 -4
- package/MetroWidgetDemos/itemSizeUpdate/backward/Item.vue +2 -25
- package/MetroWidgetDemos/itemSizeUpdate/center/Center.vue +6 -6
- package/MetroWidgetDemos/itemSizeUpdate/center/Item.vue +38 -49
- package/MetroWidgetDemos/itemSizeUpdate/stretch/App.vue +122 -0
- package/MetroWidgetDemos/itemSizeUpdate/stretch/Item.vue +105 -0
- package/MindMap/App.vue +61 -0
- package/MindMap/Item.vue +40 -0
- package/MindMap/data.js +86 -0
- package/Preload/App.vue +25 -18
- package/Preload/Item.vue +1 -1
- package/Preload/data.js +12 -12
- package/Preload/images/bg_btn.png +0 -0
- package/Preload/images/bg_btn_focus.png +0 -0
- package/Preload/images/btn_cancle.png +0 -0
- package/Preload/images/btn_ok.png +0 -0
- package/Preload/images/tease.png +0 -0
- package/Preload/images/tease_lock.png +0 -0
- package/SecTorTest/App.vue +106 -0
- package/TextureStoreTest/App.vue +168 -0
- package/VisibleSensorDemo/App.vue +38 -18
- package/package.json +1 -1
- package/Preload/images/rank.png +0 -0
- package/Preload/images/rank_focus.png +0 -0
- package/Preload/images/rule.png +0 -0
- package/Preload/images/rule_focus.png +0 -0
- package/Preload/images/start.png +0 -0
- package/Preload/images/start_focus.png +0 -0
|
@@ -34,21 +34,12 @@ for (let i = 0; i < 10; ++i) {
|
|
|
34
34
|
});
|
|
35
35
|
const pageData = [];
|
|
36
36
|
for (let j = 0; j < 10; ++j) {
|
|
37
|
-
let floorType = 0; // 0: 默认; 1: 不滚动; 2: 首屏最后一个楼层
|
|
38
|
-
if (i == 0) {
|
|
39
|
-
if (j == 0 || j == 1) {
|
|
40
|
-
floorType = 1;
|
|
41
|
-
} else if (j == 2) {
|
|
42
|
-
floorType = 2;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
37
|
pageData.push({
|
|
46
38
|
width: 500,
|
|
47
39
|
height: 170,
|
|
48
40
|
name: "testPage_" + i + "-" + "widget_" + j,
|
|
49
41
|
marginBottom: 10,
|
|
50
42
|
index: j,
|
|
51
|
-
floorType,
|
|
52
43
|
});
|
|
53
44
|
}
|
|
54
45
|
pageList.push({
|
|
@@ -29,6 +29,7 @@ const widgetRef = shallowRef(null);
|
|
|
29
29
|
const slideSetting = props.data.tabIndex == 0 ? new SeamlessSlide({
|
|
30
30
|
startPercent: 0.5,
|
|
31
31
|
endPercent: 0.5,
|
|
32
|
+
fixFirstPage: true,
|
|
32
33
|
}) : new SeamlessSlide();
|
|
33
34
|
|
|
34
35
|
const provideData = () => {
|
|
@@ -38,7 +39,7 @@ const measures = (item) => {
|
|
|
38
39
|
return {
|
|
39
40
|
width: item.width,
|
|
40
41
|
height: item.height,
|
|
41
|
-
itemSlide:
|
|
42
|
+
itemSlide: METRO_WIDGET_CONST.ITEM_SLIDE.ACT_FOCUS_RECT_EVENT,
|
|
42
43
|
};
|
|
43
44
|
};
|
|
44
45
|
|
|
@@ -45,11 +45,6 @@ const onFocus = (rect) => {
|
|
|
45
45
|
//获得焦点时需要做就近移动的处理, 因此需要通过setEnterFocusRect设置寻找最近焦点的区域
|
|
46
46
|
mwRef.value?.setEnterFocusRect(rect);
|
|
47
47
|
focusHub.setFocus(props.data.name);
|
|
48
|
-
|
|
49
|
-
//首屏不动时, 末尾楼层获得焦点时滚动到0
|
|
50
|
-
if (props.data.floorType == 2) {
|
|
51
|
-
props.query.widgetHandler.slideTo(0, true);
|
|
52
|
-
}
|
|
53
48
|
};
|
|
54
49
|
const onBlur = () => {
|
|
55
50
|
//onBlur时需要返还焦点给父MetroWidget
|
|
@@ -17,7 +17,7 @@ const measures = (item) => {
|
|
|
17
17
|
width: item.width,
|
|
18
18
|
height: item.height,
|
|
19
19
|
marginRight: 10,
|
|
20
|
-
|
|
20
|
+
marginBottom: 10,
|
|
21
21
|
};
|
|
22
22
|
};
|
|
23
23
|
|
|
@@ -60,6 +60,8 @@ onMounted(() => {
|
|
|
60
60
|
:enableItemRenderBreak="true"
|
|
61
61
|
:placeHolderSetting="{
|
|
62
62
|
backgroundColor: 'rgba(78,105,127, 0.8)',
|
|
63
|
+
focusBackgroundColor: '#770088aa',
|
|
64
|
+
borderRadius: 10,
|
|
63
65
|
gap: 10,
|
|
64
66
|
}"
|
|
65
67
|
>
|
|
@@ -50,6 +50,7 @@ props.onAction.register("onClick", onClicked);
|
|
|
50
50
|
width: props.data.width + 20,
|
|
51
51
|
height: props.data.height + 20,
|
|
52
52
|
backgroundColor: '#770088',
|
|
53
|
+
borderRadius: 10,
|
|
53
54
|
}"
|
|
54
55
|
>
|
|
55
56
|
</div>
|
|
@@ -58,6 +59,7 @@ props.onAction.register("onClick", onClicked);
|
|
|
58
59
|
:style="{
|
|
59
60
|
width: data.width,
|
|
60
61
|
height: data.height,
|
|
62
|
+
borderRadius: 10,
|
|
61
63
|
}"
|
|
62
64
|
:src="data.url"
|
|
63
65
|
>
|
|
@@ -66,6 +68,7 @@ props.onAction.register("onClick", onClicked);
|
|
|
66
68
|
width: data.width,
|
|
67
69
|
height: data.height,
|
|
68
70
|
backgroundColor: '#ff0000',
|
|
71
|
+
borderRadius: 10,
|
|
69
72
|
}"
|
|
70
73
|
/>
|
|
71
74
|
</jsv-poster-image>
|
|
@@ -86,6 +89,7 @@ props.onAction.register("onClick", onClicked);
|
|
|
86
89
|
width: data.width,
|
|
87
90
|
height: data.height,
|
|
88
91
|
backgroundImage: `url(${data.url})`,
|
|
92
|
+
borderRadius: 10,
|
|
89
93
|
}"
|
|
90
94
|
>
|
|
91
95
|
<div
|
|
@@ -93,6 +97,7 @@ props.onAction.register("onClick", onClicked);
|
|
|
93
97
|
width: data.width,
|
|
94
98
|
height: data.height,
|
|
95
99
|
backgroundColor: '#ff0000',
|
|
100
|
+
borderRadius: 10,
|
|
96
101
|
}"
|
|
97
102
|
/>
|
|
98
103
|
</jsv-poster-div>
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import { useFocusHub } from "jsview";
|
|
8
8
|
import Center from "./center/Center.vue";
|
|
9
9
|
import Backward from "./backward/Backward.vue";
|
|
10
|
+
import Stretch from "./stretch/App.vue";
|
|
10
11
|
|
|
11
12
|
import { onMounted } from "vue";
|
|
12
13
|
|
|
@@ -26,23 +27,29 @@ onMounted(() => {
|
|
|
26
27
|
}"
|
|
27
28
|
>
|
|
28
29
|
<div :style="{ left: 150, top: 10 }" class="text">
|
|
29
|
-
|
|
30
|
+
获焦后放大, 按ok键可以控制放大/缩小, 放大动画以中心为锚点
|
|
30
31
|
</div>
|
|
31
32
|
<div :style="{ left: 150, top: 50 }">
|
|
32
33
|
<center />
|
|
33
34
|
</div>
|
|
34
|
-
<div :style="{ left: 150, top:
|
|
35
|
+
<div :style="{ left: 150, top: 220 }" class="text">
|
|
35
36
|
获焦一秒后放大, 放大动画以左侧为锚点
|
|
36
37
|
</div>
|
|
37
|
-
<div :style="{ left: 150, top:
|
|
38
|
+
<div :style="{ left: 150, top: 260 }">
|
|
38
39
|
<backward />
|
|
39
40
|
</div>
|
|
41
|
+
<div :style="{ left: 150, top: 430 }" class="text">
|
|
42
|
+
推拉组件
|
|
43
|
+
</div>
|
|
44
|
+
<div :style="{ left: 150, top: 470 }">
|
|
45
|
+
<stretch />
|
|
46
|
+
</div>
|
|
40
47
|
</div>
|
|
41
48
|
</template>
|
|
42
49
|
|
|
43
50
|
<style scoped>
|
|
44
51
|
.text {
|
|
45
|
-
width:
|
|
52
|
+
width: 1280;
|
|
46
53
|
height: 30;
|
|
47
54
|
line-height: 30;
|
|
48
55
|
font-size: 25;
|
|
@@ -30,7 +30,7 @@ const provideData = () => {
|
|
|
30
30
|
for (let i = 0; i < dataLength; ++i) {
|
|
31
31
|
data.push({
|
|
32
32
|
width: 100,
|
|
33
|
-
height:
|
|
33
|
+
height: 100,
|
|
34
34
|
marginRight: 10,
|
|
35
35
|
color: randomColor(),
|
|
36
36
|
content: i,
|
|
@@ -51,6 +51,8 @@ const measures = (data) => {
|
|
|
51
51
|
const onEdge = (edgeInfo) => {
|
|
52
52
|
if (edgeInfo.direction == EdgeDirection.top) {
|
|
53
53
|
focusHub.setFocus("itemResizeCenter");
|
|
54
|
+
} else if (edgeInfo.direction == EdgeDirection.bottom) {
|
|
55
|
+
focusHub.setFocus("stretch");
|
|
54
56
|
}
|
|
55
57
|
};
|
|
56
58
|
|
|
@@ -58,14 +60,14 @@ const widgetLayout = {
|
|
|
58
60
|
left: 0,
|
|
59
61
|
top: 0,
|
|
60
62
|
width: 600,
|
|
61
|
-
height:
|
|
63
|
+
height: 120,
|
|
62
64
|
};
|
|
63
65
|
|
|
64
66
|
const padding = {
|
|
65
67
|
left: 25,
|
|
66
|
-
top:
|
|
68
|
+
top: 10,
|
|
67
69
|
right: 25,
|
|
68
|
-
bottom:
|
|
70
|
+
bottom: 10,
|
|
69
71
|
};
|
|
70
72
|
|
|
71
73
|
const name = "itemResizeBackward";
|
|
@@ -28,16 +28,15 @@ const focusHub = useFocusHub();
|
|
|
28
28
|
const focused = ref(false);
|
|
29
29
|
|
|
30
30
|
const width = ref(props.data.width);
|
|
31
|
-
let innerWidth = props.data.width;
|
|
32
31
|
const duration = 200;
|
|
33
32
|
|
|
34
33
|
let timeoutHandler = -1;
|
|
35
34
|
|
|
36
|
-
let originPadding;
|
|
37
35
|
const animInfo = {
|
|
36
|
+
anchor: 0,
|
|
38
37
|
duration: duration,
|
|
39
38
|
onEnd: () => {
|
|
40
|
-
console.log("resize end");
|
|
39
|
+
console.log("resize end", props.query.index);
|
|
41
40
|
},
|
|
42
41
|
};
|
|
43
42
|
|
|
@@ -52,22 +51,6 @@ const onFocus = () => {
|
|
|
52
51
|
width: width.value,
|
|
53
52
|
height: props.data.height,
|
|
54
53
|
},
|
|
55
|
-
{
|
|
56
|
-
type: METRO_WIDGET_CONST.ITEM_RESIZE.CUSTOMER_SET,
|
|
57
|
-
func: (oldRect, newRect, oldItemPadding) => {
|
|
58
|
-
originPadding = oldItemPadding;
|
|
59
|
-
if (oldItemPadding + newRect.width > props.widgetLayout.width) {
|
|
60
|
-
//新的item超出了widget的宽度
|
|
61
|
-
return (
|
|
62
|
-
props.widgetLayout.width -
|
|
63
|
-
newRect.width -
|
|
64
|
-
props.widgetPadding.right
|
|
65
|
-
);
|
|
66
|
-
} else {
|
|
67
|
-
return oldItemPadding;
|
|
68
|
-
}
|
|
69
|
-
},
|
|
70
|
-
},
|
|
71
54
|
animInfo
|
|
72
55
|
);
|
|
73
56
|
}, 1000); /* 延迟1秒变化 */
|
|
@@ -84,12 +67,6 @@ const onBlur = () => {
|
|
|
84
67
|
width: width.value,
|
|
85
68
|
height: props.data.height,
|
|
86
69
|
},
|
|
87
|
-
{
|
|
88
|
-
type: METRO_WIDGET_CONST.ITEM_RESIZE.CUSTOMER_SET,
|
|
89
|
-
func: (oldRect, newRect, oldItemPadding) => {
|
|
90
|
-
return originPadding;
|
|
91
|
-
},
|
|
92
|
-
},
|
|
93
70
|
animInfo
|
|
94
71
|
);
|
|
95
72
|
}
|
|
@@ -18,7 +18,7 @@ const focusHub = useFocusHub();
|
|
|
18
18
|
const randomColor = () => {
|
|
19
19
|
let randomColor = Math.round(Math.random() * 2 ** 24).toString(16);
|
|
20
20
|
return (
|
|
21
|
-
"#" + new Array(6 - randomColor.length).fill("0").join("") + randomColor
|
|
21
|
+
"#" + new Array(6 - randomColor.length).fill("0").join("") + randomColor + "77"
|
|
22
22
|
);
|
|
23
23
|
};
|
|
24
24
|
|
|
@@ -29,8 +29,8 @@ const provideData = () => {
|
|
|
29
29
|
const data = [];
|
|
30
30
|
for (let i = 0; i < dataLength; ++i) {
|
|
31
31
|
data.push({
|
|
32
|
-
width:
|
|
33
|
-
height:
|
|
32
|
+
width: 90,
|
|
33
|
+
height: 100,
|
|
34
34
|
marginRight: 10,
|
|
35
35
|
color: randomColor(),
|
|
36
36
|
content: i,
|
|
@@ -58,14 +58,14 @@ const widgetLayout = {
|
|
|
58
58
|
left: 0,
|
|
59
59
|
top: 0,
|
|
60
60
|
width: 600,
|
|
61
|
-
height:
|
|
61
|
+
height: 120,
|
|
62
62
|
};
|
|
63
63
|
|
|
64
64
|
const padding = {
|
|
65
65
|
left: 25,
|
|
66
|
-
top:
|
|
66
|
+
top: 10,
|
|
67
67
|
right: 25,
|
|
68
|
-
bottom:
|
|
68
|
+
bottom: 10,
|
|
69
69
|
};
|
|
70
70
|
|
|
71
71
|
const name = "itemResizeCenter";
|
|
@@ -4,15 +4,7 @@
|
|
|
4
4
|
* @Description: file content
|
|
5
5
|
-->
|
|
6
6
|
<script setup>
|
|
7
|
-
import {
|
|
8
|
-
ref,
|
|
9
|
-
shallowRef,
|
|
10
|
-
inject,
|
|
11
|
-
onUpdated,
|
|
12
|
-
onMounted,
|
|
13
|
-
onBeforeUnmount,
|
|
14
|
-
} from "vue";
|
|
15
|
-
import { METRO_WIDGET_CONST } from "jsview";
|
|
7
|
+
import { ref } from "vue";
|
|
16
8
|
|
|
17
9
|
const props = defineProps({
|
|
18
10
|
data: Object,
|
|
@@ -25,45 +17,31 @@ const focused = ref(false);
|
|
|
25
17
|
|
|
26
18
|
const width = ref(props.data.width);
|
|
27
19
|
const duration = 200;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
if (props.query.index == 0) {
|
|
33
|
-
return 0;
|
|
34
|
-
} else if (props.query.index == props.dataLength - 1) {
|
|
35
|
-
return 1;
|
|
36
|
-
} else {
|
|
37
|
-
return 0.5;
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
const locateSetting = {
|
|
42
|
-
type: METRO_WIDGET_CONST.ITEM_RESIZE.WIDGET_SET,
|
|
43
|
-
};
|
|
20
|
+
const transitionStr = `left ${duration / 1000}s, top ${
|
|
21
|
+
duration / 1000
|
|
22
|
+
}s, width ${duration / 1000}s, height ${duration / 1000}s`;
|
|
23
|
+
const transition = ref(transitionStr);
|
|
44
24
|
|
|
45
25
|
const animInfo = {
|
|
26
|
+
anchor: 0.5,
|
|
46
27
|
duration: duration,
|
|
47
28
|
onEnd: () => {
|
|
48
|
-
console.log("resize end");
|
|
29
|
+
console.log("resize end", props.query.index);
|
|
49
30
|
},
|
|
50
31
|
};
|
|
51
32
|
|
|
52
33
|
const onFocus = () => {
|
|
53
34
|
focused.value = true;
|
|
54
35
|
if (width.value == props.data.width) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
props.query.
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
animInfo
|
|
65
|
-
);
|
|
66
|
-
}, 1000); /* 延迟1秒变化 */
|
|
36
|
+
width.value = props.data.width + 200;
|
|
37
|
+
props.query.updateItemSize(
|
|
38
|
+
props.query.index,
|
|
39
|
+
{
|
|
40
|
+
width: width.value,
|
|
41
|
+
height: props.data.height,
|
|
42
|
+
},
|
|
43
|
+
animInfo
|
|
44
|
+
);
|
|
67
45
|
}
|
|
68
46
|
};
|
|
69
47
|
|
|
@@ -77,26 +55,39 @@ const onBlur = () => {
|
|
|
77
55
|
width: width.value,
|
|
78
56
|
height: props.data.height,
|
|
79
57
|
},
|
|
80
|
-
locateSetting,
|
|
81
58
|
animInfo
|
|
82
59
|
);
|
|
83
60
|
}
|
|
84
|
-
clearTimeout(timeoutHandler);
|
|
85
|
-
timeoutHandler = -1;
|
|
86
61
|
};
|
|
87
62
|
|
|
88
63
|
const onClick = () => {
|
|
89
64
|
console.log("onClick");
|
|
65
|
+
if (width.value == props.data.width) {
|
|
66
|
+
width.value = props.data.width + 200;
|
|
67
|
+
props.query.updateItemSize(
|
|
68
|
+
props.query.index,
|
|
69
|
+
{
|
|
70
|
+
width: width.value,
|
|
71
|
+
height: props.data.height,
|
|
72
|
+
},
|
|
73
|
+
animInfo
|
|
74
|
+
);
|
|
75
|
+
} else {
|
|
76
|
+
width.value = props.data.width;
|
|
77
|
+
props.query.updateItemSize(
|
|
78
|
+
props.query.index,
|
|
79
|
+
{
|
|
80
|
+
width: width.value,
|
|
81
|
+
height: props.data.height,
|
|
82
|
+
},
|
|
83
|
+
animInfo
|
|
84
|
+
);
|
|
85
|
+
}
|
|
90
86
|
};
|
|
91
87
|
|
|
92
88
|
props.onAction.register("onFocus", onFocus);
|
|
93
89
|
props.onAction.register("onBlur", onBlur);
|
|
94
90
|
props.onAction.register("onClick", onClick);
|
|
95
|
-
|
|
96
|
-
onBeforeUnmount(() => {
|
|
97
|
-
clearTimeout(timeoutHandler);
|
|
98
|
-
timeoutHandler = -1;
|
|
99
|
-
});
|
|
100
91
|
</script>
|
|
101
92
|
|
|
102
93
|
<template>
|
|
@@ -107,9 +98,7 @@ onBeforeUnmount(() => {
|
|
|
107
98
|
fontSize: 30,
|
|
108
99
|
color: focused ? '#FF0000' : '#FFFFFF',
|
|
109
100
|
backgroundColor: data.color,
|
|
110
|
-
transition:
|
|
111
|
-
duration / 1000
|
|
112
|
-
}s, height ${duration / 1000}s`,
|
|
101
|
+
transition: transition,
|
|
113
102
|
borderRadius: 10,
|
|
114
103
|
}"
|
|
115
104
|
>
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
* @Author: ChenChanghua
|
|
3
|
+
* @Date: 2023-03-08 14:52:08
|
|
4
|
+
* @Description: file content
|
|
5
|
+
-->
|
|
6
|
+
<script setup>
|
|
7
|
+
import {
|
|
8
|
+
ListWidget,
|
|
9
|
+
HORIZONTAL,
|
|
10
|
+
useFocusHub,
|
|
11
|
+
FixPositionSlide,
|
|
12
|
+
EdgeDirection,
|
|
13
|
+
} from "jsview";
|
|
14
|
+
import Item from "./Item.vue";
|
|
15
|
+
import { ref, provide } from "vue";
|
|
16
|
+
|
|
17
|
+
const focusHub = useFocusHub();
|
|
18
|
+
|
|
19
|
+
const randomColor = () => {
|
|
20
|
+
let randomColor = Math.round(Math.random() * 2 ** 24).toString(16);
|
|
21
|
+
return (
|
|
22
|
+
"#" +
|
|
23
|
+
new Array(6 - randomColor.length).fill("0").join("") +
|
|
24
|
+
randomColor +
|
|
25
|
+
"77"
|
|
26
|
+
);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const fixPositionSlide = new FixPositionSlide();
|
|
30
|
+
const largeItemIndex = ref(0);
|
|
31
|
+
provide("largeItemIndex", largeItemIndex);
|
|
32
|
+
const data = [
|
|
33
|
+
{
|
|
34
|
+
width: 310,
|
|
35
|
+
height: 100,
|
|
36
|
+
marginRight: 10,
|
|
37
|
+
color: randomColor(),
|
|
38
|
+
content: 0,
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
width: 110,
|
|
42
|
+
height: 100,
|
|
43
|
+
marginRight: 10,
|
|
44
|
+
color: randomColor(),
|
|
45
|
+
content: 1,
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
width: 110,
|
|
49
|
+
height: 100,
|
|
50
|
+
marginRight: 10,
|
|
51
|
+
color: randomColor(),
|
|
52
|
+
content: 2,
|
|
53
|
+
},
|
|
54
|
+
];
|
|
55
|
+
const provideData = () => {
|
|
56
|
+
return data;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const measures = (data) => {
|
|
60
|
+
return {
|
|
61
|
+
width: data.width,
|
|
62
|
+
height: data.height,
|
|
63
|
+
marginRight: data.marginRight,
|
|
64
|
+
marginBottom: data.marginBottom,
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const onEdge = (edgeInfo) => {
|
|
69
|
+
if (edgeInfo.direction == EdgeDirection.top) {
|
|
70
|
+
focusHub.setFocus("itemResizeBackward");
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const widgetLayout = {
|
|
75
|
+
left: 0,
|
|
76
|
+
top: 0,
|
|
77
|
+
width: 600,
|
|
78
|
+
height: 120,
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const padding = {
|
|
82
|
+
left: 25,
|
|
83
|
+
top: 10,
|
|
84
|
+
right: 25,
|
|
85
|
+
bottom: 10,
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const name = "stretch";
|
|
89
|
+
</script>
|
|
90
|
+
|
|
91
|
+
<template>
|
|
92
|
+
<div>
|
|
93
|
+
<div
|
|
94
|
+
:style="{
|
|
95
|
+
...widgetLayout,
|
|
96
|
+
backgroundColor: 'rgba(255,0,0,0.5)',
|
|
97
|
+
}"
|
|
98
|
+
></div>
|
|
99
|
+
<list-widget
|
|
100
|
+
ref="widgetRef"
|
|
101
|
+
:name="name"
|
|
102
|
+
:left="widgetLayout.left"
|
|
103
|
+
:top="widgetLayout.top"
|
|
104
|
+
:width="widgetLayout.width"
|
|
105
|
+
:height="widgetLayout.height"
|
|
106
|
+
:provideData="provideData"
|
|
107
|
+
:direction="HORIZONTAL"
|
|
108
|
+
:slideSetting="fixPositionSlide"
|
|
109
|
+
:measures="measures"
|
|
110
|
+
:padding="padding"
|
|
111
|
+
:onEdge="onEdge"
|
|
112
|
+
>
|
|
113
|
+
<template #renderItem="{ data, onAction, query }">
|
|
114
|
+
<item
|
|
115
|
+
:data="data"
|
|
116
|
+
:onAction="onAction"
|
|
117
|
+
:query="query"
|
|
118
|
+
/>
|
|
119
|
+
</template>
|
|
120
|
+
</list-widget>
|
|
121
|
+
</div>
|
|
122
|
+
</template>
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
* @Author: ChenChanghua
|
|
3
|
+
* @Date: 2023-03-08 14:52:17
|
|
4
|
+
* @Description: file content
|
|
5
|
+
-->
|
|
6
|
+
<script setup>
|
|
7
|
+
import { ref, watch, inject, watchSyncEffect } from "vue";
|
|
8
|
+
|
|
9
|
+
const props = defineProps({
|
|
10
|
+
data: Object,
|
|
11
|
+
onAction: Object,
|
|
12
|
+
query: Object,
|
|
13
|
+
currentLargeItem: Object,
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
const focused = ref(false);
|
|
17
|
+
const largeItemIndex = inject("largeItemIndex");
|
|
18
|
+
|
|
19
|
+
const width = ref(props.data.width);
|
|
20
|
+
const duration = 200;
|
|
21
|
+
const transitionStr = `left ${duration / 1000}s, top ${
|
|
22
|
+
duration / 1000
|
|
23
|
+
}s, width ${duration / 1000}s, height ${duration / 1000}s`;
|
|
24
|
+
const transition = ref(transitionStr);
|
|
25
|
+
const animInfo = {
|
|
26
|
+
anchor: 0.5,
|
|
27
|
+
duration: duration,
|
|
28
|
+
onEnd: () => {
|
|
29
|
+
console.log("resize end", props.query.index);
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
let isLarge = props.query.index == 0;
|
|
34
|
+
watch(
|
|
35
|
+
() => largeItemIndex.value,
|
|
36
|
+
(newV) => {
|
|
37
|
+
console.log("testtest watch", newV)
|
|
38
|
+
if (newV == props.query.index) {
|
|
39
|
+
if (!isLarge) {
|
|
40
|
+
isLarge = true;
|
|
41
|
+
width.value = 310;
|
|
42
|
+
props.query.updateItemSize(
|
|
43
|
+
props.query.index,
|
|
44
|
+
{
|
|
45
|
+
width: width.value,
|
|
46
|
+
height: props.data.height,
|
|
47
|
+
},
|
|
48
|
+
animInfo
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
} else {
|
|
52
|
+
if (isLarge) {
|
|
53
|
+
isLarge = false;
|
|
54
|
+
width.value = 110;
|
|
55
|
+
props.query.updateItemSize(
|
|
56
|
+
props.query.index,
|
|
57
|
+
{
|
|
58
|
+
width: width.value,
|
|
59
|
+
height: props.data.height,
|
|
60
|
+
},
|
|
61
|
+
animInfo
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
let timeoutHandler = -1;
|
|
69
|
+
const onFocus = () => {
|
|
70
|
+
focused.value = true;
|
|
71
|
+
timeoutHandler = setTimeout(() => {
|
|
72
|
+
largeItemIndex.value = props.query.index;
|
|
73
|
+
}, 1000);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const onBlur = () => {
|
|
77
|
+
focused.value = false;
|
|
78
|
+
clearTimeout(timeoutHandler);
|
|
79
|
+
timeoutHandler = -1;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const onClick = () => {
|
|
83
|
+
console.log("onClick");
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
props.onAction.register("onFocus", onFocus);
|
|
87
|
+
props.onAction.register("onBlur", onBlur);
|
|
88
|
+
props.onAction.register("onClick", onClick);
|
|
89
|
+
</script>
|
|
90
|
+
|
|
91
|
+
<template>
|
|
92
|
+
<div
|
|
93
|
+
:style="{
|
|
94
|
+
width: width,
|
|
95
|
+
height: data.height,
|
|
96
|
+
fontSize: 30,
|
|
97
|
+
color: focused ? '#FF0000' : '#FFFFFF',
|
|
98
|
+
backgroundColor: data.color,
|
|
99
|
+
transition: transition,
|
|
100
|
+
borderRadius: 10,
|
|
101
|
+
}"
|
|
102
|
+
>
|
|
103
|
+
{{ data.content }}
|
|
104
|
+
</div>
|
|
105
|
+
</template>
|
package/MindMap/App.vue
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { JsvMindMap } from "jsview";
|
|
3
|
+
import Item from "./Item.vue";
|
|
4
|
+
import { data } from "./data"
|
|
5
|
+
|
|
6
|
+
const provideData = () => {
|
|
7
|
+
return data;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const lineColor = {
|
|
11
|
+
0: "#ff0000",
|
|
12
|
+
1: "#00ff00",
|
|
13
|
+
2: "#0000ff",
|
|
14
|
+
3: "#007788",
|
|
15
|
+
4: "#007788",
|
|
16
|
+
5: "#007788",
|
|
17
|
+
};
|
|
18
|
+
const formatNode = (item, depth) => {
|
|
19
|
+
return {
|
|
20
|
+
left: item.left,
|
|
21
|
+
top: item.top,
|
|
22
|
+
width: 50,
|
|
23
|
+
height: 50,
|
|
24
|
+
childrenList: item.children,
|
|
25
|
+
moveType: item.moveType ?? "layer",
|
|
26
|
+
id: item.id,
|
|
27
|
+
lineStyle: {
|
|
28
|
+
backgroundColor: lineColor[depth],
|
|
29
|
+
lineWidth: 3,
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
const onEdge = (info) => {
|
|
34
|
+
console.log("onEdge ", info);
|
|
35
|
+
};
|
|
36
|
+
</script>
|
|
37
|
+
|
|
38
|
+
<template>
|
|
39
|
+
<jsv-mind-map
|
|
40
|
+
:left="200"
|
|
41
|
+
:top="100"
|
|
42
|
+
:width="500"
|
|
43
|
+
:height="500"
|
|
44
|
+
:formatNode="formatNode"
|
|
45
|
+
:provideData="provideData"
|
|
46
|
+
:onEdge="onEdge"
|
|
47
|
+
>
|
|
48
|
+
<template v-slot="{ data, onAction, handler }">
|
|
49
|
+
<item :data="data" :onAction="onAction" :handler="handler"></item>
|
|
50
|
+
</template>
|
|
51
|
+
<template #background>
|
|
52
|
+
<div
|
|
53
|
+
:style="{
|
|
54
|
+
width: 1920,
|
|
55
|
+
height: 1920,
|
|
56
|
+
backgroundColor: '#aa0000aa',
|
|
57
|
+
}"
|
|
58
|
+
></div>
|
|
59
|
+
</template>
|
|
60
|
+
</jsv-mind-map>
|
|
61
|
+
</template>
|