- 小程序手写签名分享
/* wxss */ page { background-color: #EEEEEE; } /* 详细信息展示样式 */ .page { display: flex; flex-direction: column; justify-content: center; align-items: center; } .container { padding-bottom: 5rpx; } .panel { display: flex; flex-direction: column; justify-content: space-between; align-items: stretch; box-sizing: border-box; width: 710rpx; margin-top: 15rpx; border-radius: 10rpx; background-color: #FFFFFF; } page { --canvas-hight:800px; } .wricont{ width:100%; height:var(--canvas-hight); align-items: center; display: flex; } .canvastyle{ height:100%; width:100%; background-color: #f5f5f5; } <!-- wxml --> <view class="container page"> <view class="panel"> <view class="wricont" style="{{viewData.style}}"> <canvas class="canvastyle" canvas-id="myCanvas" id='myCanvas' bindtouchstart="beg_t" bindtouchmove="move_t"></canvas> </view> <view style="display:flex;align-items:center;height: 50px;"> <button size="mini" type="warn" class="btn1" bindtap="clear">重写</button> <button size="mini" type="default" class="btn2" bindtap="save">确认</button> </view> </view> </view> // json { "usingComponents": {}, "navigationBarTitleText": "签名确认", "disableScroll":true } //js代码 var x = 0 var y = 0 var w = 0 var h = 0 let myStyle = ` --canvas-hight:1000px; ` Page({ data: { viewData: { style: myStyle }, ctx:'', image:[] }, onLoad(options) { var that = this const ctx = wx.createCanvasContext('myCanvas') //获取手机屏幕高度和宽度 wx.getSystemInfo({ success (res) { w = res.windowWidth-28 let h0 = res.windowHeight-110 h = res.windowHeight-120 console.log(w,h) //根据手机高自适应 var chageStyle = `--canvas-hight:`+h0+'px;' that.setData({'viewData.style': chageStyle}) //外线框颜色 ctx.setStrokeStyle('grey') ctx.fill('red') //画一哥矩形 ctx.rect(2, 2, w, h) // 设定虚线(【实线长,虚线长】,虚线偏移量) ctx.setLineDash([10, 10], 5); //矩形线宽 ctx.setLineWidth(2) //画布底色,不设定导出来图片背景默认黑色, ctx.setFillStyle('#f5f5f5') //画布底色大小, ctx.fillRect(2, 2, w, h) ctx.stroke() ctx.draw() that.setData({ ctx:ctx }) } }) }, beg_t(e) { //开始触摸位置, x = e.changedTouches[0].x y = e.changedTouches[0].y console.log(x,y); console.log(e); }, move_t(e) { //开始写 var ctx = this.data.ctx var x1 = e.changedTouches[0].x var y1 = e.changedTouches[0].y //指针移到开始触摸位置 ctx.moveTo(x, y) //线条黑色 ctx.setStrokeStyle('black') //线条宽度 ctx.setLineWidth(5) // 设定虚线(【实线长,虚线长】,虚线偏移量) ctx.setLineDash([10, 0], 5); //画点(x,y)到点(x1,y1) ctx.lineTo(x1, y1) ctx.stroke() // ctx.draw(true) 设定true后,保留前面的draw(),不会被清空。 ctx.draw(true) x = x1 y = y1 this.setData({ ctx:ctx }) console.log(x,y); }, clear:function(){ var that = this var ctx = this.data.ctx //线条颜色 ctx.setStrokeStyle('grey') ctx.rect(2, 2, w, h) // 设定虚线(【实线长,虚线长】,虚线偏移量) ctx.setLineDash([10, 10], 5); //线宽 ctx.setLineWidth(2) ctx.stroke() ctx.draw() that.setData({ ctx:ctx }) }, save:function(){ var that = this wx.canvasToTempFilePath({ x: 2, y: 2, width: w, height: h, destWidth: w, destHeight: h, canvasId: 'myCanvas', success(res) { console.log(res.tempFilePath) that.setData({ ["image[0]"]:res.tempFilePath, }) wx.previewImage({ current:that.data.image[0], urls:that.data.image }); } }) } })
2022-05-11 - 小程序实现列表拖拽排序
小程序列表拖拽排序 [图片] wxml [代码]<view class='listbox'> <view class='list kelong' hidden='{{!showkelong}}' style='top:{{kelong.top}}px'> <view class='index'>?</view> <image src='{{kelong.xt}}' class='xt'></image> <view class='info'> <view class="name">{{kelong.name}}</view> <view class='sub-name'>{{kelong.subname}}</view> </view> <image src='/images/sl_36.png' class='more'></image> </view> <view class='list' wx:for="{{optionList}}" wx:key=""> <view class='index'>{{index+1}}</view> <image src='{{item.xt}}' class='xt'></image> <view class='info'> <view class="name">{{item.name}}</view> <view class='sub-name'>{{item.subname}}</view> </view> <image src='/images/sl_36.png' class='more'></image> <view class='moreiconpl' data-index='{{index}}' catchtouchstart='dragStart' catchtouchmove='dragMove' catchtouchend='dragEnd'></view> </view> </view> [代码] wxss [代码].map-list .list { position: relative; height: 120rpx; } .map-list .list::after { content: ''; width: 660rpx; height: 2rpx; background-color: #eee; position: absolute; right: 0; bottom: 0; } .map-list .list .xt { display: block; width: 95rpx; height: 77rpx; position: absolute; left: 93rpx; top: 20rpx; } .map-list .list .more { display: block; width: 48rpx; height: 38rpx; position: absolute; right: 30rpx; top: 40rpx; } .map-list .list .info { display: block; width: 380rpx; height: 80rpx; position: absolute; left: 220rpx; top: 20rpx; font-size: 30rpx; } .map-list .list .info .sub-name { font-size: 28rpx; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: #646567; } .map-list .list .index { color: #e4463b; font-size: 32rpx; font-weight: bold; position: absolute; left: 35rpx; top: 40rpx; } [代码] js [代码]data:{ kelong: { top: 0, xt: '', name: '', subname: '' }, replace: { xt: '', name: '', subname: '' }, }, dragStart: function(e) { var that = this var kelong = that.data.kelong var i = e.currentTarget.dataset.index kelong.xt = this.data.optionList[i].xt kelong.name = this.data.optionList[i].name kelong.subname = this.data.optionList[i].subname var query = wx.createSelectorQuery(); //选择id query.select('.listbox').boundingClientRect(function(rect) { // console.log(rect.top) kelong.top = e.changedTouches[0].clientY - rect.top - 30 that.setData({ kelong: kelong, showkelong: true }) }).exec(); }, dragMove: function(e) { var that = this var i = e.currentTarget.dataset.index var query = wx.createSelectorQuery(); var kelong = that.data.kelong var listnum = that.data.optionList.length var optionList = that.data.optionList query.select('.listbox').boundingClientRect(function(rect) { kelong.top = e.changedTouches[0].clientY - rect.top - 30 if(kelong.top < -60) { kelong.top = -60 } else if (kelong.top > rect.height) { kelong.top = rect.height - 60 } that.setData({ kelong: kelong, }) }).exec(); }, dragEnd: function(e) { var that = this var i = e.currentTarget.dataset.index var query = wx.createSelectorQuery(); var kelong = that.data.kelong var listnum = that.data.optionList.length var optionList = that.data.optionList query.select('.listbox').boundingClientRect(function (rect) { kelong.top = e.changedTouches[0].clientY - rect.top - 30 if(kelong.top<-20){ wx.showModal({ title: '删除提示', content: '确定要删除此条记录?', confirmColor:'#e4463b' }) } var target = parseInt(kelong.top / 60) var replace = that.data.replace if (target >= 0) { replace.xt = optionList[target].xt replace.name = optionList[target].name replace.subname = optionList[target].subname optionList[target].xt = optionList[i].xt optionList[target].name = optionList[i].name optionList[target].subname = optionList[i].subname optionList[i].xt = replace.xt optionList[i].name = replace.name optionList[i].subname = replace.subname } that.setData({ optionList: optionList, showkelong:false }) }).exec(); }, [代码]
2019-07-28 - 如何实现一个自定义导航栏
自定义导航栏在刚出的时候已经有很多实现方案了,但是还有大哥在问,那这里再贴下代码及原理: 首先在App.js的 onLaunch中获取当前手机机型头部状态栏的高度,单位为px,存在内存中,操作如下: [代码]onLaunch() { wx.getSystemInfo({ success: (res) => { this.globalData.statusBarHeight = res.statusBarHeight this.globalData.titleBarHeight = wx.getMenuButtonBoundingClientRect().bottom + wx.getMenuButtonBoundingClientRect().top - (res.statusBarHeight * 2) }, failure() { this.globalData.statusBarHeight = 0 this.globalData.titleBarHeight = 0 } }) } [代码] 然后需要在目录下新建个components文件夹,里面存放此次需要演示的文件 navigateTitle WXML 文件如下: [代码]<view class="navigate-container"> <view style="height:{{statusBarHeight}}px"></view> <view class="navigate-bar" style="height:{{titleBarHeight}}px"> <view class="navigate-icon"> <navigator class="navigator-back" open-type="navigateBack" wx:if="{{!isShowHome}}" /> <navigator class="navigator-home" open-type="switchTab" url="/pages/index/index" wx:else /> </view> <view class="navigate-title">{{title}}</view> <view class="navigate-icon"></view> </view> </view> <view class="navigate-line" style="height: {{statusBarHeight + titleBarHeight}}px; width: 100%;"></view> [代码] WXSS文件如下: [代码].navigate-container { position: fixed; top: 0; width: 100%; z-index: 9999; background: #FFF; } .navigate-bar { width: 100%; display: flex; justify-content: space-around; } .navigate-icon { width: 100rpx; height: 100rpx; display: flex; justify-content: space-around; } .navigate-title { width: 550rpx; text-align: center; line-height: 100rpx; font-size: 34rpx; color: #3c3c3c; font-weight: bold; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; } /*箭头部分*/ .navigator-back { width: 36rpx; height: 36rpx; align-self: center; } .navigator-back:after { content: ''; display: block; width: 22rpx; height: 22rpx; border-right: 4rpx solid #000; border-top: 4rpx solid #000; transform: rotate(225deg); } .navigator-home { width: 56rpx; height: 56rpx; background: url(https://qiniu-image.qtshe.com/20190301home.png) no-repeat center center; background-size: 100% 100%; align-self: center; } [代码] JS如下: [代码]var app = getApp() Component({ data: { statusBarHeight: '', titleBarHeight: '', isShowHome: false }, properties: { //属性值可以在组件使用时指定 title: { type: String, value: '青团公益' } }, pageLifetimes: { // 组件所在页面的生命周期函数 show() { let pageContext = getCurrentPages() if (pageContext.length > 1) { this.setData({ isShowHome: false }) } else { this.setData({ isShowHome: true }) } } }, attached() { this.setData({ statusBarHeight: app.globalData.statusBarHeight, titleBarHeight: app.globalData.titleBarHeight }) }, methods: {} }) [代码] JSON如下: [代码]{ "component": true } [代码] 如何引用? 需要引用的页面JSON里配置: [代码]"navigationStyle": "custom", "usingComponents": { "navigate-title": "/pages/components/navigateTitle/index" } [代码] WXML [代码]<navigate-title title="青团社" /> [代码] 按上面步骤操作即可实现一个自定义的导航栏。 如何实现通栏的效果默认透明以及滚动更换title为白色背景,如下图所示: [图片] [图片] [图片] [图片] 最后代码片段如下: https://developers.weixin.qq.com/s/wi6Pglmv7s8P。 以下为收集到的社区老哥们的分享: @Yunior: 小程序顶部自定义导航组件实现原理及坑分享 @志军: 微信小程序自定义导航栏组件(完美适配所有手机),可自定义实现任何你想要的功能 @✨o0o有脾气的酸奶💤 [有点炫]自定义navigate+分包+自定义tabbar @安晓苏 分享一个自适应的自定义导航栏组件
2020-03-10