用空閑時間做了一個小程序-二維碼生成器

一直在摸魚中賺錢的大家好呀~

先向各位魚友們匯報一下情況,目前小程序已經有900+的魚友注冊使用過。雖然每天都有新的魚友注冊,但是魚友增長的還很緩慢。自從國慶前的文字轉語音的工具上線到現在已經將近有1個月沒有更新小程序了。但是今天終終終終終于又有個小工具上線了,希望這個小工具可以幫助到更多的魚友們(沒錯就是你們)

這次更新的工具是一個二維碼生成器,雖然很多小程序存在這個工具,但是本人也是想嘗試一下實現這個工具。老規矩,先來看下知名UI設計師設計的頁面。
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

同樣在工具tab頁中增加了二維碼生成器模塊。從UI圖中可以看出第一個表單頁面不是很難,就是一個文本框、兩個顏色選擇、一個圖片上傳。這個頁面我在開發中也是很快就完成了,沒有什么技術含量。

當我做到顏色選擇彈窗的時候是想從網上找一個現成的插件。但是找了半天沒有找到合適的,只能自己手動開發一個。既然要做顏色選擇器的功能就要先了解一下顏色的兩種格式 (我這邊的實現就這兩種格式)

顏色的HEX格式

顏色的HEX格式是#+六位數字/字母,其中六位數字/字母是一種十六進制的表達方式。這六位分別兩個一組,從左到右分別表示00表示最小,十進制是0FF表示最大,十進制是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組件庫的popupslider兩個組件 (聰明人都喜歡用現成的)。貼一下部分實現代碼:

<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

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/75004.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/75004.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/75004.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

31天Python入門——第14天:異常處理

你好&#xff0c;我是安然無虞。 文章目錄 異常處理1. Python異常2. 異常捕獲try-except語句捕獲所有的異常信息獲取異常對象finally塊 3. raise語句4. 自定義異常5. 函數調用里面產生的異常補充練習 異常處理 1. Python異常 Python異常指的是在程序執行過程中發生的錯誤或異…

PyQt6實例_批量下載pdf工具_使用pyinstaller與installForge打包成exe文件

目錄 前置&#xff1a; 步驟&#xff1a; step one 準備好已開發完畢的項目代碼 step two 安裝pyinstaller step three 執行pyinstaller pdfdownload.py&#xff0c;獲取初始.spec文件 step four 修改.spec文件&#xff0c;將data文件夾加入到打包程序中 step five 增加…

Axure項目實戰:智慧城市APP(完整交互匯總版)

親愛的小伙伴&#xff0c;在您瀏覽之前&#xff0c;煩請關注一下&#xff0c;在此深表感謝&#xff01; 課程主題&#xff1a;智慧城市APP 主要內容&#xff1a;主功能&#xff08;社保查詢、醫療信息、公交查詢等&#xff09;、活動、消息、我的頁面匯總 應用場景&#xff…

Appium Inspector使用教程

1.下載最新版本 https://github.com/appium/appium-inspector/releases 2.本地啟動一個Appium服務 若Android SDK已安裝Appium服務&#xff0c;則在任意terminal使用appium啟動服務即可 3.Appium Inspector客戶端配置連接到Appium服務 Configuring and Starting a Session…

Pycharm(七):幾個簡單案例

一.剪刀石頭布 需求&#xff1a;和電腦玩剪刀石頭布游戲 考察點&#xff1a;1.隨機數&#xff1b;2.判斷語句 import random # numrandom.randint(1,3) # print(num) # print(**30) #1.錄入玩家手勢 playerint(input(請輸入手勢&#xff1a;&#xff08;1.剪刀 2.石頭 3&…

Python Cookbook-4.13 獲取字典的一個子集

任務 你有一個巨大的字典&#xff0c;字典中的一些鍵屬于一個特定的集合&#xff0c;而你想創建一個包含這個鍵集合及其對應值的新字典。 解決方案 如果你不想改動原字典: def sub_dict(somedict,somekeys,default None):return dict([(k, somedict.get(k,default)) for k…

VMware Ubuntu 網絡配置全攻略:從斷網到暢通無阻

一、網絡連接模式選擇&#xff08;先搞懂原理&#xff09; VMware提供三種網絡模式&#xff0c;就像手機的不同網絡套餐&#xff1a; 模式適用場景特點類比NAT個人上網/新手首選虛擬機共享主機IP&#xff0c;能上網但隱身家用WiFi橋接服務器/需要被局域網訪問虛擬機會獲得獨立…

鏈表(C++)

這是本人第二次學習鏈表&#xff0c;第一次學習鏈表是在大一上的C語言課上&#xff0c;首次接觸&#xff0c;感到有些難&#xff1b;第二次是在大一下學習數據結構時&#xff08;就是這次&#xff09;&#xff0c;使用C再次理解鏈表。同時&#xff0c;這也是開啟數據結構學習寫…

