ue 3.2 + js 实现点赞粒子特效

  • 创建一个项目
  • 一、显示页面
    • 1.新建页面
    • 2.写部分显示代码
    • 3.导入文件
    • 4.将其他的注释掉
  • 二、下载点赞图片
    • 1.打开阿里云矢量库
    • 2.复制SVG代码
    • 3.调整样式
      • ①包裹整体、爱心和文字
      • ②修改总体样式
      • ③修改`心`样式
      • ④修改`svg`样式
      • ⑤修改文字样式
      • ⑥增加鼠标悬浮效果
  • 三、制作粒子扩散效果
    • 1.安装`mo.js`
    • 2.页面引用
    • 3.构建特效
      • ①定义`ref`(响应式数据)
      • ②构建`burst`
      • ③调用动画
  • 四、制作`红晕`
    • 1.定义`ref`
    • 2.构建`aperture`
    • 3.增加动画
  • 五、制作已点赞效果
    • 1.心形样式绑定
    • 2.炸裂效果点赞
  • 六、制作心跳效果
    • 1.制作跳动函数
    • 2.添加进`thumbsUp`函数中
  • 七、制作点赞状态锁
  • 完整代码

最终效果

为方便大家下载,开源gitee地址如下
点赞粒子效果 (gitee.com)

文章较长,建议一步一步跟着走

创建一个项目

首先我们创建一个vue3.2项目

详情请见Vue3+TypeScript 项目创建_qq_22841387的博客-CSDN博客,这里就不赘述了

这里选择默认即可

一、显示页面

1.新建页面

components文件夹下新建页面ThumbsUp.vue

单文件组件遵循 大驼峰原则

2.写部分显示代码

<template><h1>点赞页面</h1>
</template><script>
export default {}
</script><style></style>

3.导入文件

App.vue文件下导入文件

可直接写名字(Vue 3会自动导入

4.将其他的注释掉

<template><!-- <img alt="Vue logo" src="./assets/logo.png"><HelloWorld msg="Welcome to Your Vue.js App"/> --><thumbs-up></thumbs-up>
</template><script>
// import HelloWorld from './components/HelloWorld.vue'
import ThumbsUp from './components/ThumbsUp.vue'export default {name: 'App',components: {// HelloWorld,ThumbsUp}
}
</script><style>
#app {font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;margin-top: 60px;
}
</style>

二、下载点赞图片

1.打开阿里云矢量库

打开下方链接

iconfont-阿里巴巴矢量图标库

选择一个你喜欢的图标下载,最好是空心的

2.复制SVG代码

选择完成后,将鼠标移动至所选图标

点击下载

在弹出的窗口中,选择复制SVG代码,直接粘贴到目标文件ThumbsUp.vue

3.调整样式

css建议书写顺序:

  1. 布局定位属性:display / position / float / clear / visibility / overflow
  2. 自身属性:width / height / margin / padding / border / background
  3. 文本属性:color / font / text-decoration / text-align / vertical-align / white- space / break-word
  4. 其他属性(CSS3):content / cursor / border-radius / box-shadow / text-shadow / background: linear-gradient …

示例代码:

.jdc {display: block;position: relative;float: left;width: 100px;height: 100px;margin: 0 10px;padding: 20px 0;font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif;color: #333;background: rgba(0,0,0,.5);-webkit-border-radius: 10px;-moz-border-radius: 10px;-o-border-radius: 10px;-ms-border-radius: 10px;border-radius: 10px;
}

①包裹整体、爱心和文字

这里我使用thums-up包裹整体,局部心形用heart包裹

<template><h3>点赞页面</h3><div class="thums-up"><div class="heart"><svgt="1644501913302"class="icon"viewBox="0 0 1024 1024"version="1.1"xmlns="http://www.w3.org/2000/svg"p-id="1268"width="25"height="20"><pathd="M171.712 571.648l0.352 0.32 287.904 252.8a64 64 0 0 0 82.912 1.344l296.832-244.544a215.584 215.584 0 1 0-301.824-300.576L512 316.672l-25.888-35.616a215.584 215.584 0 1 0-314.4 290.624zM32 407.584a279.584 279.584 0 0 1 480-194.944 279.584 279.584 0 0 1 480 194.944 278.144 278.144 0 0 1-113.024 224.512l-295.36 243.392a128 128 0 0 1-165.888-2.592L129.984 620.16A278.976 278.976 0 0 1 32 407.584z"p-id="1269"></path></svg></div><div class="thums-up-text"><span>点赞</span></div></div>
</template>

②修改总体样式

.thums-up {display: flex;align-items: center;justify-content: center;height: 24px;cursor: pointer;
}

③修改样式

.thums-up .heart {display: inline-flex;position: relative;height: 20px;
}

④修改svg样式

.thums-up .heart svg {stroke: #9A9DAA;stroke-width: 30px;transition: fill 0.3s , stroke 0.3s;fill: transparent;
}

给一个延迟的动画效果,显得没有那么突兀

⑤修改文字样式

.thums-up-text {margin-left: 1px;font-size: 13px;user-select: none; // 用户不可选择
}

⑥增加鼠标悬浮效果

.thums-up:hover .heart svg {stroke: #e05b5b;
}

当前效果

三、制作粒子扩散效果

1.安装mo.js

这里使用的是一个轻量级的图形动画库

API overview | mo.js (mojs.github.io)

npm install @mojs/core

或者使用cnpm安装也可以,会快一些

cnpm install @mojs/core

出现无法安装的问题可查看这篇文章

使用cnpm i安装依赖【Npm、Cnpm】_qq_22841387的博客-CSDN博客

2.页面引用

<script>
import mojs from '@mojs/core'
export default {setup(){new mojs.Timeline()}
};
</script>

3.构建特效

这里我们使用的是Burst(炸裂)特效

Burst | mo.js (mojs.github.io)

①定义ref(响应式数据)

    <div class="heart" ref="heart">
……const heart = ref(null);

②构建burst

let burst;onMounted(() => {burst = new mojs.Burst({// 爆炸范围radius: { 0: 50 },// 动画挂载父元素,默认改在到body上parent: heart.value,// 动画延时函数easing: mojs.easing.bezier(0.1, 1, 0.3, 1),// 动画延时时间duration: 1500,// 动画等待时间delay: 300,// 扩散的粒子配置children: {duration: 750,// 随机数范围爆炸radius: { 0: "rand(5,25)" },shape: ["circle", "rect", "polygon"],// 粒子可选色fill: ["#1abc9c","#2ecc71","#00cec9","#3498db","#9b59b6","#fdcb6e","#f1c40f","#e67e22","#e74c3c","#e84393",],degreeShift: "rand(-90, 90)",delay: "stagger(0, 40)",},// 透明度opacity: 0.6,// 生成粒子数量count: 10,});});

③调用动画

  <div class="thums-up" @click="thumbsUp">
……function thumbsUp() {new mojs.Timeline().add(burst).play();}

<template><h3>点赞页面</h3><div class="thums-up" @click="thumbsUp"><div class="heart" ref="heart"><svgt="1644501913302"viewBox="0 0 1024 1024"version="1.1"xmlns="http://www.w3.org/2000/svg"p-id="1268"width="25"height="20"><pathd="M171.712 571.648l0.352 0.32 287.904 252.8a64 64 0 0 0 82.912 1.344l296.832-244.544a215.584 215.584 0 1 0-301.824-300.576L512 316.672l-25.888-35.616a215.584 215.584 0 1 0-314.4 290.624zM32 407.584a279.584 279.584 0 0 1 480-194.944 279.584 279.584 0 0 1 480 194.944 278.144 278.144 0 0 1-113.024 224.512l-295.36 243.392a128 128 0 0 1-165.888-2.592L129.984 620.16A278.976 278.976 0 0 1 32 407.584z"p-id="1269"></path></svg></div><div class="thums-up-text"><span>点赞</span></div></div>
</template><script>
import mojs from "@mojs/core";
import { ref, onMounted } from "vue";
export default {setup() {const heart = ref(null);let burst;onMounted(() => {burst = new mojs.Burst({// 爆炸范围radius: { 0: 50 },// 动画挂载父元素,默认改在到body上parent: heart.value,// 动画延时函数easing: mojs.easing.bezier(0.1, 1, 0.3, 1),// 动画延时时间duration: 1500,// 动画等待时间delay: 300,// 扩散的粒子配置children: {duration: 750,// 随机数范围爆炸radius: { 0: "rand(5,25)" },shape: ["circle", "rect", "polygon"],// 粒子可选色fill: ["#1abc9c","#2ecc71","#00cec9","#3498db","#9b59b6","#fdcb6e","#f1c40f","#e67e22","#e74c3c","#e84393",],degreeShift: "rand(-90, 90)",delay: "stagger(0, 40)",},// 透明度opacity: 0.6,// 生成粒子数量count: 10,});});function thumbsUp() {new mojs.Timeline().add(burst).play();}return {heart,burst,thumbsUp,};},
};
</script><style>
.thums-up {display: flex;align-items: center;justify-content: center;cursor: pointer;height: 24px;
}
.thums-up .heart {display: inline-flex;position: relative;height: 20px;
}.thums-up .heart svg {stroke: #9a9daa;stroke-width: 30px;transition: fill 0.3s, stroke 0.3s;fill: transparent;
}
.thums-up:hover .heart svg {stroke: #e05b5b;
}.thums-up-text {margin-left: 1px;font-size: 13px;user-select: none;
}
</style>

阶段演示效果

四、制作红晕

使用mo.js中的Transit制作一个空心的圆形

1.定义ref

<svgref="heart_icon"t="1644501913302"viewBox="0 0 1024 1024"version="1.1"xmlns="http://www.w3.org/2000/svg"p-id="1268"width="25"height="20">……const heart_icon = ref(null);

2.构建aperture

    let burst , aperture;aperture = new mojs.Transit({parent: heart.value,duration: 750,type: 'circle',radius: { 0 : 20 },fill: 'transparent',stroke: '#E05B5B',strokeWidth: { 20 : 0 },opacity: 0.6,isRunless: true,easing: mojs.easing.bezier(0, 1, 0.5, 1)})

3.增加动画

function thumbsUp() {new mojs.Timeline().add(burst , aperture).play();}

<template><h3>点赞页面</h3><div class="thums-up" @click="thumbsUp"><div class="heart" ref="heart"><svgref="heart_icon"t="1644501913302"viewBox="0 0 1024 1024"version="1.1"xmlns="http://www.w3.org/2000/svg"p-id="1268"width="25"height="20"><pathd="M171.712 571.648l0.352 0.32 287.904 252.8a64 64 0 0 0 82.912 1.344l296.832-244.544a215.584 215.584 0 1 0-301.824-300.576L512 316.672l-25.888-35.616a215.584 215.584 0 1 0-314.4 290.624zM32 407.584a279.584 279.584 0 0 1 480-194.944 279.584 279.584 0 0 1 480 194.944 278.144 278.144 0 0 1-113.024 224.512l-295.36 243.392a128 128 0 0 1-165.888-2.592L129.984 620.16A278.976 278.976 0 0 1 32 407.584z"p-id="1269"></path></svg></div><div class="thums-up-text"><span>点赞</span></div></div>
</template><script>
import mojs from "@mojs/core";
import { ref, onMounted } from "vue";
export default {setup() {const heart = ref(null);const heart_icon = ref(null);let burst , aperture;/*** burst 扩散* aperture 红色光圈(红晕)*/onMounted(() => {burst = new mojs.Burst({// 爆炸范围radius: { 0: 50 },// 动画挂载父元素,默认改在到body上parent: heart.value,// 动画延时函数easing: mojs.easing.bezier(0.1, 1, 0.3, 1),// 动画延时时间duration: 1500,// 动画等待时间delay: 300,// 扩散的粒子配置children: {duration: 750,// 随机数范围爆炸radius: { 0: "rand(5,25)" },shape: ["circle", "rect", "polygon"],// 粒子可选色fill: ["#1abc9c","#2ecc71","#00cec9","#3498db","#9b59b6","#fdcb6e","#f1c40f","#e67e22","#e74c3c","#e84393",],degreeShift: "rand(-90, 90)",delay: "stagger(0, 40)",},// 透明度opacity: 0.6,// 生成粒子数量count: 10,});aperture = new mojs.Transit({parent: heart.value,duration: 750,type: 'circle',radius: { 0 : 20 },fill: 'transparent',stroke: '#E05B5B',strokeWidth: { 20 : 0 },opacity: 0.6,isRunless: true,easing: mojs.easing.bezier(0, 1, 0.5, 1)})});function thumbsUp() {new mojs.Timeline().add(burst , aperture).play();}return {heart,heart_icon,burst,aperture,thumbsUp,};},
};
</script><style>
.thums-up {display: flex;align-items: center;justify-content: center;cursor: pointer;height: 24px;
}
.thums-up .heart {display: inline-flex;position: relative;height: 20px;
}.thums-up .heart svg {stroke: #9a9daa;stroke-width: 30px;transition: fill 0.3s, stroke 0.3s;fill: transparent;
}
.thums-up:hover .heart svg {stroke: #e05b5b;
}.thums-up-text {margin-left: 1px;font-size: 13px;user-select: none;
}
</style>

阶段演示效果

五、制作已点赞效果

1.心形样式绑定

<svgref="heart_icon":style="heartStyle"viewBox="0 0 1024 1024"version="1.1"xmlns="http://www.w3.org/2000/svg"width="20"height="20"><pathd="M533.504 268.288q33.792-41.984 71.68-75.776 32.768-27.648 74.24-50.176t86.528-19.456q63.488 5.12 105.984 30.208t67.584 63.488 34.304 87.04 6.144 99.84-17.92 97.792-36.864 87.04-48.64 74.752-53.248 61.952q-40.96 41.984-85.504 78.336t-84.992 62.464-73.728 41.472-51.712 15.36q-20.48 1.024-52.224-14.336t-69.632-41.472-79.872-61.952-82.944-75.776q-26.624-25.6-57.344-59.392t-57.856-74.24-46.592-87.552-21.504-100.352 11.264-99.84 39.936-83.456 65.536-61.952 88.064-35.328q24.576-5.12 49.152-1.536t48.128 12.288 45.056 22.016 40.96 27.648q45.056 33.792 86.016 80.896z"p-id="2432"></path></svg>
……// 是否已点赞const hearted = ref(false)const heartBounce = ref(1)const heartStyle = computed(() => {return {fill: `${hearted.value ? '#E05B5B' : ''}`,stroke: `${hearted.value ? 'E05B5B' : ''}`,transform: `scale3d(${heartBounce.value},${heartBounce.value},1)`,}})

2.炸裂效果点赞

burst = new mojs.Burst({// 爆炸范围radius: { 0: 50 },……onStart(){hearted.value = true}});

<template><h3>点赞页面</h3><div class="thums-up" @click="thumbsUp"><div class="heart" ref="heart"><!-- <svgref="heart_icon":style="heartStyle"t="1644501913302"viewBox="0 0 1024 1024"version="1.1"xmlns="http://www.w3.org/2000/svg"p-id="1268"width="25"height="20"><pathd="M171.712 571.648l0.352 0.32 287.904 252.8a64 64 0 0 0 82.912 1.344l296.832-244.544a215.584 215.584 0 1 0-301.824-300.576L512 316.672l-25.888-35.616a215.584 215.584 0 1 0-314.4 290.624zM32 407.584a279.584 279.584 0 0 1 480-194.944 279.584 279.584 0 0 1 480 194.944 278.144 278.144 0 0 1-113.024 224.512l-295.36 243.392a128 128 0 0 1-165.888-2.592L129.984 620.16A278.976 278.976 0 0 1 32 407.584z"p-id="1269"></path></svg> --><svgref="heart_icon":style="heartStyle"viewBox="0 0 1024 1024"version="1.1"xmlns="http://www.w3.org/2000/svg"width="20"height="20"><pathd="M533.504 268.288q33.792-41.984 71.68-75.776 32.768-27.648 74.24-50.176t86.528-19.456q63.488 5.12 105.984 30.208t67.584 63.488 34.304 87.04 6.144 99.84-17.92 97.792-36.864 87.04-48.64 74.752-53.248 61.952q-40.96 41.984-85.504 78.336t-84.992 62.464-73.728 41.472-51.712 15.36q-20.48 1.024-52.224-14.336t-69.632-41.472-79.872-61.952-82.944-75.776q-26.624-25.6-57.344-59.392t-57.856-74.24-46.592-87.552-21.504-100.352 11.264-99.84 39.936-83.456 65.536-61.952 88.064-35.328q24.576-5.12 49.152-1.536t48.128 12.288 45.056 22.016 40.96 27.648q45.056 33.792 86.016 80.896z"p-id="2432"></path></svg></div><div class="thums-up-text"><span>点赞</span></div></div>
</template><script>
import mojs from "@mojs/core";
import { ref, onMounted, computed } from "vue";
export default {setup() {const heart = ref(null);const heart_icon = ref(null);// 是否已点赞const hearted = ref(false);const heartBounce = ref(1);const heartStyle = computed(() => {return {fill: `${hearted.value ? "#E05B5B" : ""}`,stroke: `${hearted.value ? "E05B5B" : ""}`,transform: `scale3d(${heartBounce.value},${heartBounce.value},1)`,};});let burst, aperture;/*** burst 扩散* aperture 红色光圈(红晕)*/onMounted(() => {burst = new mojs.Burst({// 爆炸范围radius: { 0: 50 },// 动画挂载父元素,默认改在到body上parent: heart.value,// 动画延时函数easing: mojs.easing.bezier(0.1, 1, 0.3, 1),// 动画延时时间duration: 1500,// 动画等待时间delay: 300,// 扩散的粒子配置children: {duration: 750,// 随机数范围爆炸radius: { 0: "rand(5,25)" },shape: ["circle", "rect", "polygon"],// 粒子可选色fill: ["#1abc9c","#2ecc71","#00cec9","#3498db","#9b59b6","#fdcb6e","#f1c40f","#e67e22","#e74c3c","#e84393",],degreeShift: "rand(-90, 90)",delay: "stagger(0, 40)",},// 透明度opacity: 0.6,// 生成粒子数量count: 10,onStart() {hearted.value = true;},});aperture = new mojs.Transit({parent: heart.value,duration: 750,type: "circle",radius: { 0: 20 },fill: "transparent",stroke: "#E05B5B",strokeWidth: { 20: 0 },opacity: 0.6,isRunless: true,easing: mojs.easing.bezier(0, 1, 0.5, 1),});});function thumbsUp() {new mojs.Timeline().add(burst, aperture).play();}return {heart,heart_icon,hearted,heartBounce,heartStyle,burst,aperture,thumbsUp,};},
};
</script><style>
.thums-up {display: flex;align-items: center;justify-content: center;cursor: pointer;height: 24px;
}
.thums-up .heart {display: inline-flex;position: relative;height: 20px;
}.thums-up .heart svg {stroke: #9a9daa;stroke-width: 60px;transition: fill 0.3s, stroke 0.3s;fill: transparent;
}
.thums-up:hover .heart svg {stroke: #e05b5b;
}.thums-up-text {margin-left: 1px;font-size: 13px;user-select: none;
}
</style>

阶段演示效果

六、制作心跳效果

Tween | mo.js (mojs.github.io)

1.制作跳动函数

bounce = new mojs.Tween({duration: 1200,onUpdate:(progress) => {if(progress > 0.3) {// elastic 弹性的heartBounce.value = mojs.easing.elastic.out(1.43 * progress - 0.43);}else {heartBounce.value = 0}}})

2.添加进thumbsUp函数中

function thumbsUp() {new mojs.Timeline().add(burst, aperture, bounce).play();}

<template><h3>点赞页面</h3><div class="thums-up" @click="thumbsUp"><div class="heart" ref="heart"><!-- <svgref="heart_icon":style="heartStyle"t="1644501913302"viewBox="0 0 1024 1024"version="1.1"xmlns="http://www.w3.org/2000/svg"p-id="1268"width="25"height="20"><pathd="M171.712 571.648l0.352 0.32 287.904 252.8a64 64 0 0 0 82.912 1.344l296.832-244.544a215.584 215.584 0 1 0-301.824-300.576L512 316.672l-25.888-35.616a215.584 215.584 0 1 0-314.4 290.624zM32 407.584a279.584 279.584 0 0 1 480-194.944 279.584 279.584 0 0 1 480 194.944 278.144 278.144 0 0 1-113.024 224.512l-295.36 243.392a128 128 0 0 1-165.888-2.592L129.984 620.16A278.976 278.976 0 0 1 32 407.584z"p-id="1269"></path></svg> --><svgref="heart_icon":style="heartStyle"viewBox="0 0 1024 1024"version="1.1"xmlns="http://www.w3.org/2000/svg"width="20"height="20"><pathd="M533.504 268.288q33.792-41.984 71.68-75.776 32.768-27.648 74.24-50.176t86.528-19.456q63.488 5.12 105.984 30.208t67.584 63.488 34.304 87.04 6.144 99.84-17.92 97.792-36.864 87.04-48.64 74.752-53.248 61.952q-40.96 41.984-85.504 78.336t-84.992 62.464-73.728 41.472-51.712 15.36q-20.48 1.024-52.224-14.336t-69.632-41.472-79.872-61.952-82.944-75.776q-26.624-25.6-57.344-59.392t-57.856-74.24-46.592-87.552-21.504-100.352 11.264-99.84 39.936-83.456 65.536-61.952 88.064-35.328q24.576-5.12 49.152-1.536t48.128 12.288 45.056 22.016 40.96 27.648q45.056 33.792 86.016 80.896z"p-id="2432"></path></svg></div><div class="thums-up-text"><span>点赞</span></div></div>
</template><script>
import mojs from "@mojs/core";
import { ref, onMounted, computed } from "vue";
export default {setup() {const heart = ref(null);const heart_icon = ref(null);// 是否已点赞const hearted = ref(false);const heartBounce = ref(1);const heartStyle = computed(() => {return {fill: `${hearted.value ? "#E05B5B" : ""}`,stroke: `${hearted.value ? "E05B5B" : ""}`,transform: `scale3d(${heartBounce.value},${heartBounce.value},1)`,};});let burst, aperture, bounce;/*** burst 扩散* aperture 红色光圈(红晕)*/onMounted(() => {burst = new mojs.Burst({// 爆炸范围radius: { 0: 50 },// 动画挂载父元素,默认改在到body上parent: heart.value,// 动画延时函数easing: mojs.easing.bezier(0.1, 1, 0.3, 1),// 动画延时时间duration: 1500,// 动画等待时间delay: 300,// 扩散的粒子配置children: {duration: 750,// 随机数范围爆炸radius: { 0: "rand(5,25)" },shape: ["circle", "rect", "polygon"],// 粒子可选色fill: ["#1abc9c","#2ecc71","#00cec9","#3498db","#9b59b6","#fdcb6e","#f1c40f","#e67e22","#e74c3c","#e84393",],degreeShift: "rand(-90, 90)",delay: "stagger(0, 40)",},// 透明度opacity: 0.6,// 生成粒子数量count: 10,onStart() {hearted.value = true;},});aperture = new mojs.Transit({parent: heart.value,duration: 750,type: "circle",radius: { 0: 20 },fill: "transparent",stroke: "#E05B5B",strokeWidth: { 20: 0 },opacity: 0.6,isRunless: true,easing: mojs.easing.bezier(0, 1, 0.5, 1),});bounce = new mojs.Tween({duration: 1200,onUpdate:(progress) => {if(progress > 0.3) {// elastic 弹性的heartBounce.value = mojs.easing.elastic.out(1.43 * progress - 0.43);}else {heartBounce.value = 0}}})});function thumbsUp() {new mojs.Timeline().add(burst, aperture, bounce).play();}return {heart,heart_icon,hearted,heartBounce,heartStyle,burst,aperture,bounce,thumbsUp,};},
};
</script><style>
.thums-up {display: flex;align-items: center;justify-content: center;cursor: pointer;height: 24px;
}
.thums-up .heart {display: inline-flex;position: relative;height: 20px;
}.thums-up .heart svg {stroke: #9a9daa;stroke-width: 60px;transition: fill 0.3s, stroke 0.3s;fill: transparent;
}
.thums-up:hover .heart svg {stroke: #e05b5b;
}.thums-up-text {margin-left: 1px;font-size: 13px;user-select: none;
}
</style>

阶段演示效果

七、制作点赞状态锁

增加一层判断,当处在已点赞状态时,取消状态

function thumbsUp() {if (!hearted.value) {new mojs.Timeline().add(burst, aperture, bounce).play();} else {hearted.value = false}}

阶段演示效果

完整代码

<template><h3>点赞页面</h3><div class="thums-up" @click="thumbsUp"><div class="heart" ref="heart"><!-- <svgref="heart_icon":style="heartStyle"t="1644501913302"viewBox="0 0 1024 1024"version="1.1"xmlns="http://www.w3.org/2000/svg"p-id="1268"width="25"height="20"><pathd="M171.712 571.648l0.352 0.32 287.904 252.8a64 64 0 0 0 82.912 1.344l296.832-244.544a215.584 215.584 0 1 0-301.824-300.576L512 316.672l-25.888-35.616a215.584 215.584 0 1 0-314.4 290.624zM32 407.584a279.584 279.584 0 0 1 480-194.944 279.584 279.584 0 0 1 480 194.944 278.144 278.144 0 0 1-113.024 224.512l-295.36 243.392a128 128 0 0 1-165.888-2.592L129.984 620.16A278.976 278.976 0 0 1 32 407.584z"p-id="1269"></path></svg> --><svg:style="heartStyle"viewBox="0 0 1024 1024"version="1.1"xmlns="http://www.w3.org/2000/svg"width="20"height="20"><pathd="M533.504 268.288q33.792-41.984 71.68-75.776 32.768-27.648 74.24-50.176t86.528-19.456q63.488 5.12 105.984 30.208t67.584 63.488 34.304 87.04 6.144 99.84-17.92 97.792-36.864 87.04-48.64 74.752-53.248 61.952q-40.96 41.984-85.504 78.336t-84.992 62.464-73.728 41.472-51.712 15.36q-20.48 1.024-52.224-14.336t-69.632-41.472-79.872-61.952-82.944-75.776q-26.624-25.6-57.344-59.392t-57.856-74.24-46.592-87.552-21.504-100.352 11.264-99.84 39.936-83.456 65.536-61.952 88.064-35.328q24.576-5.12 49.152-1.536t48.128 12.288 45.056 22.016 40.96 27.648q45.056 33.792 86.016 80.896z"p-id="2432"></path></svg></div><div class="thums-up-text"><span>点赞</span></div></div>
</template><script>
import mojs from "@mojs/core";
import { ref, onMounted, computed } from "vue";
export default {setup() {const heart = ref(null);// 是否已点赞const hearted = ref(false);const heartBounce = ref(1);const heartStyle = computed(() => {return {fill: `${hearted.value ? '#E05B5B' : ''}`,stroke: `${hearted.value ? '#E05B5B' : ''}`,transform: `scale3d(${heartBounce.value},${heartBounce.value},1)`,};});let burst, aperture, bounce;/*** burst 扩散* aperture 红色光圈(红晕)* bounce 心跳*/onMounted(() => {burst = new mojs.Burst({// 爆炸范围radius: { 0: 50 },// 动画挂载父元素,默认改在到body上parent: heart.value,// 动画延时函数easing: mojs.easing.bezier(0.1, 1, 0.3, 1),// 动画延时时间duration: 1500,// 动画等待时间delay: 300,// 扩散的粒子配置children: {duration: 750,// 随机数范围爆炸radius: { 0: "rand(5,25)" },shape: ["circle", "rect", "polygon"],// 粒子可选色fill: ["#1abc9c","#2ecc71","#00cec9","#3498db","#9b59b6","#fdcb6e","#f1c40f","#e67e22","#e74c3c","#e84393",],degreeShift: "rand(-90, 90)",delay: "stagger(0, 40)",},// 透明度opacity: 0.6,// 生成粒子数量count: 10,onStart() {hearted.value = true;},});aperture = new mojs.Transit({parent: heart.value,duration: 750,type: "circle",radius: { 0: 20 },fill: "transparent",stroke: "#E05B5B",strokeWidth: { 20: 0 },opacity: 0.6,isRunless: true,easing: mojs.easing.bezier(0, 1, 0.5, 1),});bounce = new mojs.Tween({duration: 1200,onUpdate: (progress) => {if (progress > 0.3) {// elastic 弹性的heartBounce.value = mojs.easing.elastic.out(1.43 * progress - 0.43);} else {heartBounce.value = 0;}},});});function thumbsUp() {if (!hearted.value) {new mojs.Timeline().add(burst, aperture, bounce).play();} else {hearted.value = false;}}return {heart,hearted,heartBounce,heartStyle,burst,aperture,bounce,thumbsUp,};},
};
</script><style>
.thums-up {display: flex;align-items: center;justify-content: center;cursor: pointer;height: 24px;
}
.thums-up .heart {display: inline-flex;position: relative;height: 20px;
}
.thums-up .heart svg {stroke: #9a9daa;stroke-width: 60px;transition: fill 0.3s, stroke 0.3s;fill: transparent;
}
.thums-up:hover .heart svg {stroke: #e05b5b;
}.thums-up-text {margin-left: 1px;font-size: 13px;user-select: none;
}
</style>

最终效果

思考与总结

终于敲完了,内心也十分喜悦,终于独立完成了一个小小的项目。这个项目中用到了mo.jsvue3的一些钩子函数(例如,onMountedonComputed等等),特别是ref响应式数据,目前感觉这个点挺神奇(reactive

  • 这个项目的所有属性和方法都是写在setup(即vue2中的createdbeforeCreated)中的,按道理来说是不需要的,这个小项目也算是带我领略了一番vue3的风采吧。

  • 知道了css样式编写大致格式(最好统一,见名知意)

  • 还有就是第一次尝试跟着博客做一个开源的项目,尽管很小,很简单,但是也给了我一些开源项目的方法

    • 1、将代码复制到本地跑起来

    • 2、另起炉灶,跟着博客大致搭建起来(在抄写代码的时候,改成自己的代码风格,比如在这个项目中,我用到了css代码风格)

    • 3、遇见效果不一致的先自己猜测可能出现问题的地方,对比差别,逐一排查(一个一个替换进去,再思考为什么)

      其实,这个项目中有一些css样式,我就没有抄写

      因为我发现效果是一样的,所以就没有添加,比如说imargin-right


参考博客:

制作粒子扩散的点赞动效果 - 掘金 (juejin.cn)

vue 3 + mo.js 实现点赞粒子特效【实战】相关推荐

  1. 原生js实现canvas粒子特效

    要实现的效果 当鼠标移入容器时,让鼠标作为中心点半径为80到圆内的粒子散开 当粒子不在圆的范围后,粒子返回原来的位置 主要代码 创建初始位置 // NUM_PARTICLES是粒子总个数for ( i ...

  2. Vue如何引入粒子特效

    Vue如何引入粒子特效 1.安装插件 npm install vue-particles --save-dev 2.在main.js全局引入 // 引入粒子特效 import VueParticles ...

  3. 用vue做粒子特效背景

    1.你需要先引入vue-particles教脚手架 npm install vue-particles --save-dev 在main.js里面放入 import VueParticles from ...

  4. VUE粒子特效vue-particles插件使用

    vue-particles粒子特效 第一步:下载包 vue-particles npm install --save vue-particles 第二步:在main.js中引入 vue-particl ...

  5. 使用particles.js实现网页背景粒子特效

    得知途径 B3log提供了两套博客系统,一个是用Java开发的,叫做Solo,我也是在网上搜索Java博客系统时发现了它,之后才了解了B3log:还有一个是用Go语言开发的,叫做Pipe.其中Solo ...

  6. three.js 实现图片粒子爆炸特效

    大家好,这里是 CSS 魔法使--alphardex. 以下是最终实现的效果图 撒,哈吉马路由! 准备工作 笔者的three.js模板:点击右下角的fork即可复制一份 世界同步 在我的上一篇博文中, ...

  7. html、css、js粒子特效——前端

    html.css.js粒子特效--前端 看看效果图 首先是html结构 使用canvas设置一个画布 <canvas width="500px" height="5 ...

  8. js实现粒子特效,particles.js的使用

    今天偶然看到了一个比较炫酷的js网页.是粒子特效的,就试着用了用.一下是步骤,方便以后查看使用. 1.在网站下载源码https://github.com/VincentGarreau/particle ...

  9. vue js樱花飘落背景特效

    vue js樱花飘落背景特效 先上效果图 下载js文件:链接 或直接保存源码 var stop, staticx; var img = new Image(); img.src = "dat ...

最新文章

  1. spring boot 实战 / 可执行war启动参数详解
  2. 使用迭代查找一个list中最小和最大值,并返回一个tuple。
  3. 和quot;分别是什么?
  4. 简单的WinInet编程
  5. 用linq查询html中div个数,C#使用Linq to XML进行XPath查询
  6. 苹果手机透明桌面_原来苹果手机辨别真假这么简单!查看桌面1个图标,就能轻松分辨...
  7. 【编撰】linux IPC 002 - 匿名管道PIPE和有名管道FIFO的概念和实例,以及应用比较
  8. 【cogs2593】幂,暴搜+容斥
  9. 一位程序员 8 年的物联网奋斗史
  10. hdfs+zookeeper+hbase分布式在k8s中部署(本文已过期)
  11. 汇编语言32位加减乘除运算题
  12. alexnet论文_【SOT】Siamese RPN++ 论文和代码解析
  13. 项目实施方案指导性文件
  14. 基本磁盘转换为动态磁盘后快速启动关机变重启,记录一次研究过程
  15. android 截屏分享权限,android 截屏+保存图片+权限
  16. canvas中文显示乱码 html5_HTML5 CANVAS:绘制文字
  17. xml转json(使用工具)
  18. 游戏开发入门(十)游戏中的网络模块
  19. EXIT: Extrapolation and Interpolation-based Neural Controlled Differential Equations for Time-series
  20. input file选择图片后显示(FileReader)

热门文章

  1. lerna + yarn workspaces 使用备忘
  2. 给新手程序员的一点学习建议
  3. html+canvas 星空背景案例
  4. 合工大路强java第四次作业第5题
  5. eclips 快捷键大全
  6. geany怎么编写python_Geany怎么使用,Geany安装使用教程
  7. 外置USB供电与内置锂电池供电自动切换电路,便携电子设备常用,经典电路必须掌握...
  8. WIN10下配置Yolov3(VS2019,GPU)+opencv训练自己的数据集(绝对详细,小白型记录)
  9. 还在想假期去哪玩?直接做一个旅游攻略小程序
  10. 三星拿出了四摄手机,可惜诚意不足,挑战国产手机成奢望