微信小程序-測試遊戲生成六邊多邊形

背景

基於wepy小程序框架

最新又接到新的活動需求啦,是一個測試類的遊戲。 大概的看了整個需求,這個活動的難點在於結果頁面的六邊形指標怎麼實現。css

效果demo相似

分析

  • 背景
    首先,這是用戶對應六個屬性值的等邊六邊形,等邊六邊形這是一個很關鍵的點;爲何是等邊六邊形呢,由於用戶留個屬性的峯值的同樣的,起點也是一致的。
  • 中心點
    這個六邊形的中心就是整個圓心的中心位置
  • 六個屬性座標位置
    咱們須要各自的屬性值算出對應的座標位置

繪畫等邊六邊形

咱們假設要繪畫邊長爲240長度的等邊六邊形; 咱們須要簡單的計算下;html

咱們把底部切成三塊,一個三角形+矩形+三角形git

用css方式把它畫出來。github

相信三角形的畫法你們應該都很清楚了,這裏就不重複講基礎的東西canvas

dom
<view class="six-bg">
  <view class="box1"></view>
  <view class="box2"></view>
  <view class="box3"></view>
</view>
複製代碼
css
@sixWidthRPX: 208rpx; // 240*cos30°
@sixHeightRPX: 120rpx; // 240*sin30°
@sixWidthBigRPX: 416rpx;
@sixHeightBigRPX: 240rpx;
.six-bg{
    padding: 167rpx;
    .box1{
      width:0;
      border-left: @sixWidthRPX solid transparent;
      border-right: @sixWidthRPX solid transparent;
      border-bottom: @sixHeightRPX solid #6c6;
    }
    .box2{
      width: @sixWidthBigRPX;
      height: @sixHeightBigRPX;
      background-color: #6c6;
    }
    .box3{
      width:0;
      border-top: @sixHeightRPX solid #6c6;
      border-left: @sixWidthRPX solid transparent;
      border-right: @sixWidthRPX solid transparent;
    }
 }
複製代碼

效果圖小程序

根據屬性值畫點連線

假設咱們把那個屬性值的峯值都定爲10。咱們知道等邊六邊形的6邊長度都爲240。那咱們的每一個單位就是24。微信小程序

咱們先假設6個屬性值都滿了,那麼api

data = {
  sixData: {
    one: 10,
    two: 10,
    three: 10,
    four: 10,
    five: 10,
    six: 10
  }
}
複製代碼

咱們找下等邊六邊形的圓形點。bash

X軸位置 167+208 = 375
Y軸位置 167+240 = 407

6個座標位置

第一個點的座標和第四個點的座標是最容易計算的,咱們先把這兩個點的座標算出來;微信

const unit = 24  // 單位
const centerDotX = 375  // 中心點
const centerDotY = 407  // 中心點
// 第一個點 位置
let dotOne = {
    x: centerDotX,
    y: centerDotY - this.sixData.one * unit
}
// 第四個點 位置
let dotFour = {
    x: centerDotX,
    y: centerDotY + this.sixData.four * unit
}
複製代碼

第2、3、5、六點的座標咱們就須要用到三角函數了;

咱們觀察下這個圖,發現 二、三、五、6點都有30度的夾角;

第二點座標
const lineLongTwo = unit * this.sixData.two
x = centerDotX + lineLongTwo*cos30
y = centerDotY - lineLongTwo*sin30
複製代碼

咱們的js代碼並無cos、sin的方法;

這時候咱們須要補一下Math函數的知識;

Math.sin(x) x 的正玄值。返回值在 -1.0 到 1.0 之間;

Math.cos(x) x 的餘弦值。返回的是 -1.0 到 1.0 之間的數;

這兩個函數中的X 都是指的「弧度」而非「角度」,

弧度的計算公式爲:

(度數 * Math.PI) / 180;

如今咱們能夠算出6個點的位置了

const unit = 24  // 單位
const centerDotX = 375  // 中心點
const centerDotY = 407  // 中心點
// 第一個點 位置
let dotOne = {
    x: centerDotX,
    y: centerDotY - this.sixData.one * unit
}
// 第二個點 位置
const lineLongTwo = unit * this.sixData.two
let dotTwo = {
    x: centerDotX + lineLongTwo * Math.cos((30 * Math.PI) / 180),
    y: centerDotY - lineLongTwo * Math.sin((30 * Math.PI) / 180)
}
// 第三個點 位置
const lineLongThree = unit * this.sixData.three
let dotThree = {
    x: centerDotX + lineLongThree * Math.cos((30 * Math.PI) / 180),
    y: centerDotY + lineLongThree * Math.sin((30 * Math.PI) / 180)
}
// 第四個點 位置
let dotFour = {
    x: centerDotX,
    y: centerDotY + this.sixData.four * unit
}
// 第五個點 位置
const lineLongFive = unit * this.sixData.five
let dotFive = {
    x: centerDotX - lineLongFive * Math.cos((30 * Math.PI) / 180),
    y: centerDotY + lineLongFive * Math.sin((30 * Math.PI) / 180)
}
// 第六個點 位置
const lineLongSix = unit * this.sixData.six
let dotSix = {
    x: centerDotX - lineLongSix * Math.cos((30 * Math.PI) / 180),
    y: centerDotY - lineLongSix * Math.sin((30 * Math.PI) / 180)
}
複製代碼

如今咱們來把點連成;咱們能夠採用 微信小程序canvas api 來繪製咱們的六條線

先創建canvas dom

<view class="canvas-module">
  <canvas canvas-id="myCanvas" class="canvas-class"/>
</view>
複製代碼

css佈局

.canvas-module{
    position: absolute;
    width: 750rpx;
    height: 750rpx;
    z-index: 2;
    top: 0;
    left: 0;
    .canvas-class{
      width: 750rpx;
      height: 750rpx;
    }
}
複製代碼

canvas api文檔 developers.weixin.qq.com/miniprogram…

繪製

const ctx = wepy.createCanvasContext('myCanvas')
ctx.beginPath()
ctx.moveTo(dotOne.x / 2, dotOne.y / 2)
ctx.lineTo(dotTwo.x / 2, dotTwo.y / 2)
ctx.lineTo(dotThree.x / 2, dotThree.y / 2)
ctx.lineTo(dotFour.x / 2, dotFour.y / 2)
ctx.lineTo(dotFive.x / 2, dotFive.y / 2)
ctx.lineTo(dotSix.x / 2, dotSix.y / 2)
ctx.lineTo(dotOne.x / 2, dotOne.y / 2)
ctx.stroke()
ctx.draw()
複製代碼
位置座標爲何要除以2呢?

由於canvas是以px爲單位的

效果圖

咱們再給利用canvas屬性,給它加上一點補同樣的東西

咱們給線加上顏色和寬度
ctx.setStrokeStyle('yellow')  // 線條顏色
ctx.setLineWidth(2)  // 線條寬度
複製代碼
填充漸變顏色
const grd = ctx.createLinearGradient(0, 0, 200, 0)
grd.addColorStop(0, 'red')
grd.addColorStop(1, 'white')
ctx.setFillStyle(grd)
ctx.fill()
複製代碼
加上透明度
ctx.setGlobalAlpha(0.7)
複製代碼

效果圖

最後咱們再加上個動畫,修改屬性值,完成整個效果;

dom
<view class="canvas-module" animation="{{animationData}}">
  <canvas canvas-id="myCanvas" class="canvas-class"/>
</view>
<button @tap="goStart">開始canvas</button>
複製代碼
css
.canvas-module{
    position: absolute;
    width: 750rpx;
    height: 750rpx;
    z-index: 2;
    top: 0;
    left: 0;
    transform: scale(0);  //新增樣式
    .canvas-class{
      width: 750rpx;
      height: 750rpx;
    }
}
複製代碼
js
data = {
  animationData: {},
  sixData: {
    one: 10,
    two: 7,
    three: 1,
    four: 6,
    five: 2,
    six: 8
  }
};
複製代碼
methods = {
  goStart () {
    var animation = wepy.createAnimation({
      duration: 1000,
      timingFunction: 'ease'
    })
    animation.scale(1, 1).step()
    this.animationData = animation.export()
  }
}
複製代碼

效果以下

這樣整個動畫就算完成了, demo請前往github github.com/fishmankkk/…

其實背景圖也是能夠用canvas畫的,有興趣的小夥伴能夠動手本身畫一下

相關文章
相關標籤/搜索