uniapp开发微信小程序canvas动画入门

uniapp开发微信小程序canvas动画入门

前言

老版的微信小程序canvas接口由于是视图层和逻辑层双线程的关系,动画效果很卡,而且api都是为了标新立异,重新包装H5的,学习起来也要再花时间.
2.9.0版之后终于与H5的接口同步了,并且性能也得到了极大的优化,简单的动画在移动端运行起来还是非常流畅的.
大家在很多网页上都见过粒子飘来飘去的动画,有点物联网的感觉…
下面使用uniapp开发环境实现一个微信小程序端的粒子动画背景,app端不支持新版的接口,运行会报错.

粒子动画参考代码

效果预览

在这里插入图片描述
此截图是在开发者工具上录的,实际上没有那些灰色的块块
新版的canvas接口支持同层渲染,所以只需要将canvas层的z-index调到下面就行了.
真机预览下小球球是在其他元素下面的,不会影响主要元素.

页面代码

<template>
	<view>
		<view class="container">
			<view class="login-header">
				<!-- <img src="/static/login.png" alt=""> -->
				<view>XXXXX系统</view>
			</view>
			<view class="uni-form-item uni-column">
				<input class="uni-input" focus placeholder="用户名" v-model="user" @input="userChange" />
			</view>
			<view class="uni-form-item uni-column">
				<input class="uni-input" password type="text" placeholder="密码" v-model="pass" @input="passChange" />
			</view>
			<br>
			<button class="loginBtn" type="primary" @click="onLogin">登录</button>
		</view>
		<canvas type="2d" id="myCanvas"></canvas>
	</view>
</template>

<script>
	
	import Circle from './circle.js' 
	
	export default {
		data() {
			return {
				user: 'xxxxxxx',
				pass: '123456'
			}
		},
		onReady: function (e) {
		    const query = uni.createSelectorQuery()
			query.select('#myCanvas')
			  .fields({ node: true, size: true })
			  .exec((res) => {
				const canvas = res[0].node
				const ctx = canvas.getContext('2d')
				const sysInfo = uni.getSystemInfoSync()
				const dpr = sysInfo.pixelRatio
				canvas.width = res[0].width * dpr
				canvas.height = res[0].height * dpr
				ctx.scale(dpr, dpr)
		
				let circles = []
				let width = sysInfo.windowWidth
				let height = sysInfo.windowHeight
				let num = 50
				
				for (let i = 0; i < num; i++) {
				    let circle = new Circle(Math.random() * width, Math.random() * height, width, height)
				    circles.push(circle)
				}
				function draw(num) {
					ctx.clearRect(0, 0, width, height)
					for (let i = 0; i < num; i++) {
						circles[i].drawCircle(ctx)
						for (let j = i + 1; j < num; j++) {
							circles[i].drawLine(ctx, circles[j])
						}
						circles[i].move()
					}
				}
				setInterval(()=> {
					draw(num)
				}, 33)
			 })
		},
		
		methods: {
			userChange: function(e) {
				this.user = e.detail.value
			},
			passChange: function(e) {
				this.pass = e.detail.value
			},
			onLogin: function(e) {
				
			}
	},
	}
</script>

<style lang="scss" scoped>
	#myCanvas {
		position: absolute;
		left: 0;
		top: 0;
		width: 100%;
		height: 100%;
		z-index: -1;
	}
	.container {
		padding: 15px;
		// font-size: 14px;
		// line-height: 24px;
	}
	input {
		padding: 15px 0;
		border-bottom: 1px solid #C0C0C0;
	}
	.loginBtn {
		background-color: $my-primary;
	}
	/* #ifdef MP-WEIXIN */
	.loginBtn {
		margin-top: 25px;
	}
	/* #endif */
	.login-header {
		text-align: center;
		font-size: 18px;
		margin-bottom: 10px;
		img {
			width: 100px;
			height: 41px;
		}
	}
</style>

下面是circle.js的代码

