分类 编程语言 下的文章

在微信小程序里面,页面基本上都是一个栈的数据结构,当我们使用wx.navigateto,打开一个新的页面的时候,这时候就会在栈顶显示这个页面,当我们使用wx.navigateBack() 返回上个页面的时候,就是把当前的页面pop出去。小编之前用过RN,当时采用的是回调函数来实现的,其实在小程序里面不需要这么麻烦,我们可以直接拿到页面栈,然后给上个页面直接赋值就行。
操作方法:

  1. 在当前页面执行:

    let pages = getCurrentPages(); // 拿到页面栈
    let prevPage = pages[pages.length - 2]; // 拿到上个页面,-1是当前页面
    prevPage.setData({ // 赋值
     addressid: e.currentTarget.dataset.addressid
    })
    wx.navigateBack({ // 返回
     delta: 1
    })
  2. 上一个页面:

    // 获取值并进行赋值(一般小编是写在onShow里面)
    this.setData({
    addressid: currPage.__data__.addressid || null
    })

    微信小程序wx.navigateBack() 携带参数返回.png

小编今天给大家分享一个装B专用的一个特效,看上去就行黑客帝国里面的那种,是不是很装B呢,就是通过JS来实现的,大家还可以改成自己喜欢的问题哦。
我们先来看一个效果图:
hkdg.png
代码分享

<canvas id="c"></canvas>

<script type="text/javascript">
var c = document.getElementById("c");
var ctx = c.getContext("2d");

//making the canvas full screen
c.height = window.innerHeight;
c.width = window.innerWidth;

//chinese characters - taken from the unicode charset
var chinese = "小宁博客";
//converting the string into an array of single characters
chinese = chinese.split("");

var font_size = 10;
var columns = c.width / font_size; //number of columns for the rain
//an array of drops - one per column
var drops = [];
//x below is the x coordinate
//1 = y co-ordinate of the drop(same for every drop initially)
for (var x = 0; x < columns; x++)
    drops[x] = 1;

//drawing the characters
function draw() {
    //Black BG for the canvas
    //translucent BG to show trail
    ctx.fillStyle = "rgba(0, 0, 0, 0.05)";
    ctx.fillRect(0, 0, c.width, c.height);

    ctx.fillStyle = "#0F0"; //green text
    ctx.font = font_size + "px arial";
    //looping over drops
    for (var i = 0; i < drops.length; i++) {
        //a random chinese character to print
        var text = chinese[Math.floor(Math.random() * chinese.length)];
        //x = i*font_size, y = value of drops[i]*font_size
        ctx.fillText(text, i * font_size, drops[i] * font_size);

        //sending the drop back to the top randomly after it has crossed the screen
        //adding a randomness to the reset to make the drops scattered on the Y axis
        if (drops[i] * font_size > c.height && Math.random() > 0.975)
            drops[i] = 0;

        //incrementing Y coordinate
        drops[i]++;
    }
}

setInterval(draw, 50);
</script>

微信小程序的抽红包组件,小编一共是做了两种,第一种呢用了很长时间了,可能是时间长了,觉得不是那么霸气了,就重新又制作了一个,第一个当时使用了大量的图片,这也导致了加载的时候很慢,这里面的主要样式还是参考的别人的代码,总而言之效果还是不错的,不过现在呢,小编又自己写了个抽红包的组件,这回看上去比较好看了,首先我们先看下2.0代码吧。因为是放在具体项目里面的,有些细节性的东西大家可以改改:
首先是wxml,大部分的样式也写在了这里面:

