小程式如何把文字玩出花樣

林大魚發表於2019-02-28

本文會從產品角度來講訴如何打造一款支援表情的彈幕小程式

產品需求:演唱會應援、行走的廣告牌以及地鐵讓座提醒等等(提供一種思路)
競品分析:小程式裡的彈幕類應用大部分只支援文字,而圖片和音訊這一塊功能是缺失的
功能確定:支援滾動文字和滾動圖片


實現效果

小程式如何把文字玩出花樣

思路:

input 獲取輸入文字,richtext顯示包含圖片的彈幕,設定richtext中文字的方向並滾動起來,滑動改變文字大小,文字顏色等操作

實現程式碼:

1.使用input輸入文字、支援emoji表情

先定義的一個"danmu"物件來儲存input輸入的彈幕文字以及彈幕樣式、

danmu: {
      fontColor: "#ffffff",
      text: "預設彈幕~",
      fontSize: "40px",
      glow: "#ffff00",
      speed: '10s',
},
複製程式碼

接著定義"nodes"物件顯示資料 text:彈幕文字;fontSize:文字大小;fontColor:文字顏色;glow:文字發光;speed:滾動速度。

使用input元件輸入文字:

<input type='text'
        bindconfirm='changeDanmuText'
        value='{{danmu.text}}' 
        placeholder='輸入彈幕~' 
        placeholder-style='color:#fff' 
        cursor-spacing='28'>
</input>
複製程式碼

cursor-spacing設定input中游標與鍵盤的距離


2.richText顯示包含圖片的彈幕

定義nodes物件來更新彈幕

nodes: [{
    name: 'div',
    attrs: {
    class: 'danmu-text'},
    children: [
        {
        type: 'text',
        text: '彈幕文字?~'},
        {
        name: 'img',
        attrs: {
            src: '網路圖片',
            width: '數值',
            style: '樣式'}
        }
    ]
}],
複製程式碼

nodes的children是一個節點集合,type是型別,text型別只有text物件,預設是節點型別所以不需要type,節點型別中name是指節點名,attrs是指節點的屬性。
具體方法屬性可以看官方 richText 文件

danmu物件與rich-text元件繫結資料關係,

 <rich-text nodes='{{nodes}}'
 class='rich-text'
 style='font-size:{{danmu.fontSize}};color:{{danmu.fontColor}};text-shadow: 0 0 20rpx {{danmu.glow}};'>
 </rich-text>
複製程式碼

並更新彈幕資料在rich-text元件上

changeDanmuText: function () {
    if (that.data.danmu.text != '') {
      that.data.nodes[0].children = []
      that.data.nodes[0].children.push({
        type: 'text',
        text: that.data.danmu.text
      })
      that.setData({
        danmu: that.data.danmu,
        nodes: that.data.nodes
      })
    }
},
複製程式碼

判斷彈幕資料,如果是有有效資料則push到children中,並立即更新資料


經過以上兩步,已經可以把input中的資料展示在rich-text中了。
滾動彈幕樣式,利用animation 的transform: translate3d,裝置會開啟GPU加速

rich-text {
  width: auto;
  height: auto;
  display: inline-block;
}
.danmuContent {
  animation: danmuAnimation 10s;
  animation-iteration-count: infinite;
  animation-timing-function: linear;
  display: inline-block;
  text-shadow: 0 0 20rpx #f00;
  transform: rotate(90deg);
  transform-origin: 0% 100%;
  writing-mode: vertical-lr;//很重要,把文字豎著排列
  text-orientation: sideways-right;//改變文字方向
}
@keyframes danmuAnimation {
  from {
    transform: translate3d(0, 100%, 0);
  }

  to {
    transform: translate3d(0, -100%, 0);
  }
}

複製程式碼
<view style='display:flex;align-items:center;justify-content:center;'>
 <view class='danmuContent' style='min-height:{{view.height}};animation-duration:{{danmu.speed}}'>
     <rich-text nodes='{{nodes}}' class='rich-text' style='font-size:{{danmu.fontSize}};color:{{danmu.fontColor}};text-shadow: 0 0 20rpx {{danmu.glow}};'>
    </rich-text>
    </view>
