From d3fbd3a06c3b802fc863b4dc8013122c14bd16f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=87=AF=E9=BE=99?= <502431556@qq.com> Date: Wed, 26 Jan 2022 14:08:37 +0800 Subject: [PATCH] feat: Add count-to demo feat: Add useWatermark hook and add useWatermark demo --- src/hooks/web/usePageLoading.ts | 4 +- src/hooks/web/useWatermark.ts | 55 ++++++++++++ src/locales/en.ts | 30 ++++++- src/locales/zh-CN.ts | 29 ++++++- src/router/index.ts | 24 ++++++ src/views/Components/CountTo.vue | 100 ++++++++++++++++++++++ src/views/Components/Echart.vue | 36 ++++++++ src/views/Components/Watermark.vue | 32 +++++++ src/views/Dashboard/Analysis.vue | 4 +- src/views/Dashboard/echarts-data.ts | 125 ++++++++++++++++++++++++++++ 10 files changed, 432 insertions(+), 7 deletions(-) create mode 100644 src/hooks/web/useWatermark.ts create mode 100644 src/views/Components/CountTo.vue create mode 100644 src/views/Components/Echart.vue create mode 100644 src/views/Components/Watermark.vue diff --git a/src/hooks/web/usePageLoading.ts b/src/hooks/web/usePageLoading.ts index 7156378d2..bb89457d9 100644 --- a/src/hooks/web/usePageLoading.ts +++ b/src/hooks/web/usePageLoading.ts @@ -8,9 +8,7 @@ export const usePageLoading = () => { } const loadDone = () => { - setTimeout(() => { - appStore.setPageLoading(false) - }, 1000) + appStore.setPageLoading(false) } return { diff --git a/src/hooks/web/useWatermark.ts b/src/hooks/web/useWatermark.ts new file mode 100644 index 000000000..4a313594c --- /dev/null +++ b/src/hooks/web/useWatermark.ts @@ -0,0 +1,55 @@ +const domSymbol = Symbol('watermark-dom') + +export function useWatermark(appendEl: HTMLElement | null = document.body) { + let func: Fn = () => {} + const id = domSymbol.toString() + const clear = () => { + const domId = document.getElementById(id) + if (domId) { + const el = appendEl + el && el.removeChild(domId) + } + window.removeEventListener('resize', func) + } + const createWatermark = (str: string) => { + clear() + + const can = document.createElement('canvas') + can.width = 300 + can.height = 240 + + const cans = can.getContext('2d') + if (cans) { + cans.rotate((-20 * Math.PI) / 120) + cans.font = '15px Vedana' + cans.fillStyle = 'rgba(0, 0, 0, 0.15)' + cans.textAlign = 'left' + cans.textBaseline = 'middle' + cans.fillText(str, can.width / 20, can.height) + } + + const div = document.createElement('div') + div.id = id + div.style.pointerEvents = 'none' + div.style.top = '0px' + div.style.left = '0px' + div.style.position = 'absolute' + div.style.zIndex = '100000000' + div.style.width = document.documentElement.clientWidth + 'px' + div.style.height = document.documentElement.clientHeight + 'px' + div.style.background = 'url(' + can.toDataURL('image/png') + ') left top repeat' + const el = appendEl + el && el.appendChild(div) + return id + } + + function setWatermark(str: string) { + createWatermark(str) + func = () => { + createWatermark(str) + } + window.addEventListener('resize', func) + } + + return { setWatermark, clear } +} diff --git a/src/locales/en.ts b/src/locales/en.ts index 4a9a6c99d..88f66605c 100644 --- a/src/locales/en.ts +++ b/src/locales/en.ts @@ -87,7 +87,10 @@ export default { workplace: 'Workplace', guide: 'Guide', component: 'Component', - icon: 'Icon' + icon: 'Icon', + echart: 'Echart', + countTo: 'Count to', + watermark: 'Watermark' }, analysis: { newUser: 'New user', @@ -203,5 +206,30 @@ export default { recommendeDes: 'Iconify component basically contains all icons. You can query any icon you want. And packaging will only package the icons used.', accessAddress: 'Access address' + }, + echartDemo: { + echart: 'Echart', + echartDes: + 'Based on the secondary packaging components of eckarts, the width is adaptive. The corresponding chart can be displayed by passing in the options and height attributes.' + }, + countToDemo: { + countTo: 'CountTo', + countToDes: + 'The transformation is based on vue-count-to and supports all vue-count-to parameters.', + suffix: 'Suffix', + prefix: 'Prefix', + separator: 'Separator', + duration: 'Duration', + endVal: 'End val', + startVal: 'Start val', + start: 'Start', + pause: 'Pause', + resume: 'Resume' + }, + watermarkDemo: { + watermark: 'Watermark', + createdWatermark: 'Created watermark', + clearWatermark: 'Clear watermark', + resetWatermark: 'Reset watermark' } } diff --git a/src/locales/zh-CN.ts b/src/locales/zh-CN.ts index e644fadb9..3723aebab 100644 --- a/src/locales/zh-CN.ts +++ b/src/locales/zh-CN.ts @@ -87,7 +87,10 @@ export default { workplace: '工作台', guide: '引导', component: '组件', - icon: '图标' + icon: '图标', + echart: '图表', + countTo: '数字动画', + watermark: '水印' }, analysis: { newUser: '新增用户', @@ -203,5 +206,29 @@ export default { recommendeDes: 'Iconify组件基本包含所有的图标,你可以查询到你想要的任何图标。并且打包只会打包所用到的图标。', accessAddress: '访问地址' + }, + echartDemo: { + echart: '图表', + echartDes: + '基于 echarts 二次封装组件,自适应宽度,只需传入 options 与 height 属性即可展示对应的图表。' + }, + countToDemo: { + countTo: '数字动画', + countToDes: '基于 vue-count-to 进行改造,支持所有 vue-count-to 参数。', + suffix: '后缀', + prefix: '前缀', + separator: '分割符号', + duration: '持续时间', + endVal: '结束值', + startVal: '开始值', + start: '开始', + pause: '暂停', + resume: '继续' + }, + watermarkDemo: { + watermark: '水印', + createdWatermark: '创建水印', + clearWatermark: '清除水印', + resetWatermark: '重置水印' } } diff --git a/src/router/index.ts b/src/router/index.ts index 303afa123..f813ec7c6 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -103,6 +103,30 @@ export const asyncRouterMap: AppRouteRecordRaw[] = [ meta: { title: t('router.icon') } + }, + { + path: 'echart', + component: () => import('@/views/Components/Echart.vue'), + name: 'Echart', + meta: { + title: t('router.echart') + } + }, + { + path: 'count-to', + component: () => import('@/views/Components/CountTo.vue'), + name: 'CountTo', + meta: { + title: t('router.countTo') + } + }, + { + path: 'watermark', + component: () => import('@/views/Components/Watermark.vue'), + name: 'Watermark', + meta: { + title: t('router.watermark') + } } ] }, diff --git a/src/views/Components/CountTo.vue b/src/views/Components/CountTo.vue new file mode 100644 index 000000000..4c906b99c --- /dev/null +++ b/src/views/Components/CountTo.vue @@ -0,0 +1,100 @@ + + + diff --git a/src/views/Components/Echart.vue b/src/views/Components/Echart.vue new file mode 100644 index 000000000..da3493c52 --- /dev/null +++ b/src/views/Components/Echart.vue @@ -0,0 +1,36 @@ + + + diff --git a/src/views/Components/Watermark.vue b/src/views/Components/Watermark.vue new file mode 100644 index 000000000..3cf92cee5 --- /dev/null +++ b/src/views/Components/Watermark.vue @@ -0,0 +1,32 @@ + + + diff --git a/src/views/Dashboard/Analysis.vue b/src/views/Dashboard/Analysis.vue index 29846ed0f..50888d1ef 100644 --- a/src/views/Dashboard/Analysis.vue +++ b/src/views/Dashboard/Analysis.vue @@ -17,7 +17,7 @@ const { t } = useI18n() const loading = ref(true) -const pieOptionsData = reactive(pieOptions) +const pieOptionsData = reactive(pieOptions) as EChartsOption // 用户来源 const getUserAccessSource = async () => { @@ -100,7 +100,7 @@ getAllApi() - + diff --git a/src/views/Dashboard/echarts-data.ts b/src/views/Dashboard/echarts-data.ts index 6ad5b54c3..09b363711 100644 --- a/src/views/Dashboard/echarts-data.ts +++ b/src/views/Dashboard/echarts-data.ts @@ -1,4 +1,5 @@ import { EChartsOption } from 'echarts' +import { EChartsOption as EChartsWordOption } from 'echarts-wordcloud' import { useI18n } from '@/hooks/web/useI18n' const { t } = useI18n() @@ -183,3 +184,127 @@ export const radarOption: EChartsOption = { } ] } + +export const wordOptions: EChartsWordOption = { + series: [ + { + type: 'wordCloud', + gridSize: 2, + sizeRange: [12, 50], + rotationRange: [-90, 90], + shape: 'pentagon', + width: 600, + height: 400, + drawOutOfBound: true, + textStyle: { + color: function () { + return ( + 'rgb(' + + [ + Math.round(Math.random() * 160), + Math.round(Math.random() * 160), + Math.round(Math.random() * 160) + ].join(',') + + ')' + ) + } + }, + emphasis: { + textStyle: { + shadowBlur: 10, + shadowColor: '#333' + } + }, + data: [ + { + name: 'Sam S Club', + value: 10000, + textStyle: { + color: 'black' + }, + emphasis: { + textStyle: { + color: 'red' + } + } + }, + { + name: 'Macys', + value: 6181 + }, + { + name: 'Amy Schumer', + value: 4386 + }, + { + name: 'Jurassic World', + value: 4055 + }, + { + name: 'Charter Communications', + value: 2467 + }, + { + name: 'Chick Fil A', + value: 2244 + }, + { + name: 'Planet Fitness', + value: 1898 + }, + { + name: 'Pitch Perfect', + value: 1484 + }, + { + name: 'Express', + value: 1112 + }, + { + name: 'Home', + value: 965 + }, + { + name: 'Johnny Depp', + value: 847 + }, + { + name: 'Lena Dunham', + value: 582 + }, + { + name: 'Lewis Hamilton', + value: 555 + }, + { + name: 'KXAN', + value: 550 + }, + { + name: 'Mary Ellen Mark', + value: 462 + }, + { + name: 'Farrah Abraham', + value: 366 + }, + { + name: 'Rita Ora', + value: 360 + }, + { + name: 'Serena Williams', + value: 282 + }, + { + name: 'NCAA baseball tournament', + value: 273 + }, + { + name: 'Point Break', + value: 265 + } + ] + } + ] +}