一直在摸魚中賺錢的大家好呀~
先向各位魚友們匯報一下情況,目前小程序已經有900+的魚友注冊使用過。雖然每天都有新的魚友注冊,但是魚友增長的還很緩慢。自從國慶前的文字轉語音的工具上線到現在已經將近有1個月沒有更新小程序了。但是今天終終終終終于又有個小工具上線了,希望這個小工具可以幫助到更多的魚友們(沒錯就是你們)
。
這次更新的工具是一個二維碼生成器,雖然很多小程序存在這個工具,但是本人也是想嘗試一下實現這個工具。老規矩,先來看下知名UI設計師設計的頁面。
同樣在工具tab頁中增加了二維碼生成器模塊。從UI圖中可以看出第一個表單頁面不是很難,就是一個文本框、兩個顏色選擇、一個圖片上傳。這個頁面我在開發中也是很快就完成了,沒有什么技術含量。
當我做到顏色選擇彈窗的時候是想從網上找一個現成的插件。但是找了半天沒有找到合適的,只能自己手動開發一個。既然要做顏色選擇器的功能就要先了解一下顏色的兩種格式 (我這邊的實現就這兩種格式)。
顏色的HEX格式
顏色的HEX
格式是#
+六位數字/字母
,其中六位數字/字母
是一種十六進制的表達方式。這六位分別兩個一組,從左到右分別表示紅
、綠
、藍
。00
表示最小,十進制是0
;FF
表示最大,十進制是255
。通俗點講,某個顏色的數值越大,包含這個顏色就越多。如:#000000
-黑色、#FFFFFF
-白色、#FF0000
-紅色、#00FF00
-綠色、#0000FF
-藍色。
顏色的RGB格式
顏色的RGB
格式是rgb(0-255,0-255,0-255)
, 其中0-255
就是HEX格式的十進制表達方式。這三個數值從左到右分別表示紅
、綠
、藍
。0
表示最小;255
表示最大。通俗點講,某個顏色的數值越大,包含這個顏色就越多。如:rgb(0,0,0)
-黑色、rgb(255,255,255)
-白色、rgb(255,0,0)
-紅色、rgb(0,255,0)
-綠色、rgb(0,0,255)
-藍色。
有了上面的概念,我的思路也就出來了。讓用戶分別選擇這三種顏色的數值,然后通過用戶選擇的三種顏色的數值轉成目標顏色,就可以完成顏色選擇的功能。思路出來了之后就告知了UI,然后按照我的思路將效果圖出了出來 (沒錯,就是先實現后出圖)。實現中主要使用了vant-ui
組件庫的popup
和slider
兩個組件 (聰明人都喜歡用現成的)。貼一下部分實現代碼:
<van-popup show="{{ show }}" title="展示彈出層" position="bottom"bind:close="cancelHandle"custom-style="background-color: #F3F3F9;border-radius: 40rpx 40rpx 0rpx 0rpx;"root-portal><view class="color-popup"><view class="popup-header flex flex_j_c--space-between flex_a_i--center"><view class="flex-item_f-1"></view><view class="title flex-item_f-1">{{ title }}</view><view class="flex-item_f-1 flex flex_j_c--flex-end"><van-icon name="cross" size="32rpx" bind:tap="cancelHandle" /></view></view><view class="color-picker" wx:for="{{ pickers }}" wx:key="index" wx:if="{{ index !== 3 }}"><view class="color-picker-label">{{ item.label }}</view><view class="flex flex_a_i--center"><view class="slider-wrap flex-item_f-1 {{ item.field }}"><van-slider value="{{ item.value }}" min="{{ 0 }}" max="{{ 255 }}" data-index="{{ index }}" bind:change="changeHandle" bind:drag="changeHandle" custom-class="slider" bar-height="60rpx" active-color="transparent" use-button-slot><view class="slider-button" slot="button"></view></van-slider></view><view class="slider-value">{{ item.value }}</view></view></view><view class="color-preview-box flex flex_a_i--center"><view class="preview-box-wrap"><view class="preview-box" style="background-color: {{ rgbaStyle }};"></view><view class="preview-label">顏色預覽</view></view><view class="presets-box-wrap flex-item_f-1 flex flex_j_c--space-between"><view class="presets-box flex flex_j_c--center flex_a_i--center {{ rgbaStyle === item.rgbaStyle ? 'active' : '' }}" wx:for="{{ presets }}" wx:key="index" style="background-color: {{ item.rgbaStyle }};" data-row="{{ item }}" bind:tap="chooseHandle"><view class="active-box"></view></view></view></view><view class="confirm-wrap flex"><view class="hex-box flex flex_a_i--center flex_j_c--space-between"><view>#</view><view>{{ hex }}</view></view><view class="confirm-button-box flex-item_f-1"><van-button type="primary" custom-class="confirm-button" bind:click="confirmHandle" round>確定</van-button></view></view></view>
</van-popup>
import { rgb2Hex } from '../../utils/util'const presets = [[0, 0, 0, 255], [102, 102, 102, 255],[0, 95, 244, 255], [100, 196, 102, 255],[247, 206, 70, 255], [235, 77, 61, 255],
]Component({options: {addGlobalClass: true},properties: {show: {type: Boolean,value: false},title: {type: String,value: ''},value: {type: Array,value: [0, 0, 0, 255],observer: function(val) {const { pickers } = this.dataif(val.length) {this.setData({pickers: pickers.map((item, index) => {return {...item, value: val[index]}}),})this.setColor(val)} else {this.setData({pickers: pickers.map((item, index) => {return {...item, value: index === 3 ? 255 : 0}}),})const rgba = [0, 0, 0, 255]this.setColor(rgba)}}}},data: {pickers: [{ field: 'r', label: '紅色', value: 0 },{ field: 'g', label: '綠色', value: 0 },{ field: 'b', label: '藍色', value: 0 },{ field: 'a', label: '透明度', value: 255 },],rgba: [],hex: '',rgbaStyle: '',presets: [...presets.map(rgba => {return {rgba,rgbaStyle: `rgba(${ rgba.join(',') })`}})]},methods: {changeHandle(e) {const { detail, currentTarget: { dataset: { index } } } = econst key = `pickers[${ index }].value`this.setData({ [key]: typeof detail === 'object' ? detail.value : detail})const rgba = this.data.pickers.map(item => item.value)this.setColor(rgba)},chooseHandle(e) {const { rgba } = e.currentTarget.dataset.rowthis.setData({pickers: this.data.pickers.map((item, index) => {return {...item, value: rgba[index]}}),})this.setColor(rgba)},// 設置顏色setColor(rgba) {const hex = rgb2Hex(...rgba)const rgbaStyle = `rgba(${ rgba.join(',') })`this.setData({ rgba, hex: hex.replace('#', ''), rgbaStyle })},confirmHandle(e) {this.triggerEvent('confirm', { rgba: this.data.rgba, rgbaStyle: this.data.rgbaStyle })},cancelHandle() {this.triggerEvent('cancel')},}
})
到此顏色選擇器的組件已經實現了,還剩下一個預覽下載的頁面。我這邊的實現并不是直接頁面跳轉,因為這邊預覽之后返回是希望還保留預覽之前的數據的。如果直接離開當前頁面并清除了數據,不符合用戶預期的。所以使用了一個假頁。微信小程序提供了一個 page-container 的頁面容器,效果類似于 popup
彈出層,頁面內存在該容器時,當用戶進行返回操作,關閉該容器不關閉頁面。
如果二維碼中含中文的靜態碼使用微信掃描后是無法正常展示內容的(后期安排上二維碼解析的功能)
感謝大家觀看我今日的水文,文筆實在是不行,歡迎魚友們給小程序提提意見,或者有什么有趣的想法也可以與樓主提一提。最后希望大家到我的小程序來多坐坐。
🦀🦀感謝看官看到這里,如果覺得文章不錯的話,可以給小生的幾個開源項目點個Star?!
- 基于 Vue3 + Element-plus 管理后臺基礎功能框架
- 預覽:http://admin.gumingchen.icu
- Github:https://github.com/gmingchen/agile-admin
- Gitee:https://gitee.com/shychen/agile-admin
- 基礎版后端:https://github.com/gmingchen/java-spring-boot-admin
- 文檔:http://admin.gumingchen.icu/doc/
- 基于 Vue3 + Element-plus + websocket 即時聊天系統
- 預覽:https://chatterbox.gumingchen.icu/
- Github:https://github.com/gmingchen/chatterbox
- Gitee:https://gitee.com/shychen/chatterbox
- 基于 node 開發的后端服務:https://github.com/gmingchen/node-server