【无标题】微信小程序的一些关于Canvas用法(实战篇)

需求

这次的需求有点难描述,设计图的一部分长这样:
在这里插入图片描述
最终实现效果呈这样:

在这里插入图片描述
天知道这圆环的纹路还要不要实现,暂时是无能为力了,主要是不知道怎么问AI效果都不对,以后解决了再更新。

需求分析

首先是这圆环了跟这个可移动的小圆了,问了百度的AI,没用Canvas,纯手搓的效果相当差,在屏幕中到处跑,根本束缚不住。
当时在搜相关有用的代码时发现别人用的Canvas代码,算是帮了大忙: 大佬代码,因为比较新,对于我接下来使用谷歌浏览器的Sider使用的chatgpt3.5版AI时代码比较旧,有些代码已经被微信小程序弃用了,参考一下大佬的才算是转换过来。

1、圆环与可控制移动的点

问(PS.问了N次):微信小程序ui实现绕固定原点与半径的可控制移动的点,请提供代码
答:以下是一个示例代码,它可以在微信小程序中实现一个点围绕固定原点(圆心)按给定半径进行可控制的移动。用户可以通过滑动手指在屏幕上改变点的位置。

  1. WXML 文件
    在你的 WXML 文件中添加一个 控件,并设置相应的样式。
<view class="container">  
  <canvas canvas-id="circleCanvas" style="width: 300px; height: 300px;" bindtouchmove="onTouchMove" bindtouchend="onTouchEnd"></canvas>  
</view>  
  1. JS 文件
    在 JavaScript 文件中,编写逻辑以控制点的绘制和更新。
Page({  
  data: {  
    centerX: 150,  // 圆心的X坐标  
    centerY: 150,  // 圆心的Y坐标  
    radius: 100,   // 圆的半径  
    angle: 0       // 当前角度  
  },  

  onReady: function () {  
    this.drawCircle(); // 页面加载完成后绘制圆和点  
  },  

  drawCircle: function () {  
    const ctx = wx.createCanvasContext('circleCanvas', this);  
    const { centerX, centerY, radius } = this.data;  

    // 清空画布  
    ctx.clearRect(0, 0, 300, 300);  

    // 绘制圆  
    ctx.beginPath();  
    ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI);  
    ctx.setStrokeStyle('#ccc'); // 设置圆圈颜色  
    ctx.setLineWidth(2); // 设置线宽  
    ctx.stroke(); // 绘制圆圈  

    // 绘制点  
    this.drawPoint(ctx); // 绘制圆周上的点  

    ctx.draw(); // 绘制到画布  
  },  

  drawPoint: function (ctx) {  
    const { centerX, centerY, radius, angle } = this.data;  

    // 计算点在圆周上的位置  
    const pointX = centerX + radius * Math.cos(angle); // 点的X坐标  
    const pointY = centerY + radius * Math.sin(angle); // 点的Y坐标  

    // 绘制点  
    ctx.beginPath();  
    ctx.arc(pointX, pointY, 10, 0, 2 * Math.PI); // 点的半径为10  
    ctx.setFillStyle('#000'); // 设置点的颜色  
    ctx.fill(); // 填充点  
  },  

  onTouchMove: function (e) {  
    const touch = e.touches[0]; // 获取手指触控的位置  
    const { centerX, centerY } = this.data;  

    // 计算当前触摸点与圆心的距离  
    const dx = touch.x - centerX; // 使用 touch.x 而不是 clientX  
    const dy = touch.y - centerY; // 使用 touch.y 而不是 clientY  
    const distance = Math.sqrt(dx * dx + dy * dy);  

    // 计算当前角度  
    let angle = Math.atan2(dy, dx);  
    if (distance > this.data.radius) {   
      // 如果超过半径,则按半径限制  
      angle = Math.atan2(dy / distance * this.data.radius, dx / distance * this.data.radius);  
    }  

    this.setData({ angle }); // 更新当前角度  

    this.drawCircle(); // 重新绘制  
  },  

  onTouchEnd: function () {  
    // 可以根据需要在触摸结束时添加逻辑  
  }  
});  
  1. CSS 文件
    在 CSS 文件中添加一些基本的样式以美化界面。
.container {  
  display: flex;  
  align-items: center;  
  justify-content: center;  
  height: 100vh; /* 充满屏幕高度 */  
}  

代码说明
数据初始化: 我们定义了圆心的位置(centerX 和 centerY)、圆的半径(radius)以及当前的角度(angle)。

绘制圆和点:

在 drawCircle() 方法中,首先清空画布,然后描绘一个灰色的圆和当前点的黑色圆。
drawPoint(ctx) 函数用于计算点的位置并将其绘制到圆周上。
手指移动控制:

onTouchMove() 方法获取当前触摸点的坐标,并计算这个点到圆心的距离和角度。
使用 Math.atan2(dy, dx) 计算当前点的角度,并根据实际情况限制该点在指定半径内移动。
样式设置: 简单的 CSS 使得界面居中。

2、渐变色的圆

问:点的颜色是从上往下渲染而成
答:如果你希望点的颜色在整个圆形上实现从上往下的渐变效果,可以使用 createRadialGradient 创建一个圈的径向渐变效果,但为更符合“从上往下渲染”的效果,我们可以考虑使用 createLinearGradient 方法来创建一个线性渐变,并将其应用于绘制的圆形。

实现从上往下的线性渐变
以下是一个示例代码,展示如何实现这个效果:

drawPoint: function (ctx) {  
  const { centerX, centerY, radius, angle } = this.data;  

  // 计算点在圆周上的位置  
  const pointX = centerX + radius * Math.cos(angle); // 点的X坐标  
  const pointY = centerY + radius * Math.sin(angle); // 点的Y坐标  

  // 创建从上到下的线性渐变  
  const gradient = ctx.createLinearGradient(pointX, pointY - 10, pointX, pointY + 10); // 从点上方到下方的渐变  
  gradient.addColorStop(0, 'red');  // 上部为红色  
  gradient.addColorStop(1, 'blue'); // 下部为蓝色  

  // 绘制点  
  ctx.beginPath();  
  ctx.arc(pointX, pointY, 10, 0, 2 * Math.PI); // 点的半径为10  
  ctx.setFillStyle(gradient); // 使用创建的渐变色  
  ctx.fill(); // 填充点  
}  

解释代码
创建线性渐变:

ctx.createLinearGradient(pointX, pointY - 10, pointX, pointY + 10):创建一个从 pointY - 10(点的上方)到 pointY + 10(点的下方)的线性渐变。
addColorStop(0,

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值