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

林大魚發表於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上,但是在這個專案上不合適。只好換一種思路,在文字開頭或結尾插入圖片。


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

相關文章