diff --git a/App.vue b/App.vue index 1f7b077..83e2dff 100644 --- a/App.vue +++ b/App.vue @@ -1,6 +1,6 @@ - + + \ No newline at end of file diff --git a/libs/components/demo-title.vue b/libs/components/demo-title.vue new file mode 100644 index 0000000..1386ff8 --- /dev/null +++ b/libs/components/demo-title.vue @@ -0,0 +1,94 @@ + + + + + diff --git a/libs/components/dynamic-demo-template.vue b/libs/components/dynamic-demo-template.vue new file mode 100644 index 0000000..2bafebe --- /dev/null +++ b/libs/components/dynamic-demo-template.vue @@ -0,0 +1,689 @@ + + + + + diff --git a/libs/components/multiple-options-demo.vue b/libs/components/multiple-options-demo.vue new file mode 100644 index 0000000..f3644b6 --- /dev/null +++ b/libs/components/multiple-options-demo.vue @@ -0,0 +1,147 @@ + + + + + diff --git a/libs/components/nav-index-button.vue b/libs/components/nav-index-button.vue new file mode 100644 index 0000000..8301940 --- /dev/null +++ b/libs/components/nav-index-button.vue @@ -0,0 +1,169 @@ + + + + + diff --git a/libs/mixin/dynamic_demo_mixin.js b/libs/mixin/dynamic_demo_mixin.js new file mode 100644 index 0000000..66ff992 --- /dev/null +++ b/libs/mixin/dynamic_demo_mixin.js @@ -0,0 +1,52 @@ +/** + * 动态参数演示mixin + */ +module.exports = { + data() { + return { + // 效果显示框top的值 + contentContainerTop: '0px', + contentContainerIsTop: false, + + // 参数显示框top的值 + sectionContainerTop: '0px' + } + }, + onReady() { + this.updateSectionContainerTop() + }, + methods: { + // 处理演示效果框的位置 + async _handleContentConatinerPosition() { + // 获取效果演示框的节点信息 + const contentContainer = await this._tGetRect('#content_container') + // 获取参数框的节点信息 + this._tGetRect('#section_container').then((res) => { + // 判断参数框是否在移动,如果是则更新效果框的位置 + // 如果效果框的顶部已经触控到顶部导航栏就停止跟随 + if (res.top - contentContainer.bottom != 15) { + const newTop = res.top - (contentContainer.height + uni.upx2px(20)) + const minTop = this.vuex_custom_bar_height + 1 + if (newTop < minTop) { + this.contentContainerTop = minTop + 'px' + this.contentContainerIsTop = true + } else { + this.contentContainerTop = newTop + 'px' + this.contentContainerIsTop = false + } + } + }) + }, + // 更新状态切换栏位置信息 + updateSectionContainerTop() { + this._tGetRect('#content_container').then((res) => { + this.contentContainerTop = (this.vuex_custom_bar_height + 148) + 'px' + this.sectionContainerTop = (res.height + 20) + 'px' + }) + } + }, + // 监听页面滚动 + onPageScroll() { + this._handleContentConatinerPosition() + } +} diff --git a/libs/mixin/template_page_mixin.js b/libs/mixin/template_page_mixin.js new file mode 100644 index 0000000..3a46196 --- /dev/null +++ b/libs/mixin/template_page_mixin.js @@ -0,0 +1,60 @@ +/** + * 演示页面mixin + */ +module.exports = { + data() { + return { + + } + }, + onLoad() { + // 更新顶部导航栏信息 + this.updateCustomBarInfo() + }, + methods: { + // 点击左上角返回按钮时触发事件 + goBack() { + // 通过判断当前页面的页面栈信息,是否有上一页进行返回,如果没有则跳转到首页 + const pages = getCurrentPages() + if (pages && pages.length > 0) { + const firstPage = pages[0] + if (pages.length == 1 && (!firstPage.route || firstPage.route != 'pages/index')) { + uni.reLaunch({ + url: '/pages/index' + }) + } else { + uni.navigateBack({ + delta: 1 + }) + } + } else { + uni.reLaunch({ + url: '/pages/index' + }) + } + }, + // 更新顶部导航栏信息 + async updateCustomBarInfo() { + // 获取vuex中的自定义顶栏的高度 + let customBarHeight = this.vuex_custom_bar_height + let statusBarHeight = this.vuex_status_bar_height + // 如果获取失败则重新获取 + if (!customBarHeight) { + try { + const navBarInfo = await this.$t.updateCustomBar() + customBarHeight = navBarInfo.customBarHeight + statusBarHeight = navBarInfo.statusBarHeight + } catch(e) { + setTimeout(() => { + this.updateCustomBarInfo() + }, 10) + return + } + } + + // 更新vuex中的导航栏信息 + this.$t.vuex('vuex_status_bar_height', statusBarHeight) + this.$t.vuex('vuex_custom_bar_height', customBarHeight) + } + } +} \ No newline at end of file diff --git a/libs/navigation/navigation.js b/libs/navigation/navigation.js new file mode 100644 index 0000000..ec62a40 --- /dev/null +++ b/libs/navigation/navigation.js @@ -0,0 +1,330 @@ +/** + * 页面展示列表数据 + */ +export default { + data: [{ + title: '图鸟首页', + backgroundColor: 'tn-cool-bg-color-1', + list: [{ + icon: 'code', + title: '关于我们', + url: '/homePages/about', + author: '图鸟北北' + },{ + icon: 'code', + title: '全局搜索', + url: '/homePages/search', + author: '图鸟北北' + }, + { + icon: 'code', + title: '今日热榜', + url: '/homePages/hot', + author: '图鸟北北' + }, + { + icon: 'code', + title: '前端业务', + url: '/homePages/profession', + author: '图鸟北北' + }, + { + icon: 'code', + title: '加载效果', + url: '/homePages/loading', + author: '图鸟北北' + } + ] + }, + { + title: '酷炫圈子', + backgroundColor: 'tn-cool-bg-color-1', + list: [{ + icon: 'code', + title: '博主_Me', + url: '/circlePages/blogger', + author: '图鸟北北' + }, + { + icon: 'code', + title: '博主_Ta', + url: '/circlePages/blogger_other', + author: '图鸟北北' + }, + { + icon: 'code', + title: '编辑发布', + url: '/circlePages/edit', + author: '图鸟北北' + }, + { + icon: 'code', + title: '广告页', + url: '/circlePages/advertise', + author: '图鸟北北' + }, + { + icon: 'code', + title: '资讯详情', + url: '/circlePages/news', + author: '图鸟北北' + }, + { + icon: 'code', + title: '名片王者', + url: '/circlePages/king', + author: '图鸟北北' + }, + { + icon: 'code', + title: '智能名片', + url: '/circlePages/business', + author: '图鸟北北' + }, + { + icon: 'code', + title: '精选圈子', + url: '/circlePages/group', + author: '图鸟北北' + }, + { + icon: 'code', + title: '积分排行', + url: '/circlePages/ranking', + author: '图鸟北北' + }, + { + icon: 'code', + title: '圈子详情', + url: '/circlePages/details', + author: '图鸟北北' + }, + { + icon: 'code', + title: '预约接龙', + url: '/circlePages/reserve', + author: '图鸟北北' + }, + { + icon: 'code', + title: '活动创建', + url: '/circlePages/create', + author: '图鸟北北' + }, + { + icon: 'code', + title: '打造圈子', + url: '/circlePages/build', + author: '图鸟北北' + }, + { + icon: 'code', + title: '一起群聊', + url: '/circlePages/chat', + author: '图鸟北北' + }, + { + icon: 'code', + title: '对话聊天', + url: '/circlePages/chatting', + author: '图鸟北北' + } + ] + }, + { + title: '活动广场', + backgroundColor: 'tn-cool-bg-color-1', + list: [{ + icon: 'code', + title: '地图打卡', + url: '/activityPages/map', + author: '图鸟北北' + }, + { + icon: 'code', + title: '快速答题', + url: '/activityPages/topic', + author: '图鸟北北' + }, + { + icon: 'code', + title: '课程学习', + url: '/activityPages/study', + author: '图鸟北北' + }, + { + icon: 'code', + title: '开源项目', + url: '/activityPages/project', + author: '图鸟北北' + }, + { + icon: 'code', + title: '活动星球', + url: '/activityPages/planet', + author: '图鸟北北' + } + ] + }, + { + title: '商品优选', + backgroundColor: 'tn-cool-bg-color-1', + list: [{ + icon: 'code', + title: '优质商家', + url: '/preferredPages/shop', + author: '图鸟北北' + }, + { + icon: 'code', + title: '商品详情', + url: '/preferredPages/product', + author: '图鸟北北' + }, + { + icon: 'code', + title: '历史订单', + url: '/preferredPages/order', + author: '图鸟北北' + }, + { + icon: 'code', + title: '商品分类', + url: '/preferredPages/classify', + author: '图鸟北北' + }, + { + icon: 'code', + title: '商家相册', + url: '/preferredPages/photo', + author: '图鸟北北' + }, + { + icon: 'code', + title: '品牌官网', + url: '/preferredPages/website', + author: '图鸟北北' + }, + { + icon: 'code', + title: '积分兑换', + url: '/preferredPages/redeem', + author: '图鸟北北' + }, + { + icon: 'code', + title: '免单活动', + url: '/preferredPages/award', + author: '图鸟北北' + }, + { + icon: 'code', + title: '免单获取', + url: '/preferredPages/awardget', + author: '图鸟北北' + } + ] + }, + { + title: '关于我的', + backgroundColor: 'tn-cool-bg-color-1', + list: [{ + icon: 'code', + title: '使用协议', + url: '/minePages/protocol', + author: '图鸟北北' + }, + { + icon: 'code', + title: '授权登录', + url: '/minePages/login', + author: '图鸟北北' + }, + { + icon: 'code', + title: '消息通知', + url: '/minePages/message', + author: '图鸟北北' + }, + { + icon: 'code', + title: '全局设置', + url: '/minePages/set', + author: '图鸟北北' + }, + { + icon: 'code', + title: '立即体验', + url: '/minePages/start', + author: '图鸟北北' + }, + { + icon: 'code', + title: '感谢名单', + url: '/minePages/thanks', + author: '图鸟北北' + }, + { + icon: 'code', + title: '版本更新', + url: '/minePages/version', + author: '图鸟北北' + }, + { + icon: 'code', + title: '帮助中心', + url: '/minePages/help', + author: '图鸟北北' + }, + { + icon: 'code', + title: '头像上传', + url: '/minePages/avatar', + author: '图鸟北北' + }, + { + icon: 'code', + title: '积分明细', + url: '/minePages/integral', + author: '图鸟北北' + }, + { + icon: 'code', + title: '积分签到', + url: '/minePages/signed', + author: '图鸟北北' + }, + { + icon: 'code', + title: '好物收藏', + url: '/minePages/collect', + author: '图鸟北北' + }, + { + icon: 'code', + title: '账号安全', + url: '/minePages/safety', + author: '图鸟北北' + }, + { + icon: 'code', + title: '赞赏支持', + url: '/minePages/reward', + author: '图鸟北北' + }, + { + icon: 'code', + title: '缺省页', + url: '/minePages/default', + author: '图鸟北北' + }, + { + icon: 'code', + title: '富文本', + url: '/minePages/content', + author: '图鸟北北' + } + ] + } + ] +} diff --git a/main.js b/main.js index 74b2cd9..c1a0d4c 100644 --- a/main.js +++ b/main.js @@ -1,10 +1,10 @@ -import Vue from 'vue' import App from './App' - - +import store from './store' +import Vue from 'vue' import HttpRequest from './common/httpRequest' import HttpCache from './common/cache' import queue from './common/queue' +import TuniaoUI from 'tuniao-ui' Vue.config.productionTip = false Vue.prototype.$Request = HttpRequest; @@ -12,7 +12,6 @@ Vue.prototype.$queue = queue; Vue.prototype.$Sysconf = HttpRequest.config; Vue.prototype.$SysCache = HttpCache; - App.mpType = 'app' // 引入全局uView @@ -21,13 +20,17 @@ Vue.use(uView); const app = new Vue({ + store, ...App }) // http拦截器,将此部分放在new Vue()和app.$mount()之间,才能App.vue中正常使用 import httpInterceptor from '@/common/http.interceptor.js' Vue.use(httpInterceptor, app) - +Vue.use(TuniaoUI) +// 引入TuniaoUI提供的vuex简写方法 +let vuexStore = require('@/store/$t.mixin.js') +Vue.mixin(vuexStore) // http接口API集中管理引入部分 import httpApi from '@/common/http.api.js' Vue.use(httpApi, app) diff --git a/other/blogger/blogger.vue b/other/blogger/blogger.vue new file mode 100644 index 0000000..f2708d4 --- /dev/null +++ b/other/blogger/blogger.vue @@ -0,0 +1,1206 @@ + + + + + diff --git a/other/blogger/details.vue b/other/blogger/details.vue new file mode 100644 index 0000000..089c384 --- /dev/null +++ b/other/blogger/details.vue @@ -0,0 +1,800 @@ + + + + + diff --git a/other/index/index.vue b/other/index/index.vue new file mode 100644 index 0000000..17e014b --- /dev/null +++ b/other/index/index.vue @@ -0,0 +1,1042 @@ + + + + + \ No newline at end of file diff --git a/other/slotMachine/components/pop-ling-qu.vue b/other/slotMachine/components/pop-ling-qu.vue new file mode 100644 index 0000000..3daa8e1 --- /dev/null +++ b/other/slotMachine/components/pop-ling-qu.vue @@ -0,0 +1,163 @@ + + + + + \ No newline at end of file diff --git a/other/slotMachine/slotMachine.vue b/other/slotMachine/slotMachine.vue index a45b726..47c622b 100644 --- a/other/slotMachine/slotMachine.vue +++ b/other/slotMachine/slotMachine.vue @@ -1,33 +1,73 @@ - + \ No newline at end of file diff --git a/other/static/ad.png b/other/static/ad.png new file mode 100644 index 0000000..7ebd0e1 Binary files /dev/null and b/other/static/ad.png differ diff --git a/other/static/avatar/5.png b/other/static/avatar/5.png new file mode 100644 index 0000000..f179988 Binary files /dev/null and b/other/static/avatar/5.png differ diff --git a/other/static/avatar/6.png b/other/static/avatar/6.png new file mode 100644 index 0000000..4808c25 Binary files /dev/null and b/other/static/avatar/6.png differ diff --git a/other/static/avatar/7.png b/other/static/avatar/7.png new file mode 100644 index 0000000..31a3d75 Binary files /dev/null and b/other/static/avatar/7.png differ diff --git a/other/tools/tools.vue b/other/tools/tools.vue new file mode 100644 index 0000000..2fb9c1f --- /dev/null +++ b/other/tools/tools.vue @@ -0,0 +1,779 @@ + + + + + \ No newline at end of file diff --git a/other/topic/reserve.vue b/other/topic/reserve.vue new file mode 100644 index 0000000..6b59b66 --- /dev/null +++ b/other/topic/reserve.vue @@ -0,0 +1,570 @@ + + + + + diff --git a/other/topic/topic.vue b/other/topic/topic.vue new file mode 100644 index 0000000..a5e54d7 --- /dev/null +++ b/other/topic/topic.vue @@ -0,0 +1,1287 @@ + + + + + diff --git a/pages.json b/pages.json index a028a7a..1ef6993 100644 --- a/pages.json +++ b/pages.json @@ -1,6 +1,7 @@ { "easycom": { - "^u-(.*)": "@/uview-ui/components/u-$1/u-$1.vue" + "^u-(.*)": "@/uview-ui/components/u-$1/u-$1.vue", + "^tn-(.*)": "@/tuniao-ui/components/tn-$1/tn-$1.vue" }, "pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages { @@ -688,7 +689,13 @@ }, { "root": "other", - "pages": [ + "pages": [{ + "path": "index/index", + "style": { + "navigationStyle": "custom", + "navigationBarTitleText": "更多" + } + }, { "path": "about/about", "style": { @@ -696,33 +703,68 @@ } }, { - "path" : "coup/coup", - "style" : - { - "navigationBarTitleText" : "卡包" + "path": "coup/coup", + "style": { + "navigationBarTitleText": "卡包" } }, { - "path" : "address/address", - "style" : - { - "navigationBarTitleText" : "收货地址" + "path": "address/address", + "style": { + "navigationBarTitleText": "收货地址" } }, { - "path" : "pay/pay", - "style" : - { - "navigationBarTitleText" : "发红包" + "path": "pay/pay", + "style": { + "navigationBarTitleText": "发红包" } }, { - "path" : "slotMachine/slotMachine", - "style" : - { - "navigationBarTitleText" : "抽奖", + "path": "slotMachine/slotMachine", + "style": { + "navigationBarTitleText": "抽奖", + "navigationStyle": "custom" + + } + }, + { + "path" : "blogger/blogger", + "style" : + { + "navigationBarTitleText" : "", + "navigationStyle": "custom" + } + }, + { + "path" : "blogger/details", + "style" : + { + "navigationBarTitleText" : "", + "navigationStyle": "custom" + } + }, + { + "path" : "topic/topic", + "style" : + { + "navigationBarTitleText" : "话题" + } + }, + { + "path" : "topic/reserve", + "style" : + { + "navigationBarTitleText" : "", + "navigationStyle": "custom" + } + }, + { + "path" : "tools/tools", + "style" : + { + "navigationBarTitleText" : "", "navigationStyle": "custom" - } } diff --git a/pages/me/index.vue b/pages/me/index.vue index d074982..bad33ef 100644 --- a/pages/me/index.vue +++ b/pages/me/index.vue @@ -251,16 +251,21 @@ - + + + + + diff --git a/tuniao-ui/components/tn-avatar-group/tn-avatar-group.vue b/tuniao-ui/components/tn-avatar-group/tn-avatar-group.vue new file mode 100644 index 0000000..4d5b547 --- /dev/null +++ b/tuniao-ui/components/tn-avatar-group/tn-avatar-group.vue @@ -0,0 +1,104 @@ + + + + + diff --git a/tuniao-ui/components/tn-avatar/tn-avatar.vue b/tuniao-ui/components/tn-avatar/tn-avatar.vue new file mode 100644 index 0000000..96e7100 --- /dev/null +++ b/tuniao-ui/components/tn-avatar/tn-avatar.vue @@ -0,0 +1,298 @@ + + + + + diff --git a/tuniao-ui/components/tn-badge/tn-badge.vue b/tuniao-ui/components/tn-badge/tn-badge.vue new file mode 100644 index 0000000..5e1747d --- /dev/null +++ b/tuniao-ui/components/tn-badge/tn-badge.vue @@ -0,0 +1,173 @@ + + + + + diff --git a/tuniao-ui/components/tn-button/tn-button.vue b/tuniao-ui/components/tn-button/tn-button.vue new file mode 100644 index 0000000..820ce2f --- /dev/null +++ b/tuniao-ui/components/tn-button/tn-button.vue @@ -0,0 +1,302 @@ + + + + + diff --git a/tuniao-ui/components/tn-calendar/tn-calendar.vue b/tuniao-ui/components/tn-calendar/tn-calendar.vue new file mode 100644 index 0000000..e0711e8 --- /dev/null +++ b/tuniao-ui/components/tn-calendar/tn-calendar.vue @@ -0,0 +1,707 @@ + + + + + diff --git a/tuniao-ui/components/tn-car-keyboard/tn-car-keyboard.vue b/tuniao-ui/components/tn-car-keyboard/tn-car-keyboard.vue new file mode 100644 index 0000000..f92559c --- /dev/null +++ b/tuniao-ui/components/tn-car-keyboard/tn-car-keyboard.vue @@ -0,0 +1,320 @@ + + + + + diff --git a/tuniao-ui/components/tn-cascade-selection/tn-cascade-selection.vue b/tuniao-ui/components/tn-cascade-selection/tn-cascade-selection.vue new file mode 100644 index 0000000..02ac406 --- /dev/null +++ b/tuniao-ui/components/tn-cascade-selection/tn-cascade-selection.vue @@ -0,0 +1,654 @@ + + + + + diff --git a/tuniao-ui/components/tn-checkbox-group/tn-checkbox-group.vue b/tuniao-ui/components/tn-checkbox-group/tn-checkbox-group.vue new file mode 100644 index 0000000..5472ad5 --- /dev/null +++ b/tuniao-ui/components/tn-checkbox-group/tn-checkbox-group.vue @@ -0,0 +1,134 @@ + + + + + diff --git a/tuniao-ui/components/tn-checkbox/tn-checkbox.vue b/tuniao-ui/components/tn-checkbox/tn-checkbox.vue new file mode 100644 index 0000000..e11d8f5 --- /dev/null +++ b/tuniao-ui/components/tn-checkbox/tn-checkbox.vue @@ -0,0 +1,328 @@ + + + + + diff --git a/tuniao-ui/components/tn-circle-progress/tn-circle-progress.vue b/tuniao-ui/components/tn-circle-progress/tn-circle-progress.vue new file mode 100644 index 0000000..6788c5d --- /dev/null +++ b/tuniao-ui/components/tn-circle-progress/tn-circle-progress.vue @@ -0,0 +1,223 @@ + + + + + diff --git a/tuniao-ui/components/tn-collapse-item/tn-collapse-item.vue b/tuniao-ui/components/tn-collapse-item/tn-collapse-item.vue new file mode 100644 index 0000000..62a9493 --- /dev/null +++ b/tuniao-ui/components/tn-collapse-item/tn-collapse-item.vue @@ -0,0 +1,236 @@ + + + + + diff --git a/tuniao-ui/components/tn-collapse/tn-collapse.vue b/tuniao-ui/components/tn-collapse/tn-collapse.vue new file mode 100644 index 0000000..00ec9a2 --- /dev/null +++ b/tuniao-ui/components/tn-collapse/tn-collapse.vue @@ -0,0 +1,98 @@ + + + + + diff --git a/tuniao-ui/components/tn-color-icon/tn-color-icon.vue b/tuniao-ui/components/tn-color-icon/tn-color-icon.vue new file mode 100644 index 0000000..c7ad83b --- /dev/null +++ b/tuniao-ui/components/tn-color-icon/tn-color-icon.vue @@ -0,0 +1,318 @@ + + + + + diff --git a/tuniao-ui/components/tn-column-notice/tn-column-notice.vue b/tuniao-ui/components/tn-column-notice/tn-column-notice.vue new file mode 100644 index 0000000..d5d795b --- /dev/null +++ b/tuniao-ui/components/tn-column-notice/tn-column-notice.vue @@ -0,0 +1,251 @@ + + + + + diff --git a/tuniao-ui/components/tn-count-down/tn-count-down.vue b/tuniao-ui/components/tn-count-down/tn-count-down.vue new file mode 100644 index 0000000..7a97943 --- /dev/null +++ b/tuniao-ui/components/tn-count-down/tn-count-down.vue @@ -0,0 +1,314 @@ + + + + + diff --git a/tuniao-ui/components/tn-count-scroll/tn-count-scroll.vue b/tuniao-ui/components/tn-count-scroll/tn-count-scroll.vue new file mode 100644 index 0000000..de208c8 --- /dev/null +++ b/tuniao-ui/components/tn-count-scroll/tn-count-scroll.vue @@ -0,0 +1,171 @@ + + + + + diff --git a/tuniao-ui/components/tn-count-to/tn-count-to.vue b/tuniao-ui/components/tn-count-to/tn-count-to.vue new file mode 100644 index 0000000..c3d8854 --- /dev/null +++ b/tuniao-ui/components/tn-count-to/tn-count-to.vue @@ -0,0 +1,231 @@ + + + + + diff --git a/tuniao-ui/components/tn-cropper/index.wxs b/tuniao-ui/components/tn-cropper/index.wxs new file mode 100644 index 0000000..6707e96 --- /dev/null +++ b/tuniao-ui/components/tn-cropper/index.wxs @@ -0,0 +1,328 @@ +var cropper = { + // 画布x轴起点 + cutX: 0, + // 画布y轴起点 + cutY: 0, + // 触摸点信息(手指与图片中心点的相对位置) + touchRelactive: [{ + x: 0, + y: 0 + }], + // 双指触摸时斜边的长度 + hypotenuseLength:0, + // 是否结束触摸 + touchEndFlag: false, + // 画布宽高 + canvasWidth: 0, + canvasHeight: 0, + // 图片宽高 + imgWidth: 0, + imgHeight: 0, + // 图片缩放比例 + scale: 1, + // 图片旋转角度 + angle: 0, + // 图片上边距 + imgTop: 0, + // 图片左边距 + imgLeft: 0, + // 窗口宽高 + windowWidth: 0, + windowHeight: 0, + init: true +} + +function bool(str) { + return str === 'true' || str === true +} + +function propsChange(prop, oldProp, ownerInstance, instance) { + if (prop && prop !== 'null') { + var params = prop.split(',') + var type = +params[0] + var dataset = instance.getDataset() + if (cropper.init || type == 4) { + cropper.canvasWidth = +dataset.width + cropper.canvasHeight = +dataset.height + cropper.imgTop = +dataset.windowheight / 2 + cropper.imgLeft = +dataset.windowwidth / 2 + cropper.imgWidth = +dataset.imgwidth + cropper.imgHeight = +dataset.imgheight + cropper.windowHeight = +dataset.windowheight + cropper.windowWidth = +dataset.windowwidth + cropper.init = false + } else if (type == 2 || type == 3) { + cropper.imgWidth = +dataset.imgwidth + cropper.imgHeight = +dataset.imgheight + } + cropper.angle = +dataset.angle + if (type == 3) { + imgTransform(ownerInstance) + } + switch(type) { + case 1: + setCutCenter(ownerInstance) + // 设置裁剪框大小 + computeCutSize(ownerInstance) + // 检查裁剪框是否在范围内 + cutDetectionPosition(ownerInstance) + break + case 2: + setCutCenter(ownerInstance) + break + case 3: + imgMarginDetectionScale(ownerInstance) + break + case 4: + imageReset(ownerInstance) + break + case 5: + setCutCenter(ownerInstance) + break + default: + break + } + } +} + +function touchStart(event, ownerInstance) { + var touch = event.touches || event.changedTouches + cropper.touchEndFlag = false + if (touch.length === 1) { + cropper.touchRelactive[0] = { + x: touch[0].pageX - cropper.imgLeft, + y: touch[0].pageY - cropper.imgTop + } + } else { + var width = Math.abs(touch[0].pageX - touch[1].pageX) + var height = Math.abs(touch[0].pageY - touch[1].pageY) + cropper.touchRelactive = [{ + x: touch[0].pageX - cropper.imgLeft, + y: touch[0].pageY - cropper.imgTop + },{ + x: touch[1].pageX - cropper.imgLeft, + y: touch[1].pageY - cropper.imgTop + }] + cropper.hypotenuseLength = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)) + } +} + +function touchMove(event, ownerInstance) { + var touch = event.touches || event.changedTouches + if (cropper.touchEndFlag) return + moveDuring(ownerInstance) + if (event.touches.length === 1) { + var left = touch[0].pageX - cropper.touchRelactive[0].x, + top = touch[0].pageY - cropper.touchRelactive[0].y; + cropper.imgLeft = left + cropper.imgTop = top + imgTransform(ownerInstance) + imgMarginDetectionPosition(ownerInstance) + } else { + var dataset = event.instance.getDataset() + var minScale = +dataset.minscale + var maxScale = +dataset.maxscale + var width = Math.abs(touch[0].pageX - touch[1].pageX), + height = Math.abs(touch[0].pageY - touch[1].pageY), + hypotenuse = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)), + scale = cropper.scale * (hypotenuse / cropper.hypotenuseLength), + current_deg = 0; + scale = scale <= minScale ? minScale : scale + scale = scale >= maxScale ? maxScale : scale + cropper.scale = scale + imgMarginDetectionScale(ownerInstance, true) + var touchRelative = [{ + x: touch[0].pageX - cropper.imgLeft, + y: touch[0].pageY - cropper.imgTop + }, { + x: touch[1].pageX - cropper.imgLeft, + y: touch[1].pageY - cropper.imgTop + }] + cropper.touchRelactive = touchRelative + cropper.hypotenuseLength = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)) + // 更新视图 + cropper.angle = cropper.angle + current_deg + imgTransform(ownerInstance) + } +} + +function touchEnd(event, ownerInstance) { + cropper.touchEndFlag = true + moveStop(ownerInstance) + updateData(ownerInstance) +} + +function moveDuring(ownerInstance) { + if (!ownerInstance) return + ownerInstance.callMethod('moveDuring') +} + +function moveStop(ownerInstance) { + if (!ownerInstance) return + ownerInstance.callMethod('moveStop') +} + +function setCutCenter(ownerInstance) { + var cutX = (cropper.windowWidth - cropper.canvasWidth) * 0.5 + var cutY = (cropper.windowHeight - cropper.canvasHeight) * 0.5 + + cropper.imgTop = cropper.imgTop - cropper.cutY + cutY + cropper.cutY = cutY + cropper.imgLeft = cropper.imgLeft - cropper.cutX + cutX + cropper.cutX = cutX + cutDetectionPosition(ownerInstance) + imgTransform(ownerInstance) + updateData(ownerInstance) +} + +// 检测剪裁框位置是否在允许的范围内(屏幕内) +function cutDetectionPosition(ownerInstance) { + var windowHeight = cropper.windowHeight, + windowWidth = cropper.windowWidth; + + // 检测上边距是否在范围内 + var cutDetectionPositionTop = function() { + if (cropper.cutY < 0) { + cropper.cutY = 0 + } + if (cropper.cutY > windowHeight - cropper.canvasHeight) { + cropper.cutY = windowHeight - cropper.canvasHeight + } + } + + // 检测左边距是否在范围内 + var cutDetectionPositionLeft = function() { + if (cropper.cutX < 0) { + cropper.cutX = 0 + } + if (cropper.cutX > windowWidth - cropper.canvasWidth) { + cropper.cutX = windowWidth - cropper.canvasWidth + } + } + + // 裁剪框坐标处理(如果只写一个参数则另一个默认为0,都不写默认为居中) + if (cropper.cutX === null && cropper.cutY === null) { + var cutX = (windowWidth - cropper.canvasWidth) * 0.5, + cutY = (windowHeight - cropper.canvasHeight) * 0.5; + cropper.cutX = cutX + cropper.cutY = cutY + } else if (cropper.cutX !== null && cropper.cutX !== null) { + cutDetectionPositionTop() + cutDetectionPositionLeft() + } else if (cropper.cutX !== null && cropper.cutY === null) { + cutDetectionPositionLeft() + cropper.cutY = (windowHeight - cropper.canvasHeight) / 2 + } else if (cropper.cutX === null && cropper.cutY !== null) { + cutDetectionPositionTop() + cropper.cutX = (windowWidth - cropper.canvasWidth) / 2 + } +} + +// 图片边缘检测-缩放 +function imgMarginDetectionScale(ownerInstance, delay) { + var scale = cropper.scale, + imgWidth = cropper.imgWidth, + imgHeight = cropper.imgHeight; + if ((cropper.angle / 90) % 2) { + imgWidth = cropper.imgHeight + imgHeight = cropper.imgWidth + } + if (imgWidth * scale < cropper.canvasWidth) { + scale = cropper.canvasWidth / imgWidth + } + if (imgHeight * scale < cropper.canvasHeight) { + scale = Math.max(scale, cropper.canvasHeight / imgHeight) + } + imgMarginDetectionPosition(ownerInstance, scale, delay) +} + +// 图片边缘检测-位置 +function imgMarginDetectionPosition(ownerInstance, scale, delay) { + var left = cropper.imgLeft, + top = cropper.imgTop, + imgWidth = cropper.imgWidth, + imgHeight = cropper.imgHeight; + scale = scale || cropper.scale + if ((cropper.angle / 90) % 2) { + imgWidth = cropper.imgHeight + imgHeight = cropper.imgWidth + } + + left = cropper.cutX + (imgWidth * scale) / 2 >= left ? left : cropper.cutX + (imgWidth * scale) / 2 + left = cropper.cutX + cropper.canvasWidth - (imgWidth * scale) / 2 <= left ? left : cropper.cutX + cropper.canvasWidth - (imgWidth * scale) / 2 + top = cropper.cutY + (imgHeight * scale) / 2 >= top ? top : cropper.cutY + (imgHeight * scale) / 2 + top = cropper.cutY + cropper.canvasHeight - (imgHeight * scale) / 2 <= top ? top : cropper.cutY + cropper.canvasHeight - (imgHeight * scale) / 2 + + cropper.imgLeft = left + cropper.imgTop = top + cropper.scale = scale + if (!delay || delay === 'null') { + imgTransform(ownerInstance) + } +} + +// 改变截取值大小 +function computeCutSize(ownerInstance) { + if (cropper.canvasWidth > cropper.windowWidth) { + cropper.canvasWidth = cropper.windowWidth + } else if (cropper.canvasWidth + cropper.cutX > cropper.windowWidth) { + cropper.cutX = cropper.windowWidth - cropper.cutX + } + if (cropper.canvasHeight > cropper.windowHeight) { + cropper.canvasHeight = cropper.windowHeight + } else if (cropper.canvasHeight + cropper.cutY > cropper.windowHeight) { + cropper.cutY = cropper.windowHeight - cropper.cutY + } +} + +// 图片动画 +function imgTransform(ownerInstance) { + var image = ownerInstance.selectComponent('.tn-cropper__image') + if (!image) return + var x = cropper.imgLeft - cropper.imgWidth / 2, + y = cropper.imgTop - cropper.imgHeight / 2; + image.setStyle({ + 'transform': 'translate3d('+ x + 'px,' + y + 'px,0) scale(' + cropper.scale +') rotate(' + cropper.angle + 'deg)' + }) +} + +// 图片重置 +function imageReset(ownerInstance) { + cropper.scale = 1 + cropper.angle = 0 + imgTransform(ownerInstance) +} + +// 高度变化 +function canvasHeight(ownerInstance) { + if (!ownerInstance) return + computeCutSize(ownerInstance) +} + +// 宽度变化 +function canvasWidth(ownerInstance) { + if (!ownerInstance) return + computeCutSize(ownerInstance) +} + +// 更新数据 +function updateData(ownerInstance) { + if (!ownerInstance) return + ownerInstance.callMethod('change', { + cutX: cropper.cutX, + cutY: cropper.cutY, + imgWidth: cropper.imgWidth, + imgHeight: cropper.imgHeight, + scale: cropper.scale, + angle: cropper.angle, + imgTop: cropper.imgTop, + imgLeft: cropper.imgLeft + }) +} + +module.exports = { + touchStart: touchStart, + touchMove: touchMove, + touchEnd: touchEnd, + propsChange: propsChange +} \ No newline at end of file diff --git a/tuniao-ui/components/tn-cropper/tn-cropper.vue b/tuniao-ui/components/tn-cropper/tn-cropper.vue new file mode 100644 index 0000000..65d75d3 --- /dev/null +++ b/tuniao-ui/components/tn-cropper/tn-cropper.vue @@ -0,0 +1,570 @@ + + + + + + diff --git a/tuniao-ui/components/tn-custom-swiper-item/index.wxs b/tuniao-ui/components/tn-custom-swiper-item/index.wxs new file mode 100644 index 0000000..a6c12b7 --- /dev/null +++ b/tuniao-ui/components/tn-custom-swiper-item/index.wxs @@ -0,0 +1,288 @@ + +function setTimeout(instance, cb, time) { + if (time > 0) { + var s = getDate().getTime() + var fn = function () { + if (getDate().getTime() - s > time) { + cb && cb() + } else + instance.requestAnimationFrame(fn) + } + fn() + } + else + cb && cb() +} + +// 判断触摸的移动方向 +function decideSwiperDirection(startTouches, currentTouches, vertical) { + // 震动偏移容差 + var toleranceShake = 150 + // 移动容差 + var toleranceTranslate = 10 + + if (!vertical) { + // 水平方向移动 + if (Math.abs(currentTouches.y - startTouches.y) <= toleranceShake) { + // console.log(currentTouches.x, startTouches.x); + if (Math.abs(currentTouches.x - startTouches.x) > toleranceTranslate) { + if (currentTouches.x - startTouches.x > 0) { + return 'right' + } else if (currentTouches.x - startTouches.x < 0) { + return 'left' + } + } + } + } else { + // 垂直方向移动 + if (Math.abs(currentTouches.x - startTouches.x) <= toleranceShake) { + // console.log(currentTouches.x, startTouches.x); + if (Math.abs(currentTouches.y - startTouches.y) > toleranceTranslate) { + if (currentTouches.y - startTouches.y > 0) { + return 'down' + } else if (currentTouches.y - startTouches.y < 0) { + return 'up' + } + } + } + } + return '' +} + +// swiperItem参数数据更新 +var itemDataObserver = function(newVal, oldVal, ownerInstance, instance) { + if (!newVal || newVal === 'undefined') return + var state = ownerInstance.getState() + state.itemData = newVal +} + +// swiperIndex数据更新 +var currentIndexObserver = function(newVal, oldVal, ownerInstance, instance) { + if ((!newVal && newVal != 0) || newVal === 'undefined') return + var state = ownerInstance.getState() + state.currentIndex = newVal +} + +// containerData数据更新 +var containerDataObserver = function(newVal, oldVal, ownerInstance, instance) { + if (!newVal || newVal === 'undefined') return + var state = ownerInstance.getState() + state.containerData = newVal +} + +// 开始触摸 +var touchStart = function(event, ownerInstance) { + console.log('touchStart'); + var instance = event.instance + var dataset = instance.getDataset() + var state = ownerInstance.getState() + var itemData = state.itemData + var containerData = state.containerData + + // 由于当前SwiperIndex初始为0,可能会导致swiperIndex数据没有更新 + if (!state.currentIndex || state.currentIndex === 'undefined') { + state.currentIndex = 0 + } + + if (!containerData || containerData.circular === 'undefined') { + containerData.circular = false + } + state.containerData = containerData + + // 如果当前切换动画还没执行结束,再次触摸会重新加载对应的swiperContainer的信息 + // console.log(containerData.animationFinish); + if (!containerData.animationFinish) { + ownerInstance.callMethod('changeParentSwiperContainerStyleStatus',{ + status: 'reload' + }) + } + + // 判断是否为为当前显示的SwiperItem + if (itemData.index != state.currentIndex) return + + var touches = event.changedTouches[0] + if (!touches) return + + // 标记滑动开始时间 + state.touchStartTime = getDate().getTime() + + // 记录当前滑动开始的x,y坐标 + state.touchRelactive = { + x: touches.pageX, + y: touches.pageY + } + // 记录触摸id,用于处理多指的情况 + state.touchId = touches.identifier + + // 标记开始触摸 + state.touching = true + ownerInstance.callMethod('updateTouchingStatus', { + status: true + }) +} + +// 正在移动 +var touchMove = function(event, ownerInstance) { + console.log('touchMove'); + var instance = event.instance + var dataset = instance.getDataset() + var state = ownerInstance.getState() + var itemData = state.itemData + var containerData = state.containerData + + // 判断是否为为当前显示的SwiperItem + if (itemData.index != state.currentIndex) return + + // 判断是否开始触摸 + if (!state.touching) return + + var touches = event.changedTouches[0] + if (!touches) return + // 判断是否为同一个触摸点 + if (state.touchId != touches.identifier) return + + var currentTouchRelactive = { + x: touches.pageX, + y: touches.pageY + } + + // 计算相对位移比例 + if (containerData.vertical) { + var touchDistance = currentTouchRelactive.y - state.touchRelactive.y + var itemHeight = itemData.itemHeight + var distanceRate = touchDistance / itemHeight + // console.log(currentTouchRelactive.y, touchDistance, itemHeight, distanceRate); + + // 判断是否为衔接轮播,如果不是衔接轮播,如果当前为第一个swiperItem并且向下滑、当前为最后一个swiperItem并且向上滑时不进行操作 + if (!containerData.circular && + ((state.currentIndex === 0 && touchDistance > 0) || (state.currentIndex === containerData.swiperItemLength - 1 && touchDistance < 0)) + ) { + return + } + + // 如果超出了距离则不进行操作 + if((Math.abs(touchDistance) > (itemData.itemTop + itemData.itemHeight))) { + ownerInstance.callMethod('updateParentSwiperContainerStyle', { + value: distanceRate < 0 ? -1 : 1 + }) + return + } + } else { + var touchDistance = currentTouchRelactive.x - state.touchRelactive.x + var itemWidth = itemData.itemWidth + var distanceRate = touchDistance / itemWidth + // console.log(currentTouchRelactive.x, touchDistance, itemWidth, distanceRate); + + // 判断是否为衔接轮播,如果不是衔接轮播,如果当前为第一个swiperItem并且向右滑、当前为最后一个swiperItem并且向左滑时不进行操作 + if (!containerData.circular && + ((state.currentIndex === 0 && touchDistance > 0) || (state.currentIndex === containerData.swiperItemLength - 1 && touchDistance < 0)) + ) { + return + } + + // 如果超出了距离则不进行操作 + if((Math.abs(touchDistance) > (itemData.itemLeft + itemData.itemWidth))) { + ownerInstance.callMethod('updateParentSwiperContainerStyle', { + value: distanceRate < 0 ? -1 : 1 + }) + return + } + } + + ownerInstance.callMethod('updateParentSwiperContainerStyle', { + value: distanceRate + }) +} + +// 移动结束 +var touchEnd = function(event, ownerInstance) { + console.log('touchEnd'); + var instance = event.instance + var dataset = instance.getDataset() + var state = ownerInstance.getState() + var itemData = state.itemData + var containerData = state.containerData + + // 判断是否为为当前显示的SwiperItem + if (itemData.index != state.currentIndex) return + + // 判断是否开始触摸 + if (!state.touching) return + + var touches = event.changedTouches[0] + if (!touches) return + // 判断是否为同一个触摸点 + if (state.touchId != touches.identifier) return + + + var currentTime = getDate().getTime() + var currentTouchRelactive = { + x: touches.pageX, + y: touches.pageY + } + + if (containerData.vertical) { + // 判断触摸移动方向 + var direction = decideSwiperDirection(state.touchRelactive, currentTouchRelactive, true) + // 判断是否为衔接轮播,如果不是衔接轮播,如果当前为第一个swiperItem并且向下滑、当前为最后一个swiperItem并且向上滑时不进行操作 + if (containerData.circular || + !((state.currentIndex === 0 && direction === 'down') || (state.currentIndex === containerData.swiperItemLength - 1 && direction === 'up')) + ) { + // 判断触摸的时间和移动的距离是否超过了当前itemHeight的一半,如果是则执行切换操作 + // console.log(currentTime - state.touchStartTime, Math.abs(currentTouchRelactive.y - state.touchRelactive.y)); + if ((currentTime - state.touchStartTime) > 200 && Math.abs(currentTouchRelactive.y - state.touchRelactive.y) < itemData.itemHeight / 2) { + ownerInstance.callMethod('changeParentSwiperContainerStyleStatus',{ + status: 'reset' + }) + } else { + // console.log(direction, state.touchRelactive.y, currentTouchRelactive.y); + + ownerInstance.callMethod('updateParentSwiperContainerStyleWithDirection', { + direction: direction + }) + } + } + } else { + // 判断触摸移动方向 + var direction = decideSwiperDirection(state.touchRelactive, currentTouchRelactive, false) + // 判断是否为衔接轮播,如果不是衔接轮播,如果当前为第一个swiperItem并且向右滑、当前为最后一个swiperItem并且向左滑时不进行操作 + if (containerData.circular || + !((state.currentIndex === 0 && direction === 'right') || (state.currentIndex === containerData.swiperItemLength - 1 && direction === 'left')) + ) { + // 判断触摸的时间和移动的距离是否超过了当前itemWidth的一半,如果是则执行切换操作 + // console.log(currentTime - state.touchStartTime, Math.abs(currentTouchRelactive.x - state.touchRelactive.x)); + if ((currentTime - state.touchStartTime) > 200 && Math.abs(currentTouchRelactive.x - state.touchRelactive.x) < itemData.itemWidth / 2) { + ownerInstance.callMethod('changeParentSwiperContainerStyleStatus',{ + status: 'reset' + }) + } else { + // console.log(direction, state.touchRelactive.x, currentTouchRelactive.x); + + ownerInstance.callMethod('updateParentSwiperContainerStyleWithDirection', { + direction: direction + }) + } + } + } + + // 清除标记 + state.touchId = null + state.touchRelactive = null + state.touchStartTime = 0 + + + // 标记停止触摸 + state.touching = true + ownerInstance.callMethod('updateTouchingStatus', { + status: false + }) +} + +module.exports = { + itemDataObserver: itemDataObserver, + currentIndexObserver: currentIndexObserver, + containerDataObserver: containerDataObserver, + touchStart: touchStart, + touchMove: touchMove, + touchEnd: touchEnd +} \ No newline at end of file diff --git a/tuniao-ui/components/tn-custom-swiper-item/tn-custom-swiper-item.vue b/tuniao-ui/components/tn-custom-swiper-item/tn-custom-swiper-item.vue new file mode 100644 index 0000000..5fd3c5b --- /dev/null +++ b/tuniao-ui/components/tn-custom-swiper-item/tn-custom-swiper-item.vue @@ -0,0 +1,277 @@ + + + + + + diff --git a/tuniao-ui/components/tn-custom-swiper/tn-custom-swiper.vue b/tuniao-ui/components/tn-custom-swiper/tn-custom-swiper.vue new file mode 100644 index 0000000..2094fe6 --- /dev/null +++ b/tuniao-ui/components/tn-custom-swiper/tn-custom-swiper.vue @@ -0,0 +1,535 @@ + + + + + diff --git a/tuniao-ui/components/tn-drag/index.wxs b/tuniao-ui/components/tn-drag/index.wxs new file mode 100644 index 0000000..6df1e84 --- /dev/null +++ b/tuniao-ui/components/tn-drag/index.wxs @@ -0,0 +1,265 @@ +// 判断是否出界 +var isOutRange = function(x1, y1, x2, y2, x3, y3) { + return x1 < 0 || x1 >= y1 || x2 < 0 || x2 >= y2 || x3 < 0 || x3 >= y3 +} +var edit = false + +function bool(str) { + return str === 'true' || str === true +} +/** + * 排序核心 + * @param {Object} startKey 开始时位置 + * @param {Object} endKey 结束时位置 + * @param {Object} instance wxs内的局部变量快照 + */ +var sortCore = function(startKey, endKey, state) { + var basedata = state.basedata + var excludeFix = function(sortKey, type) { + // fixed 元素位置不会变化, 这里直接用 sortKey 获取,更加便捷 + if (state.list[sortKey].fixed) { + var _sortKey = type ? --sortKey : ++sortKey + return excludeFix(sortKey, type) + } + return sortKey + } + + // 先获取到 endKey 对应的 realKey, 防止下面排序过程中该 realKey 被修改 + var endRealKey = -1 + state.list.forEach(function(item) { + if (item.sortKey === endKey) endRealKey = item.realKey + }) + + return state.list.map(function(item) { + if (item.fixed) return item + var sortKey = item.sortKey + var realKey = item.realKey + + if (startKey < endKey) { + // 正序拖动 + if (sortKey > startKey && sortKey <= endKey) { + --realKey + sortKey = excludeFix(--sortKey, true) + } else if (sortKey === startKey) { + realKey = endRealKey + sortKey = endKey + } + } else if (startKey > endKey) { + // 倒序拖动 + if (sortKey >= endKey && sortKey < startKey) { + ++realKey + sortKey = excludeFix(++sortKey, false) + } else if (sortKey === startKey) { + realKey = endRealKey + sortKey = endKey + } + } + + if (item.sortKey != sortKey) { + item.translateX = (sortKey % basedata.columns) * 100 + '%' + item.translateY = Math.floor(sortKey / basedata.columns) * 100 + '%' + item.sortKey = sortKey + item.realKey = realKey + } + return item + }) +} + +var triggerCustomEvent = function(list, type, instance) { + if (!instance) return + var _list = [], + listData = []; + + list.forEach(function(item) { + _list[item.sortKey] = item + }) + _list.forEach(function(item) { + listData.push(item.data) + }) + + // 编译到小程序 funcName作为参数传递导致事件不执行 + switch(type) { + case 'change': + instance.callMethod('change', {data: listData}) + break + case 'sortEnd': + instance.callMethod('sortEnd', {data: listData}) + break + } +} + +var listObserver = function(newVal, oldVal, ownerInstance, instance) { + var state = ownerInstance.getState() + state.itemsInstance = ownerInstance.selectAllComponents('.tn-drag__item') + + state.list = newVal || [] + + state.list.forEach(function(item, index) { + var itemInstance = state.itemsInstance[index] + if (item && itemInstance) { + itemInstance.setStyle({ + 'transform': 'translate3d('+ item.translateX + ',' + item.translateY +', 0)' + }) + if (item.fixed) itemInstance.addClass('tn-drag__fixed') + } + }) +} + +var baseDataObserver = function(newVal, oldVal, ownerInstance, instance) { + var state = ownerInstance.getState() + state.basedata = newVal +} + +var longPress = function(event, ownerInstance) { + var instance = event.instance + var dataset = instance.getDataset() + var state = ownerInstance.getState() + + edit = bool(dataset.edit) + if (!edit) return + if (!state.basedata || state.basedata === 'undefined') { + state.basedata = JSON.parse(dataset.basedata) + } + var basedata = state.basedata + var touches = event.changedTouches[0] + if (!touches) return + + state.current = +dataset.index + + // 初始项是固定项则返回 + var item = state.list[state.current] + if (item && item.fixed) return + + // 如果已经在 drag 中则返回, 防止多指触发 drag 动作, touchstart 事件中有效果 + if (state.dragging) return + + ownerInstance.callMethod("drag", { + dragging: true + }) + + // 计算X, Y轴初始位移,使item中心移动到点击处,单列的时候X轴初始不做位移 + state.translateX = basedata.columns === 1 ? 0 : touches.pageX - (basedata.itemWidth / 2 + basedata.left) + state.translateY = touches.pageY - (basedata.itemHeight / 2 + basedata.top) + state.touchId = touches.identifier + + instance.setStyle({ + 'transform': 'translate3d(' + state.translateX + 'px,' + state.translateY +'px, 0)' + }) + state.itemsInstance.forEach(function(item, index) { + item.removeClass("tn-drag__transition").removeClass("tn-drag__current") + item.addClass(index === state.current ? "tn-drag__current" : "tn-drag__transition") + }) + + ownerInstance.callMethod("vibrate") + state.dragging = true +} + +var touchStart = function(event, ownerInstance) { + var instance = event.instance + var dataset = instance.getDataset() + edit = bool(dataset.edit) +} + +var touchMove = function(event, ownerInstance) { + var instance = event.instance + var dataset = instance.getDataset() + var state = ownerInstance.getState() + var basedata = state.basedata + + if (!state.dragging || !edit) return + var touches = event.changedTouches[0] + if (!touches) return + + // 如果不是同一个触发点则返回 + if (state.touchId !== touches.identifier) return + + // 计算X,Y轴位移, 单列时候X轴初始不做位移 + var translateX = basedata.columns === 1 ? 0 : touches.pageX - (basedata.itemWidth / 2 + basedata.left) + var translateY = touches.pageY - (basedata.itemHeight / 2 + basedata.top) + + // 到顶到低自动滑动 + if (touches.clientY > basedata.windowHeight - basedata.itemHeight - basedata.realBottomSize) { + // 当前触摸点pageY + item高度 - (屏幕高度 - 底部固定区域高度) + ownerInstance.callMethod('pageScroll', { + scrollTop: touches.pageY + basedata.itemHeight - (basedata.windowHeight - basedata.realBottomSize) + }) + } else if (touches.clientY < basedata.itemHeight + basedata.realTopSize) { + // 当前触摸点pageY - item高度 - 顶部固定区域高 + ownerInstance.callMethod('pageScroll', { + scrollTop: touches.pageY - basedata.itemHeight - basedata.realTopSize + }) + } + + // 设置当前激活元素的偏移量 + instance.setStyle({ + 'transform': 'translate3d('+ translateX + 'px,' + translateY + 'px, 0)' + }) + + var startKey = state.list[state.current].sortKey + var currentX = Math.round(translateX / basedata.itemWidth) + var currentY = Math.round(translateY / basedata.itemHeight) + var endKey = currentX + basedata.columns * currentY + + // 目标项时固定项则返回 + var item = state.list[endKey] + if (item && item.fixed) return + + // X轴或者Y轴超出范围则返回 + if (isOutRange(currentX, basedata.columns, currentY, basedata.rows, endKey, state.list.length)) return + + // 防止拖拽过程中发生乱序问题 + if (startKey === endKey || startKey === state.preStartKey) return + state.preStartKey = startKey + + var list = sortCore(startKey, endKey, state) + state.itemsInstance.forEach(function(itemInstance, index) { + var item = list[index] + if (index !== state.current) { + itemInstance.setStyle({ + 'transform': 'translate3d('+ item.translateX + ',' + item.translateY +', 0)' + }) + } + }) + + // ownerInstance.callMethod('vibrate') + ownerInstance.callMethod('listDataChange', { + data: list + }) + triggerCustomEvent(list, "change", ownerInstance) +} + +var touchEnd = function(event, ownerInstance) { + var instance = event.instance + var dataset = instance.getDataset() + var state = ownerInstance.getState() + var basedata = state.basedata + + if (!state.dragging || !edit) return + triggerCustomEvent(state.list, "sortEnd", ownerInstance) + + instance.addClass('tn-drag__transition') + instance.setStyle({ + 'transform': 'translate3d('+ state.list[state.current].translateX + ',' + state.list[state.current].translateY + ', 0)' + }) + state.itemsInstance.forEach(function(item, index) { + item.removeClass('tn-drag__transition') + }) + + state.preStartKey = -1 + state.dragging = false + ownerInstance.callMethod('drag', { + dragging: false + }) + state.current = -1 + state.translateX = 0 + state.translateY = 0 +} + +module.exports = { + longPress: longPress, + touchStart: touchStart, + touchMove: touchMove, + touchEnd: touchEnd, + baseDataObserver: baseDataObserver, + listObserver: listObserver +} \ No newline at end of file diff --git a/tuniao-ui/components/tn-drag/tn-drag.vue b/tuniao-ui/components/tn-drag/tn-drag.vue new file mode 100644 index 0000000..17d269d --- /dev/null +++ b/tuniao-ui/components/tn-drag/tn-drag.vue @@ -0,0 +1,278 @@ + + + + + diff --git a/tuniao-ui/components/tn-empty/tn-empty.vue b/tuniao-ui/components/tn-empty/tn-empty.vue new file mode 100644 index 0000000..3a85b15 --- /dev/null +++ b/tuniao-ui/components/tn-empty/tn-empty.vue @@ -0,0 +1,190 @@ + + + + + diff --git a/tuniao-ui/components/tn-fab/tn-fab.vue b/tuniao-ui/components/tn-fab/tn-fab.vue new file mode 100644 index 0000000..6b867e9 --- /dev/null +++ b/tuniao-ui/components/tn-fab/tn-fab.vue @@ -0,0 +1,523 @@ + + + + + diff --git a/tuniao-ui/components/tn-form-item/tn-form-item.vue b/tuniao-ui/components/tn-form-item/tn-form-item.vue new file mode 100644 index 0000000..9e9725c --- /dev/null +++ b/tuniao-ui/components/tn-form-item/tn-form-item.vue @@ -0,0 +1,457 @@ + + + + + diff --git a/tuniao-ui/components/tn-form/tn-form.vue b/tuniao-ui/components/tn-form/tn-form.vue new file mode 100644 index 0000000..f0ebf19 --- /dev/null +++ b/tuniao-ui/components/tn-form/tn-form.vue @@ -0,0 +1,139 @@ + + + + + diff --git a/tuniao-ui/components/tn-goods-nav/tn-goods-nav.vue b/tuniao-ui/components/tn-goods-nav/tn-goods-nav.vue new file mode 100644 index 0000000..bf577cf --- /dev/null +++ b/tuniao-ui/components/tn-goods-nav/tn-goods-nav.vue @@ -0,0 +1,382 @@ + + + + + diff --git a/tuniao-ui/components/tn-grid-item/tn-grid-item.vue b/tuniao-ui/components/tn-grid-item/tn-grid-item.vue new file mode 100644 index 0000000..2837bc2 --- /dev/null +++ b/tuniao-ui/components/tn-grid-item/tn-grid-item.vue @@ -0,0 +1,114 @@ + + + + + diff --git a/tuniao-ui/components/tn-grid/tn-grid.vue b/tuniao-ui/components/tn-grid/tn-grid.vue new file mode 100644 index 0000000..f5487c6 --- /dev/null +++ b/tuniao-ui/components/tn-grid/tn-grid.vue @@ -0,0 +1,111 @@ + + + + + diff --git a/tuniao-ui/components/tn-image-upload-drag/tn-image-upload-drag.vue b/tuniao-ui/components/tn-image-upload-drag/tn-image-upload-drag.vue new file mode 100644 index 0000000..05b4b25 --- /dev/null +++ b/tuniao-ui/components/tn-image-upload-drag/tn-image-upload-drag.vue @@ -0,0 +1,1011 @@ + + + + + diff --git a/tuniao-ui/components/tn-image-upload/tn-image-upload.vue b/tuniao-ui/components/tn-image-upload/tn-image-upload.vue new file mode 100644 index 0000000..f9d7d8c --- /dev/null +++ b/tuniao-ui/components/tn-image-upload/tn-image-upload.vue @@ -0,0 +1,645 @@ + + + + + diff --git a/tuniao-ui/components/tn-index-anchor/tn-index-anchor.vue b/tuniao-ui/components/tn-index-anchor/tn-index-anchor.vue new file mode 100644 index 0000000..97bef6e --- /dev/null +++ b/tuniao-ui/components/tn-index-anchor/tn-index-anchor.vue @@ -0,0 +1,90 @@ + + + + + diff --git a/tuniao-ui/components/tn-index-list/tn-index-list.vue b/tuniao-ui/components/tn-index-list/tn-index-list.vue new file mode 100644 index 0000000..91fc639 --- /dev/null +++ b/tuniao-ui/components/tn-index-list/tn-index-list.vue @@ -0,0 +1,361 @@ + + + + + diff --git a/tuniao-ui/components/tn-input/tn-input.vue b/tuniao-ui/components/tn-input/tn-input.vue new file mode 100644 index 0000000..902bb91 --- /dev/null +++ b/tuniao-ui/components/tn-input/tn-input.vue @@ -0,0 +1,427 @@ +