Skip to content

Commit 7aed103

Browse files
committed
feat(字体): 增加样式字体
1 parent 5169596 commit 7aed103

File tree

7 files changed

+529
-246
lines changed

7 files changed

+529
-246
lines changed

packages/core/plugin/FontPlugin.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* @Author: 秦少卫
33
* @Date: 2024-04-21 23:51:01
44
* @LastEditors: 秦少卫
5-
* @LastEditTime: 2024-04-22 19:14:54
5+
* @LastEditTime: 2024-05-17 16:13:03
66
* @Description: 自定义字体
77
*/
88

@@ -31,7 +31,7 @@ class FontPlugin {
3131
public canvas: fabric.Canvas;
3232
public editor: IEditor;
3333
static pluginName = 'FontPlugin';
34-
static apis = ['getFontList', 'loadFont'];
34+
static apis = ['getFontList', 'loadFont', 'getFontJson', 'downFontByJSON'];
3535
repoSrc: string;
3636
cacheList: FontSource[];
3737
constructor(canvas: fabric.Canvas, editor: IEditor, config: { repoSrc: string }) {

src/components/fontStyle.vue

+165
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
<!--
2+
* @Author: 秦少卫
3+
* @Date: 2023-08-05 17:47:35
4+
* @LastEditors: 秦少卫
5+
* @LastEditTime: 2024-05-17 16:26:25
6+
* @Description: 字体样式
7+
-->
8+
9+
<template>
10+
<div>
11+
<!-- 搜索组件 -->
12+
<div class="search-box">
13+
<Select class="select" v-model="typeValue" @on-change="startGetList" :disabled="pageLoading">
14+
<Option v-for="item in typeList" :value="item.value" :key="item.value">
15+
{{ item.label }}
16+
</Option>
17+
</Select>
18+
<Input
19+
class="input"
20+
:placeholder="`在${typeText}中搜索`"
21+
v-model="searchKeyWord"
22+
search
23+
:disabled="pageLoading"
24+
@on-search="startGetList"
25+
/>
26+
</div>
27+
<!-- 列表 -->
28+
<div style="height: calc(100vh - 108px)" id="myTemplBox3">
29+
<Scroll
30+
key="mysscroll2"
31+
v-if="showScroll"
32+
:on-reach-bottom="nextPage"
33+
:height="scrollHeight"
34+
:distance-to-edge="[-1, -1]"
35+
>
36+
<!-- 列表 -->
37+
<div class="img-group">
38+
<Tooltip :content="info.name" v-for="info in pageData" :key="info.src" placement="top">
39+
<div class="tmpl-img-box">
40+
<Image
41+
lazy
42+
:src="info.src"
43+
fit="contain"
44+
height="100%"
45+
:alt="info.name"
46+
@click="addItem(info)"
47+
@dragend="(e) => dragItem(e, info)"
48+
/>
49+
</div>
50+
</Tooltip>
51+
</div>
52+
<Spin size="large" fix :show="pageLoading"></Spin>
53+
54+
<Divider plain v-if="isDownBottm">已经到底了</Divider>
55+
</Scroll>
56+
</div>
57+
</div>
58+
</template>
59+
60+
<script setup name="ImportSvg">
61+
import useSelect from '@/hooks/select';
62+
import usePageList from '@/hooks/pageList';
63+
import { fabric } from 'fabric';
64+
import { v4 as uuid } from 'uuid';
65+
import { Spin } from 'view-ui-plus';
66+
import { useI18n } from 'vue-i18n';
67+
const { t } = useI18n();
68+
69+
const {
70+
startPage,
71+
typeValue,
72+
typeText,
73+
typeList,
74+
pageLoading,
75+
pageData,
76+
searchKeyWord,
77+
isDownBottm,
78+
startGetList,
79+
nextPage,
80+
showScroll,
81+
scrollHeight,
82+
} = usePageList({
83+
typeUrl: 'font-style-types',
84+
listUrl: 'font-styles',
85+
searchTypeKey: 'font_style_type',
86+
searchWordKey: 'name',
87+
pageSize: 50,
88+
scrollElement: '#myTemplBox3',
89+
});
90+
91+
const { canvasEditor } = useSelect();
92+
93+
// 按照类型渲染
94+
const dragItem = async (e, item) => {
95+
Spin.show({
96+
render: (h) => h('div', t('alert.loading_data')),
97+
});
98+
await canvasEditor.downFontByJSON(JSON.stringify(item.json));
99+
const el = JSON.parse(JSON.stringify(item.json));
100+
el.id = uuid();
101+
const elType = capitalizeFirstLetter(el.type);
102+
new fabric[elType].fromObject(el, (fabricEl) => {
103+
canvasEditor.dragAddItem(fabricEl, e);
104+
Spin.hide();
105+
});
106+
};
107+
108+
const addItem = async (item) => {
109+
Spin.show({
110+
render: (h) => h('div', t('alert.loading_data')),
111+
});
112+
await canvasEditor.downFontByJSON(JSON.stringify(item.json));
113+
const el = JSON.parse(JSON.stringify(item.json));
114+
el.id = uuid();
115+
const elType = capitalizeFirstLetter(el.type);
116+
new fabric[elType].fromObject(el, (fabricEl) => {
117+
canvasEditor.dragAddItem(fabricEl);
118+
119+
Spin.hide();
120+
});
121+
};
122+
123+
function capitalizeFirstLetter(string) {
124+
return string.charAt(0).toUpperCase() + string.slice(1);
125+
}
126+
127+
onMounted(async () => {
128+
startPage();
129+
});
130+
</script>
131+
132+
<style scoped lang="less">
133+
.search-box {
134+
padding-top: 10px;
135+
display: flex;
136+
.input {
137+
margin-left: 10px;
138+
}
139+
.select {
140+
width: 100px;
141+
}
142+
}
143+
144+
.img-group {
145+
background: #eeeeeea1;
146+
border-radius: 10px;
147+
padding: 10px;
148+
}
149+
.tmpl-img-box {
150+
width: 67px;
151+
height: 100px;
152+
padding: 5px;
153+
cursor: pointer;
154+
border-radius: 10px;
155+
156+
&:hover {
157+
background: #e3e3e3;
158+
}
159+
}
160+
161+
.tip-text {
162+
display: block;
163+
text-align: center;
164+
}
165+
</style>

src/components/importSvgEl.vue

+45-96
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,48 @@
1+
<!--
2+
* @Author: 秦少卫
3+
* @Date: 2024-05-17 15:31:24
4+
* @LastEditors: 秦少卫
5+
* @LastEditTime: 2024-05-17 15:31:25
6+
* @Description: file content
7+
-->
18
<!--
29
* @Author: 秦少卫
310
* @Date: 2023-08-05 17:47:35
411
* @LastEditors: 秦少卫
5-
* @LastEditTime: 2024-05-09 15:05:49
12+
* @LastEditTime: 2024-05-17 15:16:59
613
* @Description: file content
714
-->
815

916
<template>
1017
<div>
1118
<!-- 搜索组件 -->
1219
<div class="search-box">
13-
<Select
14-
class="select"
15-
v-model="materialType"
16-
@on-change="startGetMaterialList"
17-
:disabled="loading"
18-
>
19-
<Option key="全部" value="">全部</Option>
20-
<Option v-for="item in materialTypeList" :value="item.value" :key="item.value">
20+
<Select class="select" v-model="typeValue" @on-change="startGetList" :disabled="pageLoading">
21+
<Option v-for="item in typeList" :value="item.value" :key="item.value">
2122
{{ item.label }}
2223
</Option>
2324
</Select>
2425
<Input
2526
class="input"
26-
:placeholder="`在${getSearchTypeText()}中搜索`"
27-
v-model="searchKeyword"
27+
:placeholder="`在${typeText}中搜索`"
28+
v-model="searchKeyWord"
2829
search
29-
:disabled="loading"
30-
@on-search="startGetMaterialList"
30+
:disabled="pageLoading"
31+
@on-search="startGetList"
3132
/>
3233
</div>
33-
3434
<!-- 列表 -->
35-
<div style="height: calc(100vh - 110px)" id="myTemplBox">
35+
<div style="height: calc(100vh - 108px)" id="myTemplBox1">
3636
<Scroll
37-
key="mysscroll"
37+
key="mysscroll2"
3838
v-if="showScroll"
39-
:on-reach-bottom="handleReachBottom"
39+
:on-reach-bottom="nextPage"
4040
:height="scrollHeight"
4141
:distance-to-edge="[-1, -1]"
4242
>
4343
<!-- 列表 -->
44-
<div>
45-
<Tooltip
46-
:content="info.name"
47-
v-for="info in materialList"
48-
:key="info.src"
49-
placement="top"
50-
>
44+
<div class="img-group">
45+
<Tooltip :content="info.name" v-for="info in pageData" :key="info.src" placement="top">
5146
<div class="tmpl-img-box">
5247
<Image
5348
lazy
@@ -61,87 +56,47 @@
6156
</div>
6257
</Tooltip>
6358
</div>
64-
<Spin size="large" fix :show="loading"></Spin>
59+
<Spin size="large" fix :show="pageLoading"></Spin>
6560

66-
<Divider plain v-if="isDownBottm()">已经到底了</Divider>
61+
<Divider plain v-if="isDownBottm">已经到底了</Divider>
6762
</Scroll>
6863
</div>
6964
</div>
7065
</template>
7166

7267
<script setup name="ImportSvg">
7368
import useSelect from '@/hooks/select';
69+
import usePageList from '@/hooks/pageList';
7470
import { fabric } from 'fabric';
7571
import { v4 as uuid } from 'uuid';
7672
import { useRoute } from 'vue-router';
7773
import { Utils } from '@kuaitu/core';
7874

79-
const { canvasEditor } = useSelect();
80-
81-
// 素材类型
82-
const materialType = ref('');
83-
materialType.value = '';
84-
// 素材类型列表
85-
const materialTypeList = ref([]);
86-
// 素材列表
87-
const materialList = ref([]);
88-
// 搜索关键字
89-
const searchKeyword = ref('');
90-
// 面板加载
91-
const loading = ref(false);
92-
93-
// 分页信息
94-
const page = ref(1);
95-
const pagination = reactive({
96-
page: 0,
97-
pageCount: 0,
98-
pageSize: 10,
99-
total: 0,
75+
const {
76+
startPage,
77+
typeValue,
78+
typeText,
79+
typeList,
80+
pageLoading,
81+
pageData,
82+
searchKeyWord,
83+
isDownBottm,
84+
startGetList,
85+
nextPage,
86+
showScroll,
87+
scrollHeight,
88+
} = usePageList({
89+
typeUrl: 'material-types',
90+
listUrl: 'materials',
91+
searchTypeKey: 'material_type',
92+
searchWordKey: 'name',
93+
pageSize: 50,
94+
scrollElement: '#myTemplBox1',
10095
});
10196

102-
const getSearchTypeText = () => {
103-
const info = materialTypeList.value.find((item) => item.value === materialType.value);
104-
const type = info?.label || '全部';
105-
return type;
106-
};
107-
108-
const isDownBottm = () => {
109-
return pagination.page === page.value && pagination.page >= pagination.pageCount;
110-
};
111-
112-
// 获取素材分类
113-
canvasEditor.getMaterialTypeList().then((list) => {
114-
materialTypeList.value = list;
115-
});
116-
117-
// 获取素材列表
118-
const getMaterialList = () => {
119-
loading.value = true;
120-
canvasEditor.getMaterialList(materialType.value, page.value, searchKeyword.value).then((res) => {
121-
const { list, pagination: resPagination } = res;
122-
Object.keys(resPagination).forEach((key) => {
123-
pagination[key] = resPagination[key];
124-
});
125-
materialList.value = [...materialList.value, ...list];
126-
loading.value = false;
127-
});
128-
};
129-
130-
const startGetMaterialList = () => {
131-
materialList.value = [];
132-
page.value = 1;
133-
getMaterialList();
134-
};
135-
136-
const handleReachBottom = () => {
137-
if (page.value >= pagination.pageCount) return;
138-
page.value++;
139-
setTimeout(() => {
140-
getMaterialList();
141-
}, 1000);
142-
};
97+
const { canvasEditor } = useSelect();
14398

144-
// // 按照类型渲染
99+
// 按照类型渲染
145100
const dragItem = (e) => {
146101
const target = e.target;
147102
const imgType = canvasEditor.getImageExtension(target.src);
@@ -198,8 +153,6 @@ const addItem = (e) => {
198153
}
199154
};
200155

201-
const showScroll = ref(false);
202-
const scrollHeight = ref(0);
203156
onMounted(async () => {
204157
// 默认添加图片
205158
const route = useRoute();
@@ -209,11 +162,7 @@ onMounted(async () => {
209162
addItem({ target: image });
210163
}
211164

212-
// 滚动
213-
const myTemplBox = document.querySelector('#myTemplBox');
214-
scrollHeight.value = myTemplBox.offsetHeight - 10;
215-
showScroll.value = true;
216-
getMaterialList();
165+
startPage();
217166
});
218167
</script>
219168

0 commit comments

Comments
 (0)