class Circle {
	constructor(x, y, width, height) {
		this.x = x
		this.y = y
		this.r = Math.random() * 10
		this._mx = Math.random()
		this._my = Math.random()
		this.width = width
		this.height = height
	}
	drawCircle(ctx) {
		ctx.beginPath()
		ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI)
		ctx.fillStyle = 'rgba(204, 204, 204, 0.3)'
		ctx.fill()
		ctx.closePath()
	}
	drawLine(ctx, _circle) {
		let dx = this.x - _circle.x
		let dy = this.y - _circle.y
		let d = Math.sqrt(dx * dx + dy * dy)
		if (d < 70) {
			ctx.beginPath()
			ctx.moveTo(this.x, this.y)
			ctx.lineTo(_circle.x, _circle.y)
			ctx.strokeStyle = 'rgba(204, 204, 204, 0.5)'
			ctx.stroke()
			ctx.closePath()
		}
	}
	move() {
		this._mx = (this.x < this.width && this.x > 0) ? this._mx : (-this._mx)
		this._my = (this.y < this.height && this.y > 0) ? this._my : (-this._my)
		this.x += this._mx
		this.y += this._my
	}
}

export default Circle

移动端没有鼠标,关于鼠标那部分的粒子球代码就去掉了.
小程序官方文档里是有requestAnimationFrame这个接口的,但我试了一下,用上以后也不报错也不会动…
所以只能用setInterval了,33毫秒重绘一次,也就是一秒钟30帧,看起来已经很流畅了.
在这里插入图片描述

结论

这个粒子球跑来跑去加连线的动画有点物联网的感觉,有木有?
把代码放到自己的项目里跑一跑,修修改改试一试,小程序端的canvas开发也就入门了.
浏览器端的canvas库什么的就别指望了,在小程序里用起来很麻烦.老老实实用原生的接口,做个简单的功能还不算太难.
写canvas代码的精髓:就把它想象成一张一张的图画,然后把重绘代码放到定时器里.如下图:
在这里插入图片描述

  • 6
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
您好!如果您想要将 Uniapp 微信小程序中的界面转换为图片,可以尝试使用以下方法: 1. 使用 `uni.canvasToTempFilePath()` 方法将界面转换为图片 Uniapp 中提供了 `uni.canvasToTempFilePath()` 方法,可以将指定的 canvas 区域内容转换为临时文件路径。因此,我们可以通过将整个页面的内容绘制到一个 canvas 中,再将 canvas 转换为图片,来实现将界面转换为图片的功能。 下面是一个简单的示例代码: ```javascript // 获取 canvas 上下文 const query = uni.createSelectorQuery() query.select('#myCanvas').fields({ node: true, size: true }) .exec((res) => { const canvas = res[0].node const ctx = canvas.getContext('2d') // 绘制整个页面内容到 canvas 上 const page = getCurrentPages()[getCurrentPages().length - 1] const width = page.windowWidth const height = page.windowHeight const dpr = uni.getSystemInfoSync().pixelRatio canvas.width = width * dpr canvas.height = height * dpr ctx.scale(dpr, dpr) uni.renderPage(page).then(() => { uni.drawCanvas({ canvasId: 'myCanvas', x: 0, y: 0, width: width, height: height, destWidth: width * dpr, destHeight: height * dpr, }) }) // 将 canvas 转换为临时文件路径 uni.canvasToTempFilePath({ canvasId: 'myCanvas', success: (res) => { console.log(res.tempFilePath) // 可以将临时文件路径保存到本地或者上传到服务器 }, }) }) ``` 在上面的代码中,我们首先获取了当前页面的 canvas 上下文,并将整个页面的内容绘制到了 canvas 上。然后,我们使用 `uni.canvasToTempFilePath()` 方法将 canvas 转换为临时文件路径,最后可以将临时文件路径保存到本地或者上传到服务器。 2. 注意事项 需要注意的是,如果您的界面中包含了涉及用户隐私的内容(例如输入框、密码框等),则不应将整个界面转换为图片。另外,由于微信小程序的安全限制,界面转换为图片的功能在某些场景下可能会受到限制,具体情况需要根据实际测试结果而定。 希望以上内容能够帮助到您,如果您还有其他问题或者需要更详细的解答,请随时提出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值