uniapp结合Canvas+renderjs根据经纬度绘制轨迹(二)

uniapp结合Canvas+renderjs根据经纬度绘制轨迹


  • 根据官方建议要想在 app-vue 流畅使用 Canvas 动画,需要使用 renderjs 技术,把操作canvas的js逻辑放到视图层运行,避免逻辑层和视图层频繁通信。
  • 这里呢结合 renderjs 技术实现绘制轨迹图形。

你可能需要先了解renderjs如何数据通讯:renderjs 与 app-vue之间数据交互

html中使用canvas根据经纬度绘制轨迹


效果图

在这里插入图片描述


template

  • coordsAll 监听数据变化,只要 coordsAll 数据改变,就是触发 initData 方法。
 <template>
	<view class="map-track-wrap">
      	<!-- xxx -->
      	<view class="track-list" :prop="coordsAll" :change:prop="canvas.initData">
          	<!-- xxx -->
          <view class="d-flex canvas-box">
            	<canvas class="canvas" :class="`canvas${index}`"></canvas>
          </view>
       	</view>
    </view>
</template>

renderjs

<script module="canvas" lang="renderjs">
	export default {
		methods: {
			initData() {
				for (let i = 0; i < this.coordsAll.length; i++) {
					// 绘制图形
					this.draw(this.coordsAll[i], i);
				}
			},
			draw(locationList, idx) {
				let canvasHeight = 72,
					canvasWidth = 72,
					canvasEle = document.querySelectorAll(`.canvas${idx}>canvas`)[0],
					ctx = canvasEle.getContext('2d'),
					amuXArr = [],
					amuYArr = []

				for (let i = 0; i < locationList.length; i++) {
					amuXArr.push(locationList[i].lat);
					amuYArr.push(locationList[i].lng);
				}
				
				amuYArr = amuYArr.map((item) => {
					return item * -1;
				});

				let xMax = Math.max(...amuXArr);
				let xMin = Math.min(...amuXArr);
				let yMax = Math.max(...amuYArr);
				let yMin = Math.min(...amuYArr);

				let xScale = canvasWidth / (xMax - xMin);
				let yScale = canvasHeight / (yMax - yMin);
				let scale = xScale < yScale ? xScale : yScale;

				let xoffset = (canvasWidth - (xMax - xMin) * scale) / 2;
				let yoffset = (canvasHeight - (yMax - yMin) * scale) / 2;
				
				ctx.save(); // 保存状态
				ctx.translate(0, canvasHeight);
				ctx.rotate(-Math.PI / 2);
				ctx.beginPath();

				// 根据偏移量移动点位并画图
				ctx.moveTo(
					(amuXArr[0] - xMin) * scale + xoffset,
					(yMax - amuYArr[0]) * scale + yoffset
				);
				for (let i = 1; i < amuXArr.length; i++) {
					ctx.lineTo(
						(amuXArr[i] - xMin) * scale + xoffset,
						(yMax - amuYArr[i]) * scale + yoffset
					);
				}
				ctx.strokeStyle = '#1FE298';
				ctx.stroke();
				ctx.restore(); // 恢复状态
			}
		}
	}
</script>

js

  • renderjs中不支持uni.request,所以请求后台获取数据操作在script中进行,然后监听参数变化,将参数传递过来进行渲染。
searchList() {      	
  	// 处理数据
  	let list = this.dataList;
  	if (list.length > 0) {
    	for(let i = 0; i < list.length; i++) {
      		let tmpLocation = list[i].locations;
         	// 页面监听 coordsAll,把数据传递renderjs,会触发 initData 方法
      		this.coordsAll.push(JSON.parse(tmpLocation));
    	}
  	}
}

数据结构

  • 测试数据,具体根据个人所需处理数据
[
    {
        locations: [
          	{
                "lng": 113.980502,
                "lat": 22.54161
        	},
            {
              "lng": 113.972839,
              "lat": 22.533976
            },
            {
              "lng": 113.98925,
              "lat": 22.524669
            },
            {
              "lng": 113.990034,
              "lat": 22.537097
            },
            {
              "lng": 114.00916,
              "lat": 22.534477
            }
    	]
  	},
    {
      	locations: [
            {
              "lng": 113.924271,
              "lat": 22.537654
            },
            {
              "lng": 113.9367,
              "lat": 22.532806
            },
            {
              "lng": 113.928494,
              "lat": 22.518594
            },
            {
              "lng": 113.942673,
              "lat": 22.524502
            },
            {
              "lng": 113.944302,
              "lat": 22.538601
            }
    	]
  	},
  	{
      	locations: [
            {
                "lng": 113.98049,
                "lat": 22.54301
            },
            {
                "lng": 114.06374,
                "lat": 22.51134
            },
            {
                "lng": 114.06259,
                "lat": 22.50951
            },
            {
                "lng": 114.06178,
                "lat": 22.51031
            },
            {
                "lng": 113.96047,
                "lat": 22.54611
            }
       ]
  	}
]
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
uniapp使用canvas绘制水印,可以通过以下步骤实现: 1. 首先,在uniapp项目中创建一个新的页面或组件,用于显示canvas画布。 2. 在该页面或组件中,使用`<canvas>`标签创建一个画布元素,并设置其宽度和高度。 3. 使用`uni.createCanvasContext()`方法创建一个绘图上下文对象,用于操作画布。 4. 使用绘图上下文对象的相关方法,如`fillText()`、`fillRect()`等来绘制水印内容。 5. 通过调用绘图上下文对象的`draw()`方法将绘制的内容显示在画布上。 下面是一个简单的示例代码,演示了如何在uniapp使用canvas绘制水印: ``` <template> <view> <canvas id="canvas" style="width: 300px; height: 200px;"></canvas> </view> </template> <script> export default { onReady() { const ctx = uni.createCanvasContext('canvas', this); ctx.setFillStyle('rgba(0, 0, 0, 0.5)'); // 设置水印颜色和透明度 ctx.setFontSize(16); // 设置水印字体大小 ctx.fillText('水印内容', 10, 20); // 绘制水印文本 ctx.draw(); // 绘制到画布上 } } </script> ``` 在上述代码中,我们使用uniapp提供的`uni.createCanvasContext()`方法创建了一个绘图上下文对象,并通过该对象的`setFillStyle()`、`setFontSize()`以及`fillText()`方法来设置水印的样式和内容。最后,通过调用`draw()`方法将绘制的水印显示在画布上。 需要注意的是,在uniapp使用canvas绘制水印时,需要确保在`onReady()`生命周期函数中进行绘制操作,以确保画布已经完全加载。另外,还需要注意设置画布的宽度和高度,以及调整水印的位置和样式,以满足具体需求。 希望以上内容对您有所帮助!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值