feat: 添加AnimateCss选择器组件ReAnimateSelector (#764)

* feat: 添加`AnimateCss`选择器组件`ReAnimateSelector`

* chore: update
This commit is contained in:
xiaoming 2023-10-21 15:00:44 +08:00 committed by GitHub
parent b325442e82
commit 59fcac86c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 291 additions and 0 deletions

View File

@ -46,6 +46,7 @@ menus:
hssplitPane: Split Pane
hsbutton: Button Components
hscropping: Picture Cropping
hsanimatecss: AnimateCss Selector
hscountTo: Digital Animation
hsselector: Selector Components
hsflowChart: Flow Chart

View File

@ -46,6 +46,7 @@ menus:
hssplitPane: 切割面板
hsbutton: 按钮组件
hscropping: 图片裁剪
hsanimatecss: AnimateCss选择器组件
hscountTo: 数字动画
hsselector: 选择器组件
hsflowChart: 流程图

View File

@ -0,0 +1,7 @@
import reAnimateSelector from "./src/index.vue";
import { withInstall } from "@pureadmin/utils";
/** [animate.css](https://animate.style/) 选择器组件 */
export const ReAnimateSelector = withInstall(reAnimateSelector);
export default ReAnimateSelector;

View File

@ -0,0 +1,114 @@
export const animates = [
/* Attention seekers */
"bounce",
"flash",
"pulse",
"rubberBand",
"shakeX",
"headShake",
"swing",
"tada",
"wobble",
"jello",
"heartBeat",
/* Back entrances */
"backInDown",
"backInLeft",
"backInRight",
"backInUp",
/* Back exits */
"backOutDown",
"backOutLeft",
"backOutRight",
"backOutUp",
/* Bouncing entrances */
"bounceIn",
"bounceInDown",
"bounceInLeft",
"bounceInRight",
"bounceInUp",
/* Bouncing exits */
"bounceOut",
"bounceOutDown",
"bounceOutLeft",
"bounceOutRight",
"bounceOutUp",
/* Fading entrances */
"fadeIn",
"fadeInDown",
"fadeInDownBig",
"fadeInLeft",
"fadeInLeftBig",
"fadeInRight",
"fadeInRightBig",
"fadeInUp",
"fadeInUpBig",
"fadeInTopLeft",
"fadeInTopRight",
"fadeInBottomLeft",
"fadeInBottomRight",
/* Fading exits */
"fadeOut",
"fadeOutDown",
"fadeOutDownBig",
"fadeOutLeft",
"fadeOutLeftBig",
"fadeOutRight",
"fadeOutRightBig",
"fadeOutUp",
"fadeOutUpBig",
"fadeOutTopLeft",
"fadeOutTopRight",
"fadeOutBottomRight",
"fadeOutBottomLeft",
/* Flippers */
"flip",
"flipInX",
"flipInY",
"flipOutX",
"flipOutY",
/* Lightspeed */
"lightSpeedInRight",
"lightSpeedInLeft",
"lightSpeedOutRight",
"lightSpeedOutLeft",
/* Rotating entrances */
"rotateIn",
"rotateInDownLeft",
"rotateInDownRight",
"rotateInUpLeft",
"rotateInUpRight",
/* Rotating exits */
"rotateOut",
"rotateOutDownLeft",
"rotateOutDownRight",
"rotateOutUpLeft",
"rotateOutUpRight",
/* Specials */
"hinge",
"jackInTheBox",
"rollIn",
"rollOut",
/* Zooming entrances */
"zoomIn",
"zoomInDown",
"zoomInLeft",
"zoomInRight",
"zoomInUp",
/* Zooming exits */
"zoomOut",
"zoomOutDown",
"zoomOutLeft",
"zoomOutRight",
"zoomOutUp",
/* Sliding entrances */
"slideInDown",
"slideInLeft",
"slideInRight",
"slideInUp",
/* Sliding exits */
"slideOutDown",
"slideOutLeft",
"slideOutRight",
"slideOutUp"
];

View File

@ -0,0 +1,127 @@
<script setup lang="ts">
import { animates } from "./animate";
import { ref, computed, toRef } from "vue";
import { cloneDeep } from "@pureadmin/utils";
defineOptions({
name: "ReAnimateSelector"
});
const props = defineProps({
modelValue: {
require: false,
type: String
}
});
const emit = defineEmits<{ (e: "update:modelValue", v: string) }>();
const inputValue = toRef(props, "modelValue");
const animatesList = ref(animates);
const copyAnimatesList = cloneDeep(animatesList);
const animateClass = computed(() => {
return [
"mt-1",
"flex",
"border",
"w-[130px]",
"h-[100px]",
"items-center",
"cursor-pointer",
"transition-all",
"justify-center",
"border-[#e5e7eb]",
"hover:text-primary",
"hover:duration-[700ms]"
];
});
const animateStyle = computed(
() => (i: string) =>
inputValue.value === i
? {
borderColor: "var(--el-color-primary)",
color: "var(--el-color-primary)"
}
: ""
);
function onChangeIcon(animate: string) {
emit("update:modelValue", animate);
}
function onClear() {
emit("update:modelValue", "");
}
function filterMethod(value: any) {
animatesList.value = copyAnimatesList.value.filter((i: string | any[]) =>
i.includes(value)
);
}
const animateMap = ref({});
function onMouseEnter(index: string | number) {
animateMap.value[index] = animateMap.value[index]?.loading
? Object.assign({}, animateMap.value[index], {
loading: false
})
: Object.assign({}, animateMap.value[index], {
loading: true
});
}
function onMouseleave() {
animateMap.value = {};
}
</script>
<template>
<el-select
:model-value="inputValue"
placeholder="请选择动画"
clearable
filterable
@clear="onClear"
:filter-method="filterMethod"
>
<template #empty>
<div class="w-[280px]">
<el-scrollbar
noresize
height="212px"
:view-style="{ overflow: 'hidden' }"
class="border-t border-[#e5e7eb]"
>
<ul class="flex flex-wrap justify-around mb-1">
<li
v-for="(animate, index) in animatesList"
:key="index"
:class="animateClass"
:style="animateStyle(animate)"
@mouseenter.prevent="onMouseEnter(index)"
@mouseleave.prevent="onMouseleave"
@click="onChangeIcon(animate)"
>
<h4
:class="[
`animate__animated animate__${
animateMap[index]?.loading
? animate + ' animate__infinite'
: ''
} `
]"
>
{{ animate }}
</h4>
</li>
</ul>
<el-empty
v-show="animatesList.length === 0"
description="暂无动画"
:image-size="60"
/>
</el-scrollbar>
</div>
</template>
</el-select>
</template>

View File

@ -105,6 +105,15 @@ export default {
title: $t("menus.hscropping")
}
},
{
path: "/components/animatecss",
name: "AnimateCss",
component: () => import("@/views/components/animatecss/index.vue"),
meta: {
title: $t("menus.hsanimatecss"),
extraIcon: "IF-pure-iconfont-new svg"
}
},
{
path: "/components/countTo",
name: "CountTo",

View File

@ -0,0 +1,32 @@
<script setup lang="ts">
import { ref, watch } from "vue";
import ReAnimateSelector from "@/components/ReAnimateSelector";
defineOptions({
name: "AnimateCss"
});
const icon = ref("");
watch(icon, () => console.log("icon", icon.value));
</script>
<template>
<el-card shadow="never">
<template #header>
<div class="card-header">
<span class="font-medium">
<el-link
href="https://animate.style/"
target="_blank"
style="margin: 0 4px 5px; font-size: 16px"
>
animate.css
</el-link>
选择器组件
</span>
</div>
</template>
<ReAnimateSelector v-model="icon" />
</el-card>
</template>