</view>
複製程式碼

下面就要插入表情和更新文字樣式

3.插入動態表情

小程式如何把文字玩出花樣
定義動態表情url陣列

gifUrl = [url0,url1,url2,....]
複製程式碼

顯示在view中

<view wx:for="{{gifUrl}}" wx:for-item="url" class='gif'>
    <image src='https://user-gold-cdn.xitu.io/2018/1/13/160ef9d4a180eee1' data-gifid='https://user-gold-cdn.xitu.io/2018/1/13/160ef9d4a180eee1' bindtap='addImg' class='gif'>
    </image>
</view>
複製程式碼

gifid傳到nodes中的img src裡,之後更新資料

addImg: function (e) {
    that.data.nodes[0].children.push({
      name: 'img',
      attrs: {
        src: e.currentTarget.dataset.gifid,
        width: '40px',
        style: 'transform:rotate(90deg)'
      }
    })
    that.setData({
      nodes: that.data.nodes,
      danmu: that.data.danmu
    })
},
複製程式碼

4.設定文字大小、顏色、發光以及滾動速度

這一步其實不難,主要就是互動上要簡潔、方便。

小程式如何把文字玩出花樣
使用slider滑動改變文字大小

<slider bindchange='changeFontSize'
bindchanging='changeFontSize' 
show-value='true' min='10' max='200'>
</slider>
複製程式碼

文字顏色和發光顏色,使用slider模擬了一個滑動取色(這個後續文章詳細分析)

小程式如何把文字玩出花樣

 changeFontColor: function (e) {
    let H = e.detail.value
    let color = this.HSB2RGB([H, 1, 1])
    this.data.danmu.fontColor = 'rgb(' + color.R + ',' + color.G + ',' + color.B + ')'
    this.setData({
      danmu: this.data.danmu
    })
  },
  changeFontGlow: function (e) {
    let H = e.detail.value
    let color = this.HSB2RGB([H, 1, 1])
    this.data.danmu.glow = 'rgb(' + color.R + ',' + color.G + ',' + color.B + ')'
    this.setData({
      danmu: this.data.danmu
    })
  },
複製程式碼

彈幕滾動速度同樣使用slider,取值1-3,避免太快。

小程式如何把文字玩出花樣

 <slider bindchange='changeFontSpeed' 
 bindchanging='changeFontSpeed' show-value='true' min='1' max='3'>
 </slider>
複製程式碼

為了保持滾動速度的均勻,要根據彈幕view的高度實時改變(animation-duration),達到勻速的目的。

  changeFontSpeed: function (e) {
    let speedValue = e.detail.value / 4 * 100
    wx.createSelectorQuery().selectAll('.danmuContent').boundingClientRect(function (rects) {
      rects.forEach(function (rect) {
        that.data.danmu.speed = rect.height / speedValue + 's'
        that.setData({
          danmu: that.data.danmu
        })

      })
    }).exec()
  },
複製程式碼

到這裡,基本功能已經實現,還有其他操作,比如保持螢幕常亮、螢幕上背景全黑並隱藏其它內容。

    // 保持螢幕常亮
wx.setKeepScreenOn({
    keepScreenOn: true
})
複製程式碼

設定導航欄顏色

wx.setNavigationBarColor({
    frontColor: '#000000',
    backgroundColor: '#000000',
})
複製程式碼

總結

滾動彈幕動畫要考慮手機的效能,沒有使用canvas,最直接就是使用css的transform動畫,效率最高。 小程式的富文字編輯支援比較弱,嘗試了許多方法,比如在文字中插入圖片,想到了類似QQ表情"[微笑/]"的方法,使用正則進行分析,再顯示在rich-text上,但是在這個專案上不合適。只好換一種思路,在文字開頭或結尾插入圖片。


以上程式碼沒做相關優化,寫的比較糙,把我的思路寫出來給大家看看,共同成長! 一個射雞獅的不歸之路~

相關文章