微信小程序 小星星样式

送你一颗小星星~

效果

收藏类型

image

评星类型

image

环境

  • 微信小程序 typescript + scss

代码

下载地址
https://download.csdn.net/download/linyisonger/85169692

收藏类型
组件

index.ts

Component({
  properties: {
    checked: {
      type: Object,
      value: undefined
    }
  },
})

index.wxml

<view class="star {{checked == null ? '' : checked == true ? 'fill' : 'none' }}">
  <view class="iconfont icon-star"></view>
  <view class="iconfont icon-star-fill"></view>
  <view class="bling"></view>
  <view class="bling"></view>
  <view class="bling"></view>
</view>

index.scss

:host {
  display: inline-flex;
}

@font-face {
  font-family: "iconfont";
  /* Project id 3330476 */
  src: url('//at.alicdn.com/t/font_3330476_y264o31cfs8.woff2?t=1649984479172') format('woff2'),
    url('//at.alicdn.com/t/font_3330476_y264o31cfs8.woff?t=1649984479172') format('woff'),
    url('//at.alicdn.com/t/font_3330476_y264o31cfs8.ttf?t=1649984479172') format('truetype');
}

.iconfont {
  font-family: "iconfont" !important;
  font-size: 16px;
  font-style: normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.icon-star:before {
  content: "\e7df";
}

.icon-star-fill:before {
  content: "\e86a";
}

.star {
  position: relative;
  --width: 20rpx;
  --height: 4rpx;
  --font-size: 50rpx;
  --color: #bbbbbb;
  --fill-color: goldenrod;
  --left: 200rpx;
  --top: -100rpx;

  .icon-star {
    color: var(--color);
    font-size: var(--font-size);
  }

  .icon-star-fill {
    position: absolute;
    font-size: var(--font-size);
    top: 0;
    left: 0;
    color: var(--fill-color);
    opacity: 0;
  }

  .bling {
    position: absolute;
    width: var(--width);
    height: var(--height);
    border-radius: calc(var(--width) / 2);
    background-color: var(--fill-color);
    top: calc(50% - calc(var(--height) / 2));
    left: calc(50% - calc(var(--width) / 2));
    box-shadow: var(--font-size) calc(var(--height) / -.5) 0px var(--fill-color), calc(-1 * var(--font-size)) calc(var(--height) / -.5) 0px var(--fill-color);
    opacity: 0;
  }

  &.fill {
    .icon-star-fill {
      animation-name: star-fill-add;
      animation-duration: 1s;
      transition-timing-function: ease-in-out;
      opacity: 1;
    }

    .icon-star {
      animation-name: star-add;
      animation-delay: 1s;
      animation-duration: 1s;
      transition-timing-function: linear;
    }

    .bling {
      animation-delay: 1s;
      animation-duration: 1s;
      transition-timing-function: ease-in-out;
      opacity: 0;

      &:nth-of-type(3) {
        animation-name: star-bling-1;
      }

      &:nth-of-type(4) {
        animation-name: star-bling-2;
      }

      &:nth-of-type(5) {
        animation-name: star-bling-3;
      }
    }

  }

  &.none {
    .icon-star-fill {
      animation-name: star-fill-subtract;
      animation-duration: 1s;
      transition-timing-function: linear;
    }

    .icon-star {
      animation-name: star-subtract;
      animation-duration: 1s;
      transition-timing-function: linear;
    }
  }
}

@keyframes star-add {
  0% {
    color: var(--fill-color);
    transform: scale(1);
  }

  100% {
    transform: scale(1.5);
    opacity: 0;
  }
}

@keyframes star-fill-add {
  0% {
    left: var(--left);
    top: var(--top);
    font-size: calc(var(--font-size) / 2.5);
    transform: rotate(720deg);
  }

  100% {
    left: 0;
    top: 0;
    font-size: var(--font-size);
  }
}

@keyframes star-bling-1 {
  0% {
    color: var(--fill-color);
    opacity: 0;
    transform: scale(.8) rotate(-45deg);
  }

  50% {
    opacity: 1;
  }

  100% {
    transform: scale(1) rotate(-45deg);
    opacity: 0;
  }
}

@keyframes star-bling-2 {
  0% {
    color: var(--fill-color);
    transform: scale(.8) rotate(45deg);
  }

  50% {
    opacity: 1;
  }

  100% {
    transform: scale(1) rotate(45deg);
    opacity: 0;
  }
}

@keyframes star-bling-3 {
  0% {
    color: var(--fill-color);
    transform: scale(.8);
  }

  50% {
    opacity: 1;
  }

  100% {
    transform: scale(1);
    opacity: 0;
  }
}

@keyframes star-subtract {
  0% {
    opacity: 0;
  }

  100% {
    opacity: 1;
  }
}

@keyframes star-fill-subtract {
  0% {
    opacity: 1;
  }

  100% {
    opacity: 0;
  }
}
引用

index.json

{
  "usingComponents": {
    "star": "../../components/star/index"
  }
}

index.scss

加个边距

.collect {
  margin: 40px;
}

index.wxml

<star class="collect" checked="{{collect}}" bindtap="collectClick"></star>

index.ts

Page({
  data: {
    collect: undefined as undefined | boolean
  }, 
  collectClick(e: any) {
    this.setData({ collect: !this.data.collect });
  }
})
评星类型
组件

index.json

{
  "component": true,
  "usingComponents": {
    "star": "../star/index"
  }
}

index.scss

这个看你需求而定,我这里随便写的。

.stars {
  display: flex;
  padding: 10rpx 50rpx;
  position: relative;

  star {
    padding: 0 20rpx;
  }
}

index.wxml

<view class="stars">
  <block wx:for="{{checkeds}}" wx:key="unique">
    <star checked="{{item}}" bindtap="tap" data-i="{{index}}"></star>
  </block>
</view>

index.ts

// components/star-item/index.ts
Component({
  properties: {
    score: {
      type: Number,
      value: 0,
    },
    disabled: {
      type: Boolean,
      value: false
    },
    delay: {
      type: Number,
      value: 500
    }
  },
  data: {
    checkeds: [undefined, undefined, undefined] as (boolean | undefined)[],
  },
  methods: {
    tap(e: any) {
      let i = e.target.dataset.i;
      this.triggerEvent('score', i + 1);
    }
  },
  observers: {
    "score": function (n) {
      let o = this.data.checkeds.filter(a => a).length;
      /** 是正数? */
      let p = n > o;
      /** 方向 */
      let d = p ? 1 : -1;
      for (let i = p ? o : o - 1, t = 0; p ? i < n : i >= n; i += d, t++) {
        setTimeout(() => {
          this.setData({ [`checkeds[${i}]`]: p })
        }, t * this.data.delay);
      }
    }
  }
})
引用

index.json

{
  "usingComponents": {
    "stars": "../../components/stars/index"
  }
}

index.wxml

<stars score="{{score}}" bind:score="scoreChange"></stars>

index.ts

Page({
  data: { 
    score: 0, 
  }, 
  scoreChange(e: any) {
    this.setData({ score: e.detail })
  } 
})
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林一怂儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值