【SPP】藍牙串口協議應用層深度解析:從連接建立到實戰開發

目錄 一、SPP應用層協議框架與角色模型 1.1 分層協議棧模型 1.2 設備角色模型&#xff08;DevA 與 DevB 交互&#xff09; 二、連接建立流程&#xff1a;從 SDP 到 RFCOMM 2.1 服務發現&#xff08;SDP&#xff09;流程&#xff08;SDP 記錄關鍵參數&#xff09; 2.2 連接…

Giteki 認證:無線產品進入日本市場的關鍵保障

目錄 適用產品認證范圍 認證項目及技術要求 認證流程 認證周期 與其他認證的對比 常見問題 注意事項 Giteki 認證&#xff0c;其名稱來源于日本語 “技適マーク”&#xff0c;羅馬字拼寫為 “GITEKI” &#xff0c;在行業內也常被稱為 Telec 認證、MIC 認證、RF 認證或技…

Ubuntu24.04 配置遠程桌面服務

一&#xff1a;安裝 sudo apt update sudo apt install vino 二&#xff1a;設置 gsettings set org.gnome.Vino require-encryption false # 關閉加密&#xff08;某些 VNC 客戶端不支持加密&#xff09; gsettings set org.gnome.Vino prompt-enabled false # 關閉連接…

人工智能與軟件工程結合的發展趨勢

AI與軟件工程的結合正在深刻改變軟件開發的流程、工具和方法&#xff0c;其發展方向涵蓋了從代碼生成到系統維護的整個生命周期。以下是主要的發展方向和技術趨勢&#xff1a; 1. 軟件架構體系的重構 從“面向過程”到“面向目標”的架構轉型&#xff1a; AI驅動軟件設計以目標…

轉發和重定向的區別詳解

轉發&#xff08;Forward&#xff09;和重定向&#xff08;Redirect&#xff09;是 Web 開發中兩種常用的請求處理方式&#xff0c;主要用于將客戶端請求從一個資源轉移到另一個資源。它們在實現機制、行為表現和應用場景上有顯著區別&#xff0c;以下是對兩者的詳細解析&#…

python專題1-----判斷一個變量是否是字符串類型

在 Python 中&#xff0c;可以使用 isinstance() 函數來判斷一個變量是否是字符串類型。字符串在 Python 中是以 str 類型表示的。下面是一些示例代碼&#xff0c;展示如何判斷一個變量是否是字符串類型&#xff1a; # 示例變量 var1 "Hello, World!" var2 12345 …

軟件工程之需求工程(需求獲取、分析、驗證)

一、需求獲取&#xff08;Requirements Elicitation&#xff09; 1. 定義與目標 需求獲取是通過與用戶、利益相關者等交互&#xff0c;識別并捕獲系統需求的過程&#xff0c;目標是明確用戶意圖與業務目標&#xff0c;避免后期因需求偏差導致返工。 2. 主要方法 問卷法&…

Java簡單生成pdf

生成這樣的PDF 直接上代碼 public static void main(String[] args) {String logoPath "Q:\\IdeaWork\\Demo\\src\\main\\webapp\\images\\logo.jpg"; // 替換為實際路徑String baseDir "E:/Demo/TEST/problem/Generate"; // 基礎目錄int year 2025; //…

k8s存儲介紹(六)StorangeClass

一、Kubernetes 存儲類&#xff08;StorageClass&#xff09;詳解 1. 什么是 StorageClass&#xff1f; 在 Kubernetes 中&#xff0c;StorageClass&#xff08;存儲類&#xff09;是一種用于動態創建 PersistentVolume&#xff08;PV&#xff09;的資源對象。它允許管理員根…

C++:allocator類(動態數組續)

1.為什么需要 allocator&#xff1f; 在 C 中&#xff0c;動態內存管理通常通過 new 和 delete 完成&#xff1a; int* p new int; // 分配內存 構造對象 delete p; // 析構對象 釋放內存 但 new 和 delete 有兩個問題&#xff1a; 耦合性&#xff1a;將內…

北斗導航 | 中國北斗衛星導航系統的發展歷程——“三步走”戰略:背景,信號頻點,調制方式,短報文,等

中國北斗衛星導航系統的發展歷程按照“三步走”戰略逐步推進,從區域服務到全球覆蓋,形成了北斗一號、北斗二號、北斗三號三代系統的迭代升級,展現了中國航天科技的自主創新與突破。以下是各階段的核心內容與發展特點綜述:一、北斗一號:中國衛星導航的奠基(1994-2003年) …

Headless Chrome 優化:減少內存占用與提速技巧

在當今數據驅動的時代&#xff0c;爬蟲技術在各行各業扮演著重要角色。傳統的爬蟲方法往往因為界面渲染和資源消耗過高而無法滿足大規模數據采集的需求。本文將深度剖析 Headless Chrome 的優化方案&#xff0c;重點探討如何利用代理 IP、Cookie 和 User-Agent 設置實現內存占用…