<view style="position: fixed; top: 0; left: 0; display: flex; flex-direction: row; justify-content: center; align-items: center; width: 100%; height: 100vh; z-index: 100000000000000000000; background: rgba(0, 0, 0, 0.4);">
    <view class="{{open ? 'red-packet-open' : ''}}" style="background: #ff3d32; border-radius: 30rpx; border-bottom-right-radius: 100% 120px; border-bottom-left-radius: 100% 120px; box-shadow: 0px 3px 5px 1px #e92c27; width: 590rpx; height: 700rpx; position: absolute; top: 80rpx; z-index: 101;">
        <view wx:if="{{name}}" style="color: #F5B37B; text-align: center; font-size: 40rpx; padding-top:100rpx;">{{name}}的红包</view>
        <view wx:if="{{text}}" style="color: #F5B37B; text-align: center; font-size: 30rpx; padding-top:60rpx;">{{text}}</view>
        <view style="position: absolute; bottom: -80rpx; left: 220rpx; background: #E8bF7B; width: 150rpx; height: 150rpx; line-height: 150rpx; text-align: center; border-radius: 75rpx; font-size: 60rpx;" bindtap="handleOpen">抽</view>
    </view>
    <view class="{{open ? 'red-packet-open' : ''}}" style="background: #ff3328; border-radius: 30rpx; border-top-right-radius: -120px; border-top-left-radius: -120px; width: 590rpx; height: 464rpx; position: absolute; top: 500rpx; z-index: 100;"></view>
    <view style="width: 590rpx; height: 883rpx; position: absolute; top: 80rpx; z-index: 90; background: #FFFFFF; border-radius: 30rpx;">
        <view style="height: 260rpx; border-radius: 30rpx; border-bottom-right-radius: 100% 120px; border-bottom-left-radius: 100% 120px; background: #ff3d32; display: flex; flex-direction: column; justify-content: center; align-items: center;text-align: center;">
            <image mode="aspectFill" src="{{user?user.avatar : ''}}" style="width: 130rpx; height: 130rpx; min-width: 130rpx; min-height: 130rpx; border-radius: 65rpx; position: absolute; top: 180rpx;" />
            <view style="position: absolute; top: 0; right: 20rpx; color: #FFFFFF; font-size: 56rpx;" bind:tap="close">X</view>
        </view>
        <view style="display: flex; flex-direction: column; justify-content: center; align-items: center;text-align: center; font-size: 26rpx; margin: 60rpx;">
            <text style="color: #f33035; font-size: 40rpx;">{{title}}</text>
            <text style="padding: 10rpx; color: #f33035; font-size: 50rpx;">{{msg}}</text>
            <view style="text-align: center; font-size: 30rpx; margin: 20rpx;">{{tips}}</view>
            <view wx:if="{{balance}}" bind:tap="toBalance" style="text-align: center; font-size: 30rpx; margin: 20rpx; color: #f33035; padding-top: 60rpx;"><text wx:if="{{balance_name}}">{{balance_name}}</text>余额:{{balance}}>>
            </view>
        </view>
    </view>
</view>

在wxss里面实现了一个动画:

.red-packet-open {
    animation: open-up 0.2s ease-in-out 0.2s 1 normal;
    animation-fill-mode: forwards;
    display: none;
}

在js里面就是相关的逻辑了

const audio = wx.createInnerAudioContext()
audio.src = 'https://audiosrc.shangpo.net/sources/coin.mp3'
let g = getApp().globalData;

Component({
    properties: {
        title: {
            type: String,
            value: null
        },
        msg: {
            type: String,
            value: null
        },
        tips: {
            type: String,
            value: null
        },
        bind: {
            type: Boolean,
            value: true,
        },
        open: {
            type: Boolean,
            value: false
        },
        amount_ui: {
            type: String,
            value: null
        },
        name: {
            type: String,
            value: null
        },
        text: {
            type: String,
            value: null
        },
        user: {
            type: Object,
            value: g.user
        }, 
        balance: {
            type: String,
            value: null
        },
        balance_name: {
            type: String,
            value: null
        }
    },
    data: {

    },
    methods: {
        handleOpen() {
            var that = this
            if (that.data.bind) {
                that.setData({
                    title: that.data.title,
                    msg: that.data.msg,
                    bind: false,
                    // 以下两项为测试页面使用
                    // tips: that.data.tips,
                    // open: true,
                })
                audio.play()
                this.triggerEvent('choujiang', {})
            }
        },
        close() {
            this.triggerEvent('close_redpacket', {})
        },
        toBalance(){
            this.triggerEvent('toBalance', {})
        }
    }
})

1.0版本的基本上就是样式上的不一样,小编在这里就不列出来了,有需要的可以单独联系小编。

如果是在一个平面里面来计算两个点之间的距离,那么我们可以直接使用勾股定理,那么问题就来了,地球是一个球啊,面是球面啊,那就这么计算

from math import radians, cos, sin, asin, sqrt

#公式计算两点间距离(m)

def geodistance(lng1,lat1,lng2,lat2):
  lng1, lat1, lng2, lat2 = map(radians, [float(lng1), float(lat1), float(lng2), float(lat2)]) # 经纬度转换成弧度
  dlon=lng2-lng1
  dlat=lat2-lat1
  a=sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2 
  distance=2*asin(sqrt(a))*6371*1000 # 地球平均半径,6371km
  distance=round(distance/1000,3)
  return distance

小编在做一个微信小程序的多选框的时候用到了bindchange这个函数来实现多选的实现,但是小编需要解决冒泡问题,这时候发现catchchange这个方法居然解决不了问题,无法阻止冒泡,经过一系列的尝试最终发现了解决的办法:在checkbox添加一个view,给view添加一个catchtap操作,指向一个空函数即可,冒泡到view的时候,在这几就结局了。代码实现如下:

 <view catchtap="catchtap">
      <checkbox value="{{_id}}" checked="{{item.checked}}" />
 </view>

catchtap.jpg

微信小程序的轮播图也是十分的方便,我们可以直接调用,不用自己再写多余的逻辑了,这样也极大的方便了我们的开发,在使用过程中,小编发现原生的小程序无法满足需求了,小编想在图片下方添加行文字,但是原生的轮播图无法满足小编的基本需求了。所以小编自己进行了部分修改,一起来看下。
先来看下效果图:
lbt.png
实现代码:

 <swiper indicator-dots="{{true}}" style="height: 200px;">
            <block wx:for="{{covers || []}}">
                <swiper-item>
                    <image src="{{item}}" class="slide-image" style="width: 100%; height: 100%;" mode="aspectFill" bindtap="onImageClick" data-images="{{covers || []}}" data-index="{{index}}" />
                    <!-- 关键代码 -->
                    <view style="font-size: 18px;width:{{width}}px;padding:10rpx; color: black; font-weight: 800; padding: 2px 0;background:rgba(0,0,0,0.4);position: absolute;bottom:0;left:0%;transform:translateX(0%);text-align:left;">
                        <text style="color:#FFFFFF;padding-left:30rpx;">{{product.name}}</text>
                    </view>
                </swiper-item>
            </block>
</swiper>

JavaScript打乱一个数组的顺序的两种方式

  • 方法一:利用sort函数

      arr.sort(function() {
          return .5 - Math.random();
      });

    这种方式可以打乱一个数组的顺序,但是并不是真正的乱序,所以建议不要用在严谨的打乱顺序上。

  • 方法二:自己封装一个函数

    function rand(arr) {
          var len = arr.length
          //倒叙遍历该数组
          for(var i = arr.length - 1; i >= 0; i--) {
              // 产生一个在数字长度内的随机数
              var randomIndex = Math.floor(Math.random() * (i + 1));
              // 作为数组下标去取数组该位置的值
              var itemIndex = arr[randomIndex];
              // 随机的位置与该位置互换
              arr[randomIndex] = arr[i];
              arr[i] = itemIndex;
          }
          return arr;
      }

微信小程序本身是没有开屏的,所以我们通过我们自己的逻辑制作一个自己的开屏,需求就是,当用户打开小程序的时候我们会先显示一个开屏,然后开屏自动关闭。如果进入的不是首页那么我们的开屏就不展示。并且还要使用各种手机的屏幕。
我们的开屏其实是显示的一张大图片,我们让宽度等于屏幕的宽度,高度通过图片的宽高比计算出来,在图片外面加一个view,这个view的背景色和图片的背景色一样这样就可以适应不同的屏幕了。
首先我们先来写下样式

 <!-- 开屏 -->
    <view wx:if='{{kaiping}}' style=' position: fixed;top: 0;left: 0;display: flex;flex-direction: row;justify-content: center;align-items: center;width: 100%;height: 100vh;z-index: 99999999;background:#a00b0a;'>
        <view style='position: fixed;'>
            <image src="../../kaiping.png" style='width:{{width}}px;height:{{width*1.51}}px' />
        </view>
    </view>

然后在我们的js里面写下逻辑:
在data里面设置:kaiping: false
在onload里面把kaiping: true

that.setData({
     kaiping: true
})

在onshow里面写一个定时器关闭开屏

if (that.data.kaiping) {
        setTimeout(function() {
             that.setData({
             kaiping: false
        })
     }, 4000);
}

我们首先下载echarts微信版,下载地址为:https://github.com/ecomfe/echarts-for-weixin,然后我们把下载好的文件放在我们的小程序中,小编是建立了一个libs用来存储这些引用的库。

  • json文件中的配置:

    "usingComponents": {
          "ec-canvas": "/libs/ec-canvas/ec-canvas"
    }
  • js中引用

    let echarts = require('../../libs/ec-canvas/echarts.js');
  • wxml中使用

    <view style="width: 720rpx; height: 720rpx;">
        <ec-canvas  id="ec-accessdata" canvas-id="ec-accessdata" ec="{{echarts.addatatrend.option}}"></ec-canvas>
    </view>
  • 使用
    我们在data中定义echarts的初始化数据:

    echarts: {
              userdatafenbu: {
                  option: {
                      lazyLoad: true,
                  },
                  form: {
                      year: new Date().getFullYear()
                  }
              },
              addatatrend: {
                  option: {
                      lazyLoad: true
                  },
              }
    
          }
    option : {
              title: {
                  text: 'ECharts 入门示例'
              },
              tooltip: {},
              legend: {
                  data:['销量']
              },
              xAxis: {
                  data: ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"]
              },
              yAxis: {},
              series: [{
                  name: '销量',
                  type: 'bar',
                  data: [5, 20, 36, 10, 10, 20]
              }]
          };
    

    在函数里使用

    let that = this;
    let ec = that.selectComponent('#ec-accessdata');
                  if (!ec) {
                      return;
                  }
                  ec.init(function(canvas, width, height) {
                      // 获取组件的 canvas、width、height 后的回调函数
                      // 在这里初始化图表
                      const chart = echarts.init(canvas, 'wonderland', {
                          width: width,
                          height: height
                      });
                      chart.setOption(that.data.option);
                      // 注意这里一定要返回 chart 实例,否则会影响事件处理等
                      return chart;
                  });