uniapp动态气泡上升效果

4 篇文章 0 订阅
1 篇文章 0 订阅

1、效果图:

2、创建子组件canvas_love.vue

<template>
	<view class="action">
		<view class="icon_img">
			<view class="icon_smallimg"></view>
			<view class="texttag">限时5折起</view>
			<canvas canvas-id="mycanvas" class="canvas" />
		</view>
	</view>
</template>

<script>
	var lastFrameTime = 0;
	var count = 0;
	var ctx = null;
	var factor = {
		speed: 0.004, // 运动速度,值越小越慢
		t: 0 //  贝塞尔函数系数
	};
	var that;
	var timer = null; // 循环定时器
	export default {
		name: 'canvas_love',
		data() {
			return {
				style_img: '',
				img_path: [
					[{
						x: 30,
						y: 50
					}, {
						x: 40,
						y: 30
					}, {
						x: 60,
						y: 25
					}, {
						x: 40,
						y: 0
					}],
					[{
						x: 30,
						y: 50
					}, {
						x: 70,
						y: 20
					}, {
						x: 80,
						y: 10
					}, {
						x: 30,
						y: 0
					}],
					[{
						x: 30,
						y: 50
					}, {
						x: 60,
						y: 10
					}, {
						x: 70,
						y: 0
					}, {
						x: 20,
						y: 0
					}]
				]
			}
		},
		created() {
			that = this
			//获取canvas实例
			ctx = uni.createCanvasContext('mycanvas', this)
		},
		mounted() {
			//一直循环:  repeatcount 为-1的情况
			that.startTimer(-1)
			// console.log("挂载完成,可以拿到属性", ctx);
		},
		destroyed() {
			if (timer != null) {
				clearTimeout(timer)
			}
		},
		methods: {
			//不断绘制图片到canvas;requestAnimationFrame函数用来控制动画的时间长短
			requestAnimationFrame(callback) {
				var currTime = new Date().getTime();
				//手机屏幕刷新率一般为60Hz,大概16ms刷新一次,这里为了使页面看上去更流畅自然,通过改变timedis的值可以控制动画的快慢
				var timedis = 16 - (currTime - lastFrameTime)
				var timeToCall = Math.max(0, timedis);
				var id = setTimeout(callback, timeToCall);
				lastFrameTime = currTime + timeToCall;
				return id;
			},

			drawImage: function(data, repeatcount) {

				if (repeatcount == 0) {
					return
				}
				var p10 = data[0][0]; // 三阶贝塞尔曲线起点坐标值
				var p11 = data[0][1]; // 三阶贝塞尔曲线第一个控制点坐标值
				var p12 = data[0][2]; // 三阶贝塞尔曲线第二个控制点坐标值
				var p13 = data[0][3]; // 三阶贝塞尔曲线终点坐标值

				var p20 = data[1][0];
				var p21 = data[1][1];
				var p22 = data[1][2];
				var p23 = data[1][3];

				var p30 = data[2][0];
				var p31 = data[2][1];
				var p32 = data[2][2];
				var p33 = data[2][3];

				var t = factor.t;

				/*计算多项式系数*/
				var cx1 = 3 * (p11.x - p10.x);
				var bx1 = 3 * (p12.x - p11.x) - cx1;
				var ax1 = p13.x - p10.x - cx1 - bx1;

				var cy1 = 3 * (p11.y - p10.y);
				var by1 = 3 * (p12.y - p11.y) - cy1;
				var ay1 = p13.y - p10.y - cy1 - by1;

				/*计算xt yt坐标值 */
				var xt1 = ax1 * (t * t * t) + bx1 * (t * t) + cx1 * t + p10.x;
				var yt1 = ay1 * (t * t * t) + by1 * (t * t) + cy1 * t + p10.y;

				/** 计算多项式系数*/
				var cx2 = 3 * (p21.x - p20.x);
				var bx2 = 3 * (p22.x - p21.x) - cx2;
				var ax2 = p23.x - p20.x - cx2 - bx2;

				var cy2 = 3 * (p21.y - p20.y);
				var by2 = 3 * (p22.y - p21.y) - cy2;
				var ay2 = p23.y - p20.y - cy2 - by2;

				/*计算xt yt坐标值*/
				var xt2 = ax2 * (t * t * t) + bx2 * (t * t) + cx2 * t + p20.x;
				var yt2 = ay2 * (t * t * t) + by2 * (t * t) + cy2 * t + p20.y;


				/** 计算多项式系数*/
				var cx3 = 3 * (p31.x - p30.x);
				var bx3 = 3 * (p32.x - p31.x) - cx3;
				var ax3 = p33.x - p30.x - cx3 - bx3;

				var cy3 = 3 * (p31.y - p30.y);
				var by3 = 3 * (p32.y - p31.y) - cy3;
				var ay3 = p33.y - p30.y - cy3 - by3;

				/*计算xt yt坐标值*/
				var xt3 = ax3 * (t * t * t) + bx3 * (t * t) + cx3 * t + p30.x;
				var yt3 = ay3 * (t * t * t) + by3 * (t * t) + cy3 * t + p30.y;
				factor.t += factor.speed;
				ctx.drawImage("/static/images/love1.png", xt1, yt1, 20, 20);
				ctx.drawImage("/static/images/love2.png", xt2, yt2, 14, 14);
				ctx.drawImage("/static/images/love3.png", xt3, yt3, 8, 8);
				ctx.draw();
				if (factor.t > 1) {
					factor.t = 0;
					clearTimeout(timer)
					if (repeatcount <= -1) {
						that.startTimer(repeatcount)
					} else {
						if (count < repeatcount) {
							that.startTimer(repeatcount)
							count++
						} else {
							that.draworiginal()
							count = 0;
						}
					}
				} else {
					timer = that.requestAnimationFrame(function() {
						that.drawImage(that.img_path, repeatcount)
					})
				}
			},
			//适用于不循环时设置点击事件触发动画
			onClickImage: function(e) {
				//点击心形的时候动画效果
				// that.style_img = 'transform: scale(1);'
				// setTimeout(function() {
				// 	that.style_img = 'transform:scale(1);'
				// }, 500)
				factor.t = 2
				count = 0
				that.startTimer(-1)
			},
			//repeatcount -1就是循环,其他大于零的整数就是动画循环次数
			startTimer: function(repeatcount) {
				that.drawImage(that.img_path, repeatcount)
			},
			//draworiginal函数将图片都画到原始位置
			draworiginal() {
				ctx.drawImage("/static/images/love1.png", 30, 50, 30, 30);
				ctx.drawImage("/static/images/love2.png", 30, 50, 30, 30);
				ctx.drawImage("/static/images/love3.png", 30, 50, 30, 30);
				ctx.draw();
			}
		}

	}
</script>

<style lang="scss">
	.canvas {
		background: transparent;
		width: 180rpx;
		height: 100rpx;
		position: absolute;
		bottom: 32rpx;
		left: 60rpx;
		display: flex;
		flex-direction: column;
		align-items: flex-end;
	}

	.action {
		margin-top: 150rpx;
		margin-left: 100rpx;
	}

	.icon_img {
		background-image: url('@/static/images/wzd.png');
		background-repeat: no-repeat;
		background-size: 100% auto;
		/* #ifdef H5 */
		width: 180rpx;
		height: 38rpx;
		/* #endif */
		/* #ifndef H5 */
		width: 170rpx;
		height: 32rpx;
		/* #endif */
		display: flex;
		align-items: center;
		justify-content: center;
		position: relative;
		top: 0;
		left: 0;
		transform: scale(1);
		-webkit-transform: scale(1);
		-webkit-transition: ease all;
		-moz-transition: ease all;
		transition: ease all;
		-webkit-transition-duration: 700ms;
		-moz-transition-duration: 700ms;
		transition-duration: 700ms;
	}

	.icon_smallimg {
		background-image: url('@/static/images/5z.png');
		background-repeat: no-repeat;
		background-size: 100% auto;
		width: 30rpx;
		height: 24rpx;
	}

	.texttag {
		// width: 84rpx;
		height: 32rpx;
		line-height: 32rpx;
		margin-left: 10rpx;
		font-size: 22rpx;
		font-weight: 400;
		color: #FFFFFF;
		display: flex;
		align-items: center;
	}
</style>

3、父组件中引入、注册并使用

<template>
	<view class="often">
		<!-- 常用组件库 -->
		<canvas-love></canvas-love>
	</view>
</template>

<script>
	import canvasLove from './components/canvas_love.vue'
	export default {
		components: {
			canvasLove
		},
		data() {
			return {

			}
		},
		onShow() {

		},
		methods: {

		}

	}
</script>

<style lang="scss">

</style>

4、注:h5正常但微信小程序失效(代码已处理)

新版本的uni-app要求传入当前this对象
uni.createCanvasContext('mycanvas', this)

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
UniApp中实现自定义气泡可以通过使用marker的customCallout属性来实现。该属性可以让你自定义marker的气泡效果,使其能够在marker的下方展示站点名称。你可以在微信小程序官方文档中查阅相关内容来了解更多细节。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [uniapp 微信小程序 map自定义气泡customCallout](https://blog.csdn.net/qq_41395120/article/details/121117331)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [支持在地图自定义标记气泡效果](https://download.csdn.net/download/weixin_38517212/16303749)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [uniapp 小程序 地图<map> 渲染标注点 且自定义气泡内容(slot写到页面中/样式自定义)](https://blog.csdn.net/weixin_44805839/article/details/128207937)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值