vue 3 + mo.js 实现点赞粒子特效【实战】
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建议书写顺序:
- 布局定位属性:display / position / float / clear / visibility / overflow
- 自身属性:width / height / margin / padding / border / background
- 文本属性:color / font / text-decoration / text-align / vertical-align / white- space / break-word
- 其他属性(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.js
和vue3
的一些钩子函数(例如,onMounted
,onComputed
等等),特别是ref
响应式数据,目前感觉这个点挺神奇(reactive
)
这个项目的所有属性和方法都是写在
setup
(即vue2中的created
和beforeCreated
)中的,按道理来说是不需要的,这个小项目也算是带我领略了一番vue3
的风采吧。知道了css样式编写大致格式(最好统一,见名知意)
还有就是第一次尝试跟着博客做一个开源的项目,尽管很小,很简单,但是也给了我一些开源项目的方法
1、将代码复制到本地跑起来
2、另起炉灶,跟着博客大致搭建起来(在抄写代码的时候,改成自己的代码风格,比如在这个项目中,我用到了
css代码风格
)3、遇见效果不一致的先自己猜测可能出现问题的地方,对比差别,逐一排查(一个一个替换进去,再思考为什么)
其实,这个项目中有一些css样式,我就没有抄写
因为我发现效果是一样的,所以就没有添加,比如说
i
,margin-right
等
参考博客:
制作粒子扩散的点赞动效果 - 掘金 (juejin.cn)
vue 3 + mo.js 实现点赞粒子特效【实战】相关推荐
- 原生js实现canvas粒子特效
要实现的效果 当鼠标移入容器时,让鼠标作为中心点半径为80到圆内的粒子散开 当粒子不在圆的范围后,粒子返回原来的位置 主要代码 创建初始位置 // NUM_PARTICLES是粒子总个数for ( i ...
- Vue如何引入粒子特效
Vue如何引入粒子特效 1.安装插件 npm install vue-particles --save-dev 2.在main.js全局引入 // 引入粒子特效 import VueParticles ...
- 用vue做粒子特效背景
1.你需要先引入vue-particles教脚手架 npm install vue-particles --save-dev 在main.js里面放入 import VueParticles from ...
- VUE粒子特效vue-particles插件使用
vue-particles粒子特效 第一步:下载包 vue-particles npm install --save vue-particles 第二步:在main.js中引入 vue-particl ...
- 使用particles.js实现网页背景粒子特效
得知途径 B3log提供了两套博客系统,一个是用Java开发的,叫做Solo,我也是在网上搜索Java博客系统时发现了它,之后才了解了B3log:还有一个是用Go语言开发的,叫做Pipe.其中Solo ...
- three.js 实现图片粒子爆炸特效
大家好,这里是 CSS 魔法使--alphardex. 以下是最终实现的效果图 撒,哈吉马路由! 准备工作 笔者的three.js模板:点击右下角的fork即可复制一份 世界同步 在我的上一篇博文中, ...
- html、css、js粒子特效——前端
html.css.js粒子特效--前端 看看效果图 首先是html结构 使用canvas设置一个画布 <canvas width="500px" height="5 ...
- js实现粒子特效,particles.js的使用
今天偶然看到了一个比较炫酷的js网页.是粒子特效的,就试着用了用.一下是步骤,方便以后查看使用. 1.在网站下载源码https://github.com/VincentGarreau/particle ...
- vue js樱花飘落背景特效
vue js樱花飘落背景特效 先上效果图 下载js文件:链接 或直接保存源码 var stop, staticx; var img = new Image(); img.src = "dat ...
最新文章
- spring boot 实战 / 可执行war启动参数详解
- 使用迭代查找一个list中最小和最大值,并返回一个tuple。
- 和quot;分别是什么?
- 简单的WinInet编程
- 用linq查询html中div个数,C#使用Linq to XML进行XPath查询
- 苹果手机透明桌面_原来苹果手机辨别真假这么简单!查看桌面1个图标,就能轻松分辨...
- 【编撰】linux IPC 002 - 匿名管道PIPE和有名管道FIFO的概念和实例,以及应用比较
- 【cogs2593】幂,暴搜+容斥
- 一位程序员 8 年的物联网奋斗史
- hdfs+zookeeper+hbase分布式在k8s中部署(本文已过期)
- 汇编语言32位加减乘除运算题
- alexnet论文_【SOT】Siamese RPN++ 论文和代码解析
- 项目实施方案指导性文件
- 基本磁盘转换为动态磁盘后快速启动关机变重启,记录一次研究过程
- android 截屏分享权限,android 截屏+保存图片+权限
- canvas中文显示乱码 html5_HTML5 CANVAS:绘制文字
- xml转json(使用工具)
- 游戏开发入门(十)游戏中的网络模块
- EXIT: Extrapolation and Interpolation-based Neural Controlled Differential Equations for Time-series
- input file选择图片后显示(FileReader)
热门文章
- lerna + yarn workspaces 使用备忘
- 给新手程序员的一点学习建议
- html+canvas 星空背景案例
- 合工大路强java第四次作业第5题
- eclips 快捷键大全
- geany怎么编写python_Geany怎么使用,Geany安装使用教程
- 外置USB供电与内置锂电池供电自动切换电路,便携电子设备常用,经典电路必须掌握...
- WIN10下配置Yolov3(VS2019,GPU)+opencv训练自己的数据集(绝对详细,小白型记录)
- 还在想假期去哪玩?直接做一个旅游攻略小程序
- 三星拿出了四摄手机,可惜诚意不足,挑战国产手机成奢望