diff --git a/components/qk/qk-send-sms-code/qk-send-sms-code.vue b/components/qk/qk-send-sms-code/qk-send-sms-code.vue new file mode 100644 index 0000000..385d707 --- /dev/null +++ b/components/qk/qk-send-sms-code/qk-send-sms-code.vue @@ -0,0 +1,130 @@ + + + + + diff --git a/components/qk/qk-statusbar-block/qk-statusbar-block.vue b/components/qk/qk-statusbar-block/qk-statusbar-block.vue new file mode 100644 index 0000000..f5b8142 --- /dev/null +++ b/components/qk/qk-statusbar-block/qk-statusbar-block.vue @@ -0,0 +1,20 @@ + + + + + diff --git a/components/thorui/tui-actionsheet/tui-actionsheet.vue b/components/thorui/tui-actionsheet/tui-actionsheet.vue new file mode 100644 index 0000000..a21427a --- /dev/null +++ b/components/thorui/tui-actionsheet/tui-actionsheet.vue @@ -0,0 +1,186 @@ + + + + + diff --git a/components/thorui/tui-alert/tui-alert.vue b/components/thorui/tui-alert/tui-alert.vue new file mode 100644 index 0000000..adb7b9e --- /dev/null +++ b/components/thorui/tui-alert/tui-alert.vue @@ -0,0 +1,134 @@ + + + + + diff --git a/components/thorui/tui-badge/tui-badge.vue b/components/thorui/tui-badge/tui-badge.vue new file mode 100644 index 0000000..208aaa6 --- /dev/null +++ b/components/thorui/tui-badge/tui-badge.vue @@ -0,0 +1,155 @@ + + + + + diff --git a/components/thorui/tui-bottom-navigation/tui-bottom-navigation.vue b/components/thorui/tui-bottom-navigation/tui-bottom-navigation.vue new file mode 100644 index 0000000..b676c3f --- /dev/null +++ b/components/thorui/tui-bottom-navigation/tui-bottom-navigation.vue @@ -0,0 +1,387 @@ + + + + + diff --git a/components/thorui/tui-bottom-popup/tui-bottom-popup.vue b/components/thorui/tui-bottom-popup/tui-bottom-popup.vue new file mode 100644 index 0000000..a8fb45c --- /dev/null +++ b/components/thorui/tui-bottom-popup/tui-bottom-popup.vue @@ -0,0 +1,106 @@ + + + + + diff --git a/components/thorui/tui-bubble-popup/tui-bubble-popup.vue b/components/thorui/tui-bubble-popup/tui-bubble-popup.vue new file mode 100644 index 0000000..a8991e7 --- /dev/null +++ b/components/thorui/tui-bubble-popup/tui-bubble-popup.vue @@ -0,0 +1,203 @@ + + + + diff --git a/components/thorui/tui-button/tui-button.vue b/components/thorui/tui-button/tui-button.vue new file mode 100644 index 0000000..03cf517 --- /dev/null +++ b/components/thorui/tui-button/tui-button.vue @@ -0,0 +1,519 @@ + + + + + diff --git a/components/thorui/tui-calendar/tui-calendar.js b/components/thorui/tui-calendar/tui-calendar.js new file mode 100644 index 0000000..8d10e6d --- /dev/null +++ b/components/thorui/tui-calendar/tui-calendar.js @@ -0,0 +1,562 @@ +/** + * @1900-2100区间内的公历、农历互转 + * @公历转农历:solar2lunar(1987,11,01); + * @农历转公历:lunar2solar(1987,09,10); + */ +let calendar = { + /** + * 农历1900-2100的润大小信息表 + * @Array Of Property + * @return Hex + */ + lunarInfo: [0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, //1900-1909 + 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, //1910-1919 + 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, //1920-1929 + 0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, //1930-1939 + 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, //1940-1949 + 0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, //1950-1959 + 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, //1960-1969 + 0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, //1970-1979 + 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, //1980-1989 + 0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0, //1990-1999 + 0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, //2000-2009 + 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, //2010-2019 + 0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, //2020-2029 + 0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, //2030-2039 + 0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, //2040-2049 + 0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0, //2050-2059 + 0x0a2e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, //2060-2069 + 0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, //2070-2079 + 0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, //2080-2089 + 0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, //2090-2099 + 0x0d520 + ], //2100 + /** + * 公历每个月份的天数普通表 + * @Array Of Property + * @return Number + */ + solarMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], + /** + * 天干地支之天干速查表 + * @Array Of Property trans["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"] + * @return Cn string + */ + Gan: ["\u7532", "\u4e59", "\u4e19", "\u4e01", "\u620a", "\u5df1", "\u5e9a", "\u8f9b", "\u58ec", "\u7678"], + /** + * 天干地支之地支速查表 + * @Array Of Property + * @trans["子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"] + * @return Cn string + */ + Zhi: ["\u5b50", "\u4e11", "\u5bc5", "\u536f", "\u8fb0", "\u5df3", "\u5348", "\u672a", "\u7533", "\u9149", "\u620c", + "\u4ea5" + ], + /** + * 天干地支之地支速查表<=>生肖 + * @Array Of Property + * @trans["鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"] + * @return Cn string + */ + Animals: ["\u9f20", "\u725b", "\u864e", "\u5154", "\u9f99", "\u86c7", "\u9a6c", "\u7f8a", "\u7334", "\u9e21", + "\u72d7", "\u732a" + ], + /** + * 24节气速查表 + * @Array Of Property + * @trans["小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至"] + * @return Cn string + */ + solarTerm: ["\u5c0f\u5bd2", "\u5927\u5bd2", "\u7acb\u6625", "\u96e8\u6c34", "\u60ca\u86f0", "\u6625\u5206", + "\u6e05\u660e", "\u8c37\u96e8", "\u7acb\u590f", "\u5c0f\u6ee1", "\u8292\u79cd", "\u590f\u81f3", "\u5c0f\u6691", + "\u5927\u6691", "\u7acb\u79cb", "\u5904\u6691", "\u767d\u9732", "\u79cb\u5206", "\u5bd2\u9732", "\u971c\u964d", + "\u7acb\u51ac", "\u5c0f\u96ea", "\u5927\u96ea", "\u51ac\u81f3" + ], + /** + * 1900-2100各年的24节气日期速查表 + * @Array Of Property + * @return 0x string For splice + */ + sTermInfo: ['9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', + '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', + '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', + '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', + 'b027097bd097c36b0b6fc9274c91aa', '9778397bd19801ec9210c965cc920e', '97b6b97bd19801ec95f8c965cc920f', + '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd197c36c9210c9274c91aa', + '97b6b97bd19801ec95f8c965cc920e', '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', + '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec95f8c965cc920e', '97bcf97c3598082c95f8e1cfcc920f', + '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e', + '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', + '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', + '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', + '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', + '97bcf97c359801ec95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', + '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd097bd07f595b0b6fc920fb0722', + '9778397bd097c36b0b6fc9210c8dc2', '9778397bd19801ec9210c9274c920e', '97b6b97bd19801ec95f8c965cc920f', + '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e', + '97b6b97bd19801ec95f8c965cc920f', '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', + '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bd07f1487f595b0b0bc920fb0722', + '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', + '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', + '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', + '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f531b0b0bb0b6fb0722', + '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', + '97bcf7f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', + '97b6b97bd19801ec9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', + '9778397bd097c36b0b6fc9210c91aa', '97b6b97bd197c36c9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722', + '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e', + '97b6b7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', + '9778397bd097c36b0b70c9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722', + '7f0e397bd097c35b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', + '7f0e27f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', + '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', + '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', + '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', + '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9274c91aa', + '97b6b7f0e47f531b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', + '9778397bd097c36b0b6fc9210c91aa', '97b6b7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', + '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '977837f0e37f149b0723b0787b0721', + '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c35b0b6fc9210c8dc2', + '977837f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722', + '7f0e397bd097c35b0b6fc9210c8dc2', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', + '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '977837f0e37f14998082b0787b06bd', + '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', + '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', + '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', + '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd', + '7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', + '977837f0e37f14998082b0723b06bd', '7f07e7f0e37f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', + '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b0721', + '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f595b0b0bb0b6fb0722', '7f0e37f0e37f14898082b0723b02d5', + '7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f531b0b0bb0b6fb0722', + '7f0e37f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', + '7f0e37f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd', + '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35', + '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', + '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f149b0723b0787b0721', + '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0723b06bd', + '7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', '7f0e37f0e366aa89801eb072297c35', + '7ec967f0e37f14998082b0723b06bd', '7f07e7f0e37f14998083b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', + '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14898082b0723b02d5', '7f07e7f0e37f14998082b0787b0721', + '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66aa89801e9808297c35', '665f67f0e37f14898082b0723b02d5', + '7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66a449801e9808297c35', + '665f67f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', + '7f0e36665b66a449801e9808297c35', '665f67f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd', + '7f07e7f0e47f531b0723b0b6fb0721', '7f0e26665b66a449801e9808297c35', '665f67f0e37f1489801eb072297c35', + '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722' + ], + /** + * 数字转中文速查表 + * @Array Of Property + * @trans ['日','一','二','三','四','五','六','七','八','九','十'] + * @return Cn string + */ + nStr1: ["\u65e5", "\u4e00", "\u4e8c", "\u4e09", "\u56db", "\u4e94", "\u516d", "\u4e03", "\u516b", "\u4e5d", "\u5341"], + /** + * 日期转农历称呼速查表 + * @Array Of Property + * @trans ['初','十','廿','卅'] + * @return Cn string + */ + nStr2: ["\u521d", "\u5341", "\u5eff", "\u5345"], + /** + * 月份转农历称呼速查表 + * @Array Of Property + * @trans ['正','一','二','三','四','五','六','七','八','九','十','冬','腊'] + * @return Cn string + */ + nStr3: ["\u6b63", "\u4e8c", "\u4e09", "\u56db", "\u4e94", "\u516d", "\u4e03", "\u516b", "\u4e5d", "\u5341", "\u51ac", + "\u814a" + ], + /** + * 返回农历y年一整年的总天数 + * @param lunar Year + * @return Number + * @eg:let count = calendar.lYearDays(1987) ;//count=387 + */ + lYearDays: function(y) { + let i, sum = 348; + for (i = 0x8000; i > 0x8; i >>= 1) { + sum += (calendar.lunarInfo[y - 1900] & i) ? 1 : 0; + } + return (sum + calendar.leapDays(y)); + }, + /** + * 返回农历y年闰月是哪个月;若y年没有闰月 则返回0 + * @param lunar Year + * @return Number (0-12) + * @eg:let leapMonth = calendar.leapMonth(1987) ;//leapMonth=6 + */ + leapMonth: function(y) { //闰字编码 \u95f0 + return (calendar.lunarInfo[y - 1900] & 0xf); + }, + /** + * 返回农历y年闰月的天数 若该年没有闰月则返回0 + * @param lunar Year + * @return Number (0、29、30) + * @eg:let leapMonthDay = calendar.leapDays(1987) ;//leapMonthDay=29 + */ + leapDays: function(y) { + if (calendar.leapMonth(y)) { + return ((calendar.lunarInfo[y - 1900] & 0x10000) ? 30 : 29); + } + return (0); + }, + /** + * 返回农历y年m月(非闰月)的总天数,计算m为闰月时的天数请使用leapDays方法 + * @param lunar Year + * @return Number (-1、29、30) + * @eg:let MonthDay = calendar.monthDays(1987,9) ;//MonthDay=29 + */ + monthDays: function(y, m) { + if (m > 12 || m < 1) { + return -1 + } //月份参数从1至12,参数错误返回-1 + return ((calendar.lunarInfo[y - 1900] & (0x10000 >> m)) ? 30 : 29); + }, + /** + * 返回公历(!)y年m月的天数 + * @param solar Year + * @return Number (-1、28、29、30、31) + * @eg:let solarMonthDay = calendar.leapDays(1987) ;//solarMonthDay=30 + */ + solarDays: function(y, m) { + if (m > 12 || m < 1) { + return -1 + } //若参数错误 返回-1 + let ms = m - 1; + if (ms == 1) { //2月份的闰平规律测算后确认返回28或29 + return (((y % 4 == 0) && (y % 100 != 0) || (y % 400 == 0)) ? 29 : 28); + } else { + return (calendar.solarMonth[ms]); + } + }, + /** + * 农历年份转换为干支纪年 + * @param lYear 农历年的年份数 + * @return Cn string + */ + toGanZhiYear: function(lYear) { + let ganKey = (lYear - 3) % 10; + let zhiKey = (lYear - 3) % 12; + if (ganKey == 0) ganKey = 10; //如果余数为0则为最后一个天干 + if (zhiKey == 0) zhiKey = 12; //如果余数为0则为最后一个地支 + return calendar.Gan[ganKey - 1] + calendar.Zhi[zhiKey - 1]; + }, + /** + * 公历月、日判断所属星座 + * @param cMonth [description] + * @param cDay [description] + * @return Cn string + */ + toAstro: function(cMonth, cDay) { + let s = + "\u9b54\u7faf\u6c34\u74f6\u53cc\u9c7c\u767d\u7f8a\u91d1\u725b\u53cc\u5b50\u5de8\u87f9\u72ee\u5b50\u5904\u5973\u5929\u79e4\u5929\u874e\u5c04\u624b\u9b54\u7faf"; + let arr = [20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22]; + return s.substr(cMonth * 2 - (cDay < arr[cMonth - 1] ? 2 : 0), 2) + "\u5ea7"; //座 + }, + /** + * 传入offset偏移量返回干支 + * @param offset 相对甲子的偏移量 + * @return Cn string + */ + toGanZhi: function(offset) { + return calendar.Gan[offset % 10] + calendar.Zhi[offset % 12]; + }, + /** + * 传入公历(!)y年获得该年第n个节气的公历日期 + * @param y公历年(1900-2100);n二十四节气中的第几个节气(1~24);从n=1(小寒)算起 + * @return day Number + * @eg:let _24 = calendar.getTerm(1987,3) ;//_24=4;意即1987年2月4日立春 + */ + getTerm: function(y, n) { + if (y < 1900 || y > 2100) { + return -1; + } + if (n < 1 || n > 24) { + return -1; + } + let _table = calendar.sTermInfo[y - 1900]; + let _info = [ + parseInt('0x' + _table.substr(0, 5)).toString(), + parseInt('0x' + _table.substr(5, 5)).toString(), + parseInt('0x' + _table.substr(10, 5)).toString(), + parseInt('0x' + _table.substr(15, 5)).toString(), + parseInt('0x' + _table.substr(20, 5)).toString(), + parseInt('0x' + _table.substr(25, 5)).toString() + ]; + let _calday = [ + _info[0].substr(0, 1), + _info[0].substr(1, 2), + _info[0].substr(3, 1), + _info[0].substr(4, 2), + _info[1].substr(0, 1), + _info[1].substr(1, 2), + _info[1].substr(3, 1), + _info[1].substr(4, 2), + _info[2].substr(0, 1), + _info[2].substr(1, 2), + _info[2].substr(3, 1), + _info[2].substr(4, 2), + _info[3].substr(0, 1), + _info[3].substr(1, 2), + _info[3].substr(3, 1), + _info[3].substr(4, 2), + _info[4].substr(0, 1), + _info[4].substr(1, 2), + _info[4].substr(3, 1), + _info[4].substr(4, 2), + _info[5].substr(0, 1), + _info[5].substr(1, 2), + _info[5].substr(3, 1), + _info[5].substr(4, 2), + ]; + return parseInt(_calday[n - 1]); + }, + /** + * 传入农历数字月份返回汉语通俗表示法 + * @param lunar month + * @return Cn string + * @eg:let cnMonth = calendar.toChinaMonth(12) ;//cnMonth='腊月' + */ + toChinaMonth: function(m) { // 月 => \u6708 + if (m > 12 || m < 1) { + return -1 + } //若参数错误 返回-1 + let s = calendar.nStr3[m - 1]; + s += "\u6708"; //加上月字 + return s; + }, + /** + * 传入农历日期数字返回汉字表示法 + * @param lunar day + * @return Cn string + * @eg:let cnDay = calendar.toChinaDay(21) ;//cnMonth='廿一' + */ + toChinaDay: function(d) { //日 => \u65e5 + let s; + switch (d) { + case 10: + s = '\u521d\u5341'; + break; + case 20: + s = '\u4e8c\u5341'; + break; + break; + case 30: + s = '\u4e09\u5341'; + break; + break; + default: + s = calendar.nStr2[Math.floor(d / 10)]; + s += calendar.nStr1[d % 10]; + } + return (s); + }, + /** + * 年份转生肖[!仅能大致转换] => 精确划分生肖分界线是“立春” + * @param y year + * @return Cn string + * @eg:let animal = calendar.getAnimal(1987) ;//animal='兔' + */ + getAnimal: function(y) { + return calendar.Animals[(y - 4) % 12] + }, + /** + * 传入阳历年月日获得详细的公历、农历object信息 <=>JSON + * @param y solar year + * @param m solar month + * @param d solar day + * @return JSON object + * @eg:console.log(calendar.solar2lunar(1987,11,01)); + */ + solar2lunar: function(y, m, d) { //参数区间1900.1.31~2100.12.31 + if (y < 1900 || y > 2100) { + return -1; + } //年份限定、上限 + if (y == 1900 && m == 1 && d < 31) { + return -1; + } //下限 + let objDate; + if (!y) { //未传参 获得当天 + objDate = new Date(); + } else { + objDate = new Date(y, parseInt(m) - 1, d) + } + let i, leap = 0, + temp = 0; + //修正ymd参数 + y = objDate.getFullYear(); + m = objDate.getMonth() + 1; + d = objDate.getDate(); + let offset = (Date.UTC(objDate.getFullYear(), objDate.getMonth(), objDate.getDate()) - Date.UTC(1900, 0, 31)) / + 86400000; + for (i = 1900; i < 2101 && offset > 0; i++) { + temp = calendar.lYearDays(i); + offset -= temp; + } + if (offset < 0) { + offset += temp; + i--; + } + //是否今天 + let isTodayObj = new Date(), + isToday = false; + if (isTodayObj.getFullYear() == y && isTodayObj.getMonth() + 1 == m && isTodayObj.getDate() == d) { + isToday = true; + } + //星期几 + let nWeek = objDate.getDay(), + cWeek = calendar.nStr1[nWeek]; + if (nWeek == 0) { + nWeek = 7; + } //数字表示周几顺应天朝周一开始的惯例 + //农历年 + let year = i; + leap = calendar.leapMonth(i); //闰哪个月 + let isLeap = false; + //效验闰月 + for (i = 1; i < 13 && offset > 0; i++) { + //闰月 + if (leap > 0 && i == (leap + 1) && isLeap == false) { + --i; + isLeap = true; + temp = calendar.leapDays(year); //计算农历闰月天数 + } else { + temp = calendar.monthDays(year, i); //计算农历普通月天数 + } + //解除闰月 + if (isLeap == true && i == (leap + 1)) { + isLeap = false; + } + offset -= temp; + } + if (offset == 0 && leap > 0 && i == leap + 1) + if (isLeap) { + isLeap = false; + } else { + isLeap = true; + --i; + } + if (offset < 0) { + offset += temp; + --i; + } + //农历月 + let month = i; + //农历日 + let day = offset + 1; + //天干地支处理 + let sm = m - 1; + let gzY = calendar.toGanZhiYear(year); + //月柱 1900年1月小寒以前为 丙子月(60进制12) + let firstNode = calendar.getTerm(year, (m * 2 - 1)); //返回当月「节」为几日开始 + let secondNode = calendar.getTerm(year, (m * 2)); //返回当月「节」为几日开始 + //依据12节气修正干支月 + let gzM = calendar.toGanZhi((y - 1900) * 12 + m + 11); + if (d >= firstNode) { + gzM = calendar.toGanZhi((y - 1900) * 12 + m + 12); + } + //传入的日期的节气与否 + let isTerm = false; + let Term = null; + if (firstNode == d) { + isTerm = true; + Term = calendar.solarTerm[m * 2 - 2]; + } + if (secondNode == d) { + isTerm = true; + Term = calendar.solarTerm[m * 2 - 1]; + } + //日柱 当月一日与 1900/1/1 相差天数 + let dayCyclical = Date.UTC(y, sm, 1, 0, 0, 0, 0) / 86400000 + 25567 + 10; + let gzD = calendar.toGanZhi(dayCyclical + d - 1); + //该日期所属的星座 + let astro = calendar.toAstro(m, d); + return { + 'lYear': year, + 'lMonth': month, + 'lDay': day, + 'Animal': calendar.getAnimal(year), + 'IMonthCn': (isLeap ? "\u95f0" : '') + calendar.toChinaMonth(month), + 'IDayCn': calendar.toChinaDay(day), + 'cYear': y, + 'cMonth': m, + 'cDay': d, + 'gzYear': gzY, + 'gzMonth': gzM, + 'gzDay': gzD, + 'isToday': isToday, + 'isLeap': isLeap, + 'nWeek': nWeek, + 'ncWeek': "\u661f\u671f" + cWeek, + 'isTerm': isTerm, + 'Term': Term, + 'astro': astro + }; + }, + /** + * 传入农历年月日以及传入的月份是否闰月获得详细的公历、农历object信息 <=>JSON + * @param y lunar year + * @param m lunar month + * @param d lunar day + * @param isLeapMonth lunar month is leap or not.[如果是农历闰月第四个参数赋值true即可] + * @return JSON object + * @eg:console.log(calendar.lunar2solar(1987,9,10)); + */ + lunar2solar: function(y, m, d, isLeapMonth) { //参数区间1900.1.31~2100.12.1 + isLeapMonth = !!isLeapMonth; + let leapOffset = 0; + let leapMonth = calendar.leapMonth(y); + let leapDay = calendar.leapDays(y); + if (isLeapMonth && (leapMonth != m)) { + return -1; + } //传参要求计算该闰月公历 但该年得出的闰月与传参的月份并不同 + if (y == 2100 && m == 12 && d > 1 || y == 1900 && m == 1 && d < 31) { + return -1; + } //超出了最大极限值 + let day = calendar.monthDays(y, m); + let _day = day; + //bugFix 2016-9-25 + //if month is leap, _day use leapDays method + if (isLeapMonth) { + _day = calendar.leapDays(y, m); + } + if (y < 1900 || y > 2100 || d > _day) { + return -1; + } //参数合法性效验 + //计算农历的时间差 + let offset = 0; + for (let i = 1900; i < y; i++) { + offset += calendar.lYearDays(i); + } + let leap = 0, + isAdd = false; + for (let i = 1; i < m; i++) { + leap = calendar.leapMonth(y); + if (!isAdd) { //处理闰月 + if (leap <= i && leap > 0) { + offset += calendar.leapDays(y); + isAdd = true; + } + } + offset += calendar.monthDays(y, i); + } + //转换闰月农历 需补充该年闰月的前一个月的时差 + if (isLeapMonth) { + offset += day; + } + //1900年农历正月一日的公历时间为1900年1月30日0时0分0秒(该时间也是本农历的最开始起始点) + let stmap = Date.UTC(1900, 1, 30, 0, 0, 0); + let calObj = new Date((offset + d - 31) * 86400000 + stmap); + let cY = calObj.getUTCFullYear(); + let cM = calObj.getUTCMonth() + 1; + let cD = calObj.getUTCDate(); + return calendar.solar2lunar(cY, cM, cD); + } +}; + +module.exports = { + solar2lunar: calendar.solar2lunar, + lunar2solar: calendar.lunar2solar +}; diff --git a/components/thorui/tui-calendar/tui-calendar.vue b/components/thorui/tui-calendar/tui-calendar.vue new file mode 100644 index 0000000..8d4eee0 --- /dev/null +++ b/components/thorui/tui-calendar/tui-calendar.vue @@ -0,0 +1,925 @@ + + + + diff --git a/components/thorui/tui-card/tui-card.vue b/components/thorui/tui-card/tui-card.vue new file mode 100644 index 0000000..7214b33 --- /dev/null +++ b/components/thorui/tui-card/tui-card.vue @@ -0,0 +1,211 @@ + + + + + diff --git a/components/thorui/tui-cascade-selection/tui-cascade-selection.vue b/components/thorui/tui-cascade-selection/tui-cascade-selection.vue new file mode 100644 index 0000000..69729c5 --- /dev/null +++ b/components/thorui/tui-cascade-selection/tui-cascade-selection.vue @@ -0,0 +1,521 @@ + + + + + diff --git a/components/thorui/tui-circular-progress/tui-circular-progress.vue b/components/thorui/tui-circular-progress/tui-circular-progress.vue new file mode 100644 index 0000000..19ab3ec --- /dev/null +++ b/components/thorui/tui-circular-progress/tui-circular-progress.vue @@ -0,0 +1,264 @@ + + + + + \ No newline at end of file diff --git a/components/thorui/tui-collapse/tui-collapse.vue b/components/thorui/tui-collapse/tui-collapse.vue new file mode 100644 index 0000000..a812a2a --- /dev/null +++ b/components/thorui/tui-collapse/tui-collapse.vue @@ -0,0 +1,166 @@ + + + + + diff --git a/components/thorui/tui-countdown-verify/tui-countdown-verify.vue b/components/thorui/tui-countdown-verify/tui-countdown-verify.vue new file mode 100644 index 0000000..695e99c --- /dev/null +++ b/components/thorui/tui-countdown-verify/tui-countdown-verify.vue @@ -0,0 +1,226 @@ + + + + + diff --git a/components/thorui/tui-countdown/tui-countdown.vue b/components/thorui/tui-countdown/tui-countdown.vue new file mode 100644 index 0000000..acdd0ba --- /dev/null +++ b/components/thorui/tui-countdown/tui-countdown.vue @@ -0,0 +1,335 @@ + + + + + diff --git a/components/thorui/tui-cropper-app/tui-cropper-app.vue b/components/thorui/tui-cropper-app/tui-cropper-app.vue new file mode 100644 index 0000000..e5fcd4c --- /dev/null +++ b/components/thorui/tui-cropper-app/tui-cropper-app.vue @@ -0,0 +1,780 @@ + + + + + diff --git a/components/thorui/tui-cropper-app/tui-cropper-app.wxs b/components/thorui/tui-cropper-app/tui-cropper-app.wxs new file mode 100644 index 0000000..7d7c119 --- /dev/null +++ b/components/thorui/tui-cropper-app/tui-cropper-app.wxs @@ -0,0 +1,560 @@ +var cropper = { + CUT_START: null, + cutX: 0, //画布x轴起点 + cutY: 0, //画布y轴起点0 + touchRelative: [{ + x: 0, + y: 0 + }], //手指或鼠标和图片中心的相对位置 + flagCutTouch: false, //是否是拖动裁剪框 + hypotenuseLength: 0, //双指触摸时斜边长度 + flagEndTouch: false, //是否结束触摸 + canvasWidth: 0, + canvasHeight: 0, + imgWidth: 0, //图片宽度 + imgHeight: 0, //图片高度 + scale: 1, //图片缩放比 + angle: 0, //图片旋转角度 + imgTop: 0, //图片上边距 + imgLeft: 0, //图片左边距 + //是否限制移动范围(剪裁框只能在图片内,为true不可触摸转动图片) + limitMove: true, + minHeight: 0, + maxHeight: 0, + minWidth: 0, + maxWidth: 0, + windowHeight: 0, + windowWidth: 0, + init: true +} + +function bool(str) { + return str === 'true' || str == true ? true : false +} + +function touchstart(e, ins) { + //var instance = e.instance; + // var state = instance.getState(); + var touch = e.touches || e.changedTouches; + cropper.flagEndTouch = false; + if (touch.length == 1) { + cropper.touchRelative[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.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.hypotenuseLength = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)); + } + +} + +function moveDuring(ins) { + if (!ins) return; + ins.callMethod('moveDuring') +} + +function moveStop(ins) { + if (!ins) return; + ins.callMethod('moveStop') +}; + +function setCutCenter(ins) { + var cutY = (cropper.windowHeight - cropper.canvasHeight) * 0.5; + var cutX = (cropper.windowWidth - cropper.canvasWidth) * 0.5; + //顺序不能变 + cropper.imgTop = cropper.imgTop - cropper.cutY + cutY; + cropper.cutY = cutY; //截取的框上边距 + cropper.imgLeft = cropper.imgLeft - cropper.cutX + cutX; + cropper.cutX = cutX; //截取的框左边距 + styleUpdate(ins) + cutDetectionPosition(ins) + imgTransform(ins) + updateData(ins) +} + +function touchmove(e, ins) { + var touch = e.touches || e.changedTouches; + if (cropper.flagEndTouch) return; + moveDuring(ins); + if (e.touches.length == 1) { + var left = touch[0].pageX - cropper.touchRelative[0].x, + top = touch[0].pageY - cropper.touchRelative[0].y; + cropper.imgLeft = left; + cropper.imgTop = top; + imgTransform(ins); + imgMarginDetectionPosition(ins); + } else { + var res = e.instance.getDataset(); + var minScale = +res.minscale; + var maxScale = +res.maxscale; + var disableRotate = bool(res.disablerotate) + 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(ins, 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 + } + ]; + if (!disableRotate) { + var first_atan = (180 / Math.PI) * Math.atan2(touchRelative[0].y, touchRelative[0].x); + var first_atan_old = (180 / Math.PI) * Math.atan2(cropper.touchRelative[0].y, cropper.touchRelative[0].x); + var second_atan = (180 / Math.PI) * Math.atan2(touchRelative[1].y, touchRelative[1].x); + var second_atan_old = (180 / Math.PI) * Math.atan2(cropper.touchRelative[1].y, cropper.touchRelative[1].x); + var first_deg = first_atan - first_atan_old, + second_deg = second_atan - second_atan_old; + if (first_deg != 0) { + current_deg = first_deg; + } else if (second_deg != 0) { + current_deg = second_deg; + } + } + cropper.touchRelative = touchRelative; + cropper.hypotenuseLength = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)); + //更新视图 + cropper.angle = cropper.angle + current_deg; + imgTransform(ins); + } +} + +function touchend(e, ins) { + cropper.flagEndTouch = true; + moveStop(ins); + updateData(ins) +} + + +function cutTouchStart(e, ins) { + var touch = e.touches || e.changedTouches; + var currentX = touch[0].pageX; + var currentY = touch[0].pageY; + + /* + * (右下-1 右上-2 左上-3 左下-4) + * left_x [3,4] + * top_y [2,3] + * right_x [1,2] + * bottom_y [1,4] + */ + var left_x1 = cropper.cutX - 30; + var left_x2 = cropper.cutX + 30; + + var top_y1 = cropper.cutY - 30; + var top_y2 = cropper.cutY + 30; + + var right_x1 = cropper.cutX + cropper.canvasWidth - 30; + var right_x2 = cropper.cutX + cropper.canvasWidth + 30; + + var bottom_y1 = cropper.cutY + cropper.canvasHeight - 30; + var bottom_y2 = cropper.cutY + cropper.canvasHeight + 30; + + if (currentX > right_x1 && currentX < right_x2 && currentY > bottom_y1 && currentY < bottom_y2) { + moveDuring(); + cropper.flagCutTouch = true; + cropper.flagEndTouch = true; + cropper.CUT_START = { + width: cropper.canvasWidth, + height: cropper.canvasHeight, + x: currentX, + y: currentY, + corner: 1 + }; + } else if (currentX > right_x1 && currentX < right_x2 && currentY > top_y1 && currentY < top_y2) { + moveDuring(); + cropper.flagCutTouch = true; + cropper.flagEndTouch = true; + cropper.CUT_START = { + width: cropper.canvasWidth, + height: cropper.canvasHeight, + x: currentX, + y: currentY, + cutY: cropper.cutY, + cutX: cropper.cutX, + corner: 2 + }; + } else if (currentX > left_x1 && currentX < left_x2 && currentY > top_y1 && currentY < top_y2) { + moveDuring(); + cropper.flagCutTouch = true; + cropper.flagEndTouch = true; + cropper.CUT_START = { + width: cropper.canvasWidth, + height: cropper.canvasHeight, + cutY: cropper.cutY, + cutX: cropper.cutX, + x: currentX, + y: currentY, + corner: 3 + }; + } else if (currentX > left_x1 && currentX < left_x2 && currentY > bottom_y1 && currentY < bottom_y2) { + moveDuring(); + cropper.flagCutTouch = true; + cropper.flagEndTouch = true; + cropper.CUT_START = { + width: cropper.canvasWidth, + height: cropper.canvasHeight, + cutY: cropper.cutY, + cutX: cropper.cutX, + x: currentX, + y: currentY, + corner: 4 + }; + } +} + +function cutTouchMove(e, ins) { + if (!cropper.CUT_START || cropper.CUT_START === 'null') return; + if (cropper.flagCutTouch) { + var touch = e.touches || e.changedTouches; + var res = e.instance.getDataset(); + var lockRatio = bool(res.lockratio); + var lockWidth = bool(res.lockwidth); + var lockHeight = bool(res.lockheight); + if (lockRatio && (lockWidth || lockHeight)) return; + var width = cropper.canvasWidth, + height = cropper.canvasHeight, + cutY = cropper.cutY, + cutX = cropper.cutX; + + var size_correct = function() { + width = width <= cropper.maxWidth ? (width >= cropper.minWidth ? width : cropper.minWidth) : cropper.maxWidth; + height = height <= cropper.maxHeight ? (height >= cropper.minHeight ? height : cropper.minHeight) : cropper.maxHeight; + } + + var size_inspect = function() { + if ((width > cropper.maxWidth || width < cropper.minWidth || height > cropper.maxHeight || height < cropper.minHeight) && + lockRatio) { + size_correct(); + return false; + } else { + size_correct(); + return true; + } + }; + height = cropper.CUT_START.height + (cropper.CUT_START.corner > 1 && cropper.CUT_START.corner < 4 ? 1 : -1) * ( + cropper.CUT_START.y - touch[0].pageY); + switch (cropper.CUT_START.corner) { + case 1: + width = cropper.CUT_START.width - cropper.CUT_START.x + touch[0].pageX; + if (lockRatio) { + height = width / (cropper.canvasWidth / cropper.canvasHeight); + } + if (!size_inspect()) return; + break; + case 2: + width = cropper.CUT_START.width - cropper.CUT_START.x + touch[0].pageX; + if (lockRatio) { + height = width / (cropper.canvasWidth / cropper.canvasHeight); + } + if (!size_inspect()) return; + cutY = cropper.CUT_START.cutY - (height - cropper.CUT_START.height); + break; + case 3: + width = cropper.CUT_START.width + cropper.CUT_START.x - touch[0].pageX; + if (lockRatio) { + height = width / (cropper.canvasWidth / cropper.canvasHeight); + } + if (!size_inspect()) return; + cutY = cropper.CUT_START.cutY - (height - cropper.CUT_START.height); + cutX = cropper.CUT_START.cutX - (width - cropper.CUT_START.width); + break; + case 4: + width = cropper.CUT_START.width + cropper.CUT_START.x - touch[0].pageX; + if (lockRatio) { + height = width / (cropper.canvasWidth / cropper.canvasHeight); + } + if (!size_inspect()) return; + cutX = cropper.CUT_START.cutX - (width - cropper.CUT_START.width); + break; + default: + break; + } + if (!lockWidth && !lockHeight) { + cropper.canvasWidth = width; + cropper.cutX = cutX; + cropper.canvasHeight = height; + cropper.cutY = cutY; + canvasHeight(ins); + canvasWidth(ins); + } else if (!lockWidth) { + cropper.canvasWidth = width; + cropper.cutX = cutX; + canvasWidth(ins); + } else if (!lockHeight) { + cropper.canvasHeight = height; + cropper.cutY = cutY; + canvasHeight(ins); + } + styleUpdate(ins) + imgMarginDetectionScale(ins); + } +} + +//检测剪裁框位置是否在允许的范围内(屏幕内) +function cutDetectionPosition(ins) { + 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.cutY == null && cropper.cutX == null) { + var cutY = (windowHeight - cropper.canvasHeight) * 0.5; + var cutX = (windowWidth - cropper.canvasWidth) * 0.5; + cropper.cutY = cutY; //截取的框上边距 + cropper.cutX = cutX; //截取的框左边距 + } else if (cropper.cutY != null && cropper.cutX != null) { + cutDetectionPositionTop(); + cutDetectionPositionLeft(); + } else if (cropper.cutY != null && cropper.cutX == null) { + cutDetectionPositionTop(); + cropper.cutX = (windowWidth - cropper.canvasWidth) / 2; + } else if (cropper.cutY == null && cropper.cutX != null) { + cutDetectionPositionLeft(); + cropper.cutY = (windowHeight - cropper.canvasHeight) / 2; + } + + styleUpdate(ins) +} + +/** + * 图片边缘检测-缩放 + */ +function imgMarginDetectionScale(ins, delay) { + if (!cropper.limitMove) return; + var scale = cropper.scale; + var imgWidth = cropper.imgWidth; + var 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(ins, scale, delay); +} +/** + * 图片边缘检测-位置 + */ +function imgMarginDetectionPosition(ins, scale, delay) { + if (!cropper.limitMove) return; + var left = cropper.imgLeft; + var top = cropper.imgTop; + scale = scale || cropper.scale; + var imgWidth = cropper.imgWidth; + var imgHeight = cropper.imgHeight; + 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; + styleUpdate(ins) + if (!delay || delay === 'null') { + imgTransform(ins); + } +} + + +function cutTouchEnd(e, ins) { + moveStop(ins); + cropper.flagCutTouch = false; + updateData(ins) +} + + +//改变截取框大小 +function computeCutSize(ins) { + if (cropper.canvasWidth > cropper.windowWidth) { + cropper.canvasWidth = cropper.windowWidth; + // canvasWidth(ins) + } else if (cropper.canvasWidth + cropper.cutX > cropper.windowWidth) { + cropper.cutX = cropper.windowWidth - cropper.cutX; + } + if (cropper.canvasHeight > cropper.windowHeight) { + cropper.canvasHeight = cropper.windowHeight; + // canvasHeight(ins) + } else if (cropper.canvasHeight + cropper.cutY > cropper.windowHeight) { + cropper.cutY = cropper.windowHeight - cropper.cutY; + } + // styleUpdate(ins) +} + +function styleUpdate(ins) { + if (!ins) return; + ins.selectComponent('.tui-cropper-box').setStyle({ + 'width': cropper.canvasWidth + 'px', + 'height': cropper.canvasHeight + 'px' + }) + ins.selectComponent('.tui-content-middle').setStyle({ + 'height': cropper.canvasHeight + 'px' + }) + ins.selectComponent('.tui-content-top').setStyle({ + 'height': cropper.cutY + 'px' + }) + ins.selectComponent('.tui-wxs-bg').setStyle({ + 'width': cropper.cutX + 'px' + }) + +} + +function imgTransform(ins) { + var owner = ins.selectComponent('.tui-cropper-image') + if (!owner) return + var x = cropper.imgLeft - cropper.imgWidth / 2; + var y = cropper.imgTop - cropper.imgHeight / 2; + owner.setStyle({ + 'transform': 'translate3d(' + x + 'px,' + y + 'px,0) scale(' + cropper.scale + ') rotate(' + cropper.angle + 'deg)' + }) +} + +function imageReset(ins) { + cropper.scale = 1; + cropper.angle = 0; + imgTransform(ins); +} +//监听截取框宽高变化 +function canvasWidth(ins) { + if (cropper.canvasWidth < cropper.minWidth) { + cropper.canvasWidth = cropper.minWidth; + } + if (!ins) return; + computeCutSize(ins); +} + +function canvasHeight(ins) { + if (cropper.canvasHeight < cropper.minHeight) { + cropper.canvasHeight = cropper.minHeight; + } + if (!ins) return; + computeCutSize(ins); +} + +function updateData(ins) { + if (!ins) return; + ins.callMethod('change', { + cutX: cropper.cutX, + cutY: cropper.cutY, + canvasWidth: cropper.canvasWidth, + canvasHeight: cropper.canvasHeight, + imgWidth: cropper.imgWidth, + imgHeight: cropper.imgHeight, + scale: cropper.scale, + angle: cropper.angle, + imgTop: cropper.imgTop, + imgLeft: cropper.imgLeft + }) +} + +function propsChange(prop, oldProp, ownerInstance, ins) { + if (prop && prop !== 'null') { + var params = prop.split(',') + var type = +params[0] + var dataset = ins.getDataset(); + if (cropper.init || type == 4) { + cropper.maxHeight = +dataset.maxheight; + cropper.minHeight = +dataset.minheight; + cropper.maxWidth = +dataset.maxwidth; + cropper.minWidth = +dataset.minwidth; + 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.limitMove = bool(dataset.limitmove); + cropper.angle = +dataset.angle; + if (type == 3) { + imgTransform(ownerInstance); + } + switch (type) { + case 1: + setCutCenter(ownerInstance); + //设置裁剪框大小>设置图片尺寸>绘制canvas + 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; + } + } +} + +module.exports = { + touchstart: touchstart, + touchmove: touchmove, + touchend: touchend, + cutTouchStart: cutTouchStart, + cutTouchMove: cutTouchMove, + cutTouchEnd: cutTouchEnd, + propsChange: propsChange +} diff --git a/components/thorui/tui-cropper/tui-cropper.vue b/components/thorui/tui-cropper/tui-cropper.vue new file mode 100644 index 0000000..e18a562 --- /dev/null +++ b/components/thorui/tui-cropper/tui-cropper.vue @@ -0,0 +1,505 @@ + + + + + diff --git a/components/thorui/tui-cropper/tui-cropper.wxs b/components/thorui/tui-cropper/tui-cropper.wxs new file mode 100644 index 0000000..122e5d9 --- /dev/null +++ b/components/thorui/tui-cropper/tui-cropper.wxs @@ -0,0 +1,321 @@ +var cropper = { + cutX: 0, //画布x轴起点 + cutY: 0, //画布y轴起点0 + touchRelative: [{ + x: 0, + y: 0 + }], //手指或鼠标和图片中心的相对位置 + hypotenuseLength: 0, //双指触摸时斜边长度 + flagEndTouch: false, //是否结束触摸 + canvasWidth: 0, + canvasHeight: 0, + imgWidth: 0, //图片宽度 + imgHeight: 0, //图片高度 + scale: 1, //图片缩放比 + angle: 0, //图片旋转角度 + imgTop: 0, //图片上边距 + imgLeft: 0, //图片左边距 + windowHeight: 0, + windowWidth: 0, + init: true +} + +function bool(str) { + return str === 'true' || str == true ? true : false +} + +function touchstart(e, ins) { + var touch = e.touches || e.changedTouches; + cropper.flagEndTouch = false; + if (touch.length == 1) { + cropper.touchRelative[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.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.hypotenuseLength = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)); + } + +} + +function moveDuring(ins) { + if (!ins) return; + ins.callMethod('moveDuring') +} + +function moveStop(ins) { + if (!ins) return; + ins.callMethod('moveStop') +}; + +function setCutCenter(ins) { + var cutY = (cropper.windowHeight - cropper.canvasHeight) * 0.5; + var cutX = (cropper.windowWidth - cropper.canvasWidth) * 0.5; + //顺序不能变 + cropper.imgTop = cropper.imgTop - cropper.cutY + cutY; + cropper.cutY = cutY; //截取的框上边距 + cropper.imgLeft = cropper.imgLeft - cropper.cutX + cutX; + cropper.cutX = cutX; //截取的框左边距 + cutDetectionPosition(ins) + imgTransform(ins) + updateData(ins) +} + +function touchmove(e, ins) { + var touch = e.touches || e.changedTouches; + if (cropper.flagEndTouch) return; + moveDuring(ins); + if (e.touches.length == 1) { + var left = touch[0].pageX - cropper.touchRelative[0].x, + top = touch[0].pageY - cropper.touchRelative[0].y; + cropper.imgLeft = left; + cropper.imgTop = top; + imgTransform(ins); + imgMarginDetectionPosition(ins); + } else { + var res = e.instance.getDataset(); + var minScale = +res.minscale; + var maxScale = +res.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(ins, 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.touchRelative = touchRelative; + cropper.hypotenuseLength = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)); + //更新视图 + cropper.angle = cropper.angle + current_deg; + imgTransform(ins); + } +} + +function touchend(e, ins) { + cropper.flagEndTouch = true; + moveStop(ins); + updateData(ins) +} + + +//检测剪裁框位置是否在允许的范围内(屏幕内) +function cutDetectionPosition(ins) { + 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.cutY == null && cropper.cutX == null) { + var cutY = (windowHeight - cropper.canvasHeight) * 0.5; + var cutX = (windowWidth - cropper.canvasWidth) * 0.5; + cropper.cutY = cutY; //截取的框上边距 + cropper.cutX = cutX; //截取的框左边距 + } else if (cropper.cutY != null && cropper.cutX != null) { + cutDetectionPositionTop(); + cutDetectionPositionLeft(); + } else if (cropper.cutY != null && cropper.cutX == null) { + cutDetectionPositionTop(); + cropper.cutX = (windowWidth - cropper.canvasWidth) / 2; + } else if (cropper.cutY == null && cropper.cutX != null) { + cutDetectionPositionLeft(); + cropper.cutY = (windowHeight - cropper.canvasHeight) / 2; + } +} + +/** + * 图片边缘检测-缩放 + */ +function imgMarginDetectionScale(ins, delay) { + var scale = cropper.scale; + var imgWidth = cropper.imgWidth; + var 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(ins, scale, delay); +} +/** + * 图片边缘检测-位置 + */ +function imgMarginDetectionPosition(ins, scale, delay) { + var left = cropper.imgLeft; + var top = cropper.imgTop; + scale = scale || cropper.scale; + var imgWidth = cropper.imgWidth; + var imgHeight = cropper.imgHeight; + 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(ins); + } +} + + +//改变截取框大小 +function computeCutSize(ins) { + 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(ins) { + var owner = ins.selectComponent('.tui-cropper__image') + if (!owner) return + var x = cropper.imgLeft - cropper.imgWidth / 2; + var y = cropper.imgTop - cropper.imgHeight / 2; + owner.setStyle({ + 'transform': 'translate3d(' + x + 'px,' + y + 'px,0) scale(' + cropper.scale + ') rotate(' + cropper.angle + 'deg)' + }) +} + +function imageReset(ins) { + cropper.scale = 1; + cropper.angle = 0; + imgTransform(ins); +} +//监听截取框宽高变化 +function canvasWidth(ins) { + if (!ins) return; + computeCutSize(ins); +} + +function canvasHeight(ins) { + if (!ins) return; + computeCutSize(ins); +} + +function updateData(ins) { + if (!ins) return; + ins.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 + }) +} + +function propsChange(prop, oldProp, ownerInstance, ins) { + if (prop && prop !== 'null') { + var params = prop.split(',') + var type = +params[0] + var dataset = ins.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); + //设置裁剪框大小>设置图片尺寸>绘制canvas + 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; + } + } +} + +module.exports = { + touchstart: touchstart, + touchmove: touchmove, + touchend: touchend, + propsChange: propsChange +} diff --git a/components/thorui/tui-datetime/tui-datetime.vue b/components/thorui/tui-datetime/tui-datetime.vue new file mode 100644 index 0000000..9b30017 --- /dev/null +++ b/components/thorui/tui-datetime/tui-datetime.vue @@ -0,0 +1,548 @@ + + + + + diff --git a/components/thorui/tui-divider/tui-divider.vue b/components/thorui/tui-divider/tui-divider.vue new file mode 100644 index 0000000..ec96112 --- /dev/null +++ b/components/thorui/tui-divider/tui-divider.vue @@ -0,0 +1,103 @@ + + + + + diff --git a/components/thorui/tui-drawer/tui-drawer.vue b/components/thorui/tui-drawer/tui-drawer.vue new file mode 100644 index 0000000..e183223 --- /dev/null +++ b/components/thorui/tui-drawer/tui-drawer.vue @@ -0,0 +1,139 @@ + + + + + diff --git a/components/thorui/tui-dropdown-list/tui-dropdown-list.vue b/components/thorui/tui-dropdown-list/tui-dropdown-list.vue new file mode 100644 index 0000000..e9eb77d --- /dev/null +++ b/components/thorui/tui-dropdown-list/tui-dropdown-list.vue @@ -0,0 +1,69 @@ + + + + + diff --git a/components/thorui/tui-fab/tui-fab.vue b/components/thorui/tui-fab/tui-fab.vue new file mode 100644 index 0000000..5efd197 --- /dev/null +++ b/components/thorui/tui-fab/tui-fab.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/components/thorui/tui-footer/tui-footer.vue b/components/thorui/tui-footer/tui-footer.vue new file mode 100644 index 0000000..b0dd70d --- /dev/null +++ b/components/thorui/tui-footer/tui-footer.vue @@ -0,0 +1,118 @@ + + + + + diff --git a/components/thorui/tui-grid-item/tui-grid-item.vue b/components/thorui/tui-grid-item/tui-grid-item.vue new file mode 100644 index 0000000..e0f1ea3 --- /dev/null +++ b/components/thorui/tui-grid-item/tui-grid-item.vue @@ -0,0 +1,147 @@ + + + + + diff --git a/components/thorui/tui-grid/tui-grid.vue b/components/thorui/tui-grid/tui-grid.vue new file mode 100644 index 0000000..f4f189a --- /dev/null +++ b/components/thorui/tui-grid/tui-grid.vue @@ -0,0 +1,44 @@ + + + + + diff --git a/components/thorui/tui-icon/tui-icon.vue b/components/thorui/tui-icon/tui-icon.vue new file mode 100644 index 0000000..55a9c74 --- /dev/null +++ b/components/thorui/tui-icon/tui-icon.vue @@ -0,0 +1,816 @@ + + + + + diff --git a/components/thorui/tui-image-cropper/tui-image-cropper.vue b/components/thorui/tui-image-cropper/tui-image-cropper.vue new file mode 100644 index 0000000..523f57a --- /dev/null +++ b/components/thorui/tui-image-cropper/tui-image-cropper.vue @@ -0,0 +1,1030 @@ + + + + + diff --git a/components/thorui/tui-image-group/tui-image-group.vue b/components/thorui/tui-image-group/tui-image-group.vue new file mode 100644 index 0000000..0bd0eec --- /dev/null +++ b/components/thorui/tui-image-group/tui-image-group.vue @@ -0,0 +1,163 @@ + + + + + diff --git a/components/thorui/tui-keyboard-input/tui-keyboard-input.vue b/components/thorui/tui-keyboard-input/tui-keyboard-input.vue new file mode 100644 index 0000000..143bc6c --- /dev/null +++ b/components/thorui/tui-keyboard-input/tui-keyboard-input.vue @@ -0,0 +1,73 @@ + + + + + diff --git a/components/thorui/tui-keyboard/tui-keyboard.vue b/components/thorui/tui-keyboard/tui-keyboard.vue new file mode 100644 index 0000000..df391e1 --- /dev/null +++ b/components/thorui/tui-keyboard/tui-keyboard.vue @@ -0,0 +1,240 @@ + + + + + diff --git a/components/thorui/tui-lazyload-img/tui-lazyload-img.vue b/components/thorui/tui-lazyload-img/tui-lazyload-img.vue new file mode 100644 index 0000000..c093483 --- /dev/null +++ b/components/thorui/tui-lazyload-img/tui-lazyload-img.vue @@ -0,0 +1,193 @@ + + + + + diff --git a/components/thorui/tui-list-cell/tui-list-cell.vue b/components/thorui/tui-list-cell/tui-list-cell.vue new file mode 100644 index 0000000..19ac128 --- /dev/null +++ b/components/thorui/tui-list-cell/tui-list-cell.vue @@ -0,0 +1,172 @@ + + + + + diff --git a/components/thorui/tui-list-view/tui-list-view.vue b/components/thorui/tui-list-view/tui-list-view.vue new file mode 100644 index 0000000..d14ebdb --- /dev/null +++ b/components/thorui/tui-list-view/tui-list-view.vue @@ -0,0 +1,97 @@ + + + + + diff --git a/components/thorui/tui-loading/tui-loading.vue b/components/thorui/tui-loading/tui-loading.vue new file mode 100644 index 0000000..4c38a09 --- /dev/null +++ b/components/thorui/tui-loading/tui-loading.vue @@ -0,0 +1,78 @@ + + + + + diff --git a/components/thorui/tui-loadmore/tui-loadmore.vue b/components/thorui/tui-loadmore/tui-loadmore.vue new file mode 100644 index 0000000..4c9ab65 --- /dev/null +++ b/components/thorui/tui-loadmore/tui-loadmore.vue @@ -0,0 +1,161 @@ + + + + + diff --git a/components/thorui/tui-modal/tui-modal.vue b/components/thorui/tui-modal/tui-modal.vue new file mode 100644 index 0000000..4e34929 --- /dev/null +++ b/components/thorui/tui-modal/tui-modal.vue @@ -0,0 +1,407 @@ + + + + + diff --git a/components/thorui/tui-navigation-bar/tui-navigation-bar.vue b/components/thorui/tui-navigation-bar/tui-navigation-bar.vue new file mode 100644 index 0000000..07ffd5c --- /dev/null +++ b/components/thorui/tui-navigation-bar/tui-navigation-bar.vue @@ -0,0 +1,250 @@ + + + + + diff --git a/components/thorui/tui-no-data/tui-no-data.vue b/components/thorui/tui-no-data/tui-no-data.vue new file mode 100644 index 0000000..c825052 --- /dev/null +++ b/components/thorui/tui-no-data/tui-no-data.vue @@ -0,0 +1,117 @@ + + + + + diff --git a/components/thorui/tui-nomore/tui-nomore.vue b/components/thorui/tui-nomore/tui-nomore.vue new file mode 100644 index 0000000..cbc9d61 --- /dev/null +++ b/components/thorui/tui-nomore/tui-nomore.vue @@ -0,0 +1,115 @@ + + + + + diff --git a/components/thorui/tui-numberbox/tui-numberbox.vue b/components/thorui/tui-numberbox/tui-numberbox.vue new file mode 100644 index 0000000..dd301f0 --- /dev/null +++ b/components/thorui/tui-numberbox/tui-numberbox.vue @@ -0,0 +1,222 @@ + + + + + diff --git a/components/thorui/tui-overflow-hidden/tui-overflow-hidden.vue b/components/thorui/tui-overflow-hidden/tui-overflow-hidden.vue new file mode 100644 index 0000000..20f4a7a --- /dev/null +++ b/components/thorui/tui-overflow-hidden/tui-overflow-hidden.vue @@ -0,0 +1,131 @@ + + + + + diff --git a/components/thorui/tui-picture-cropper/tui-picture-cropper.vue b/components/thorui/tui-picture-cropper/tui-picture-cropper.vue new file mode 100644 index 0000000..f9b5328 --- /dev/null +++ b/components/thorui/tui-picture-cropper/tui-picture-cropper.vue @@ -0,0 +1,699 @@ + + + + + diff --git a/components/thorui/tui-picture-cropper/tui-picture-cropper.wxs b/components/thorui/tui-picture-cropper/tui-picture-cropper.wxs new file mode 100644 index 0000000..7d7c119 --- /dev/null +++ b/components/thorui/tui-picture-cropper/tui-picture-cropper.wxs @@ -0,0 +1,560 @@ +var cropper = { + CUT_START: null, + cutX: 0, //画布x轴起点 + cutY: 0, //画布y轴起点0 + touchRelative: [{ + x: 0, + y: 0 + }], //手指或鼠标和图片中心的相对位置 + flagCutTouch: false, //是否是拖动裁剪框 + hypotenuseLength: 0, //双指触摸时斜边长度 + flagEndTouch: false, //是否结束触摸 + canvasWidth: 0, + canvasHeight: 0, + imgWidth: 0, //图片宽度 + imgHeight: 0, //图片高度 + scale: 1, //图片缩放比 + angle: 0, //图片旋转角度 + imgTop: 0, //图片上边距 + imgLeft: 0, //图片左边距 + //是否限制移动范围(剪裁框只能在图片内,为true不可触摸转动图片) + limitMove: true, + minHeight: 0, + maxHeight: 0, + minWidth: 0, + maxWidth: 0, + windowHeight: 0, + windowWidth: 0, + init: true +} + +function bool(str) { + return str === 'true' || str == true ? true : false +} + +function touchstart(e, ins) { + //var instance = e.instance; + // var state = instance.getState(); + var touch = e.touches || e.changedTouches; + cropper.flagEndTouch = false; + if (touch.length == 1) { + cropper.touchRelative[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.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.hypotenuseLength = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)); + } + +} + +function moveDuring(ins) { + if (!ins) return; + ins.callMethod('moveDuring') +} + +function moveStop(ins) { + if (!ins) return; + ins.callMethod('moveStop') +}; + +function setCutCenter(ins) { + var cutY = (cropper.windowHeight - cropper.canvasHeight) * 0.5; + var cutX = (cropper.windowWidth - cropper.canvasWidth) * 0.5; + //顺序不能变 + cropper.imgTop = cropper.imgTop - cropper.cutY + cutY; + cropper.cutY = cutY; //截取的框上边距 + cropper.imgLeft = cropper.imgLeft - cropper.cutX + cutX; + cropper.cutX = cutX; //截取的框左边距 + styleUpdate(ins) + cutDetectionPosition(ins) + imgTransform(ins) + updateData(ins) +} + +function touchmove(e, ins) { + var touch = e.touches || e.changedTouches; + if (cropper.flagEndTouch) return; + moveDuring(ins); + if (e.touches.length == 1) { + var left = touch[0].pageX - cropper.touchRelative[0].x, + top = touch[0].pageY - cropper.touchRelative[0].y; + cropper.imgLeft = left; + cropper.imgTop = top; + imgTransform(ins); + imgMarginDetectionPosition(ins); + } else { + var res = e.instance.getDataset(); + var minScale = +res.minscale; + var maxScale = +res.maxscale; + var disableRotate = bool(res.disablerotate) + 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(ins, 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 + } + ]; + if (!disableRotate) { + var first_atan = (180 / Math.PI) * Math.atan2(touchRelative[0].y, touchRelative[0].x); + var first_atan_old = (180 / Math.PI) * Math.atan2(cropper.touchRelative[0].y, cropper.touchRelative[0].x); + var second_atan = (180 / Math.PI) * Math.atan2(touchRelative[1].y, touchRelative[1].x); + var second_atan_old = (180 / Math.PI) * Math.atan2(cropper.touchRelative[1].y, cropper.touchRelative[1].x); + var first_deg = first_atan - first_atan_old, + second_deg = second_atan - second_atan_old; + if (first_deg != 0) { + current_deg = first_deg; + } else if (second_deg != 0) { + current_deg = second_deg; + } + } + cropper.touchRelative = touchRelative; + cropper.hypotenuseLength = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)); + //更新视图 + cropper.angle = cropper.angle + current_deg; + imgTransform(ins); + } +} + +function touchend(e, ins) { + cropper.flagEndTouch = true; + moveStop(ins); + updateData(ins) +} + + +function cutTouchStart(e, ins) { + var touch = e.touches || e.changedTouches; + var currentX = touch[0].pageX; + var currentY = touch[0].pageY; + + /* + * (右下-1 右上-2 左上-3 左下-4) + * left_x [3,4] + * top_y [2,3] + * right_x [1,2] + * bottom_y [1,4] + */ + var left_x1 = cropper.cutX - 30; + var left_x2 = cropper.cutX + 30; + + var top_y1 = cropper.cutY - 30; + var top_y2 = cropper.cutY + 30; + + var right_x1 = cropper.cutX + cropper.canvasWidth - 30; + var right_x2 = cropper.cutX + cropper.canvasWidth + 30; + + var bottom_y1 = cropper.cutY + cropper.canvasHeight - 30; + var bottom_y2 = cropper.cutY + cropper.canvasHeight + 30; + + if (currentX > right_x1 && currentX < right_x2 && currentY > bottom_y1 && currentY < bottom_y2) { + moveDuring(); + cropper.flagCutTouch = true; + cropper.flagEndTouch = true; + cropper.CUT_START = { + width: cropper.canvasWidth, + height: cropper.canvasHeight, + x: currentX, + y: currentY, + corner: 1 + }; + } else if (currentX > right_x1 && currentX < right_x2 && currentY > top_y1 && currentY < top_y2) { + moveDuring(); + cropper.flagCutTouch = true; + cropper.flagEndTouch = true; + cropper.CUT_START = { + width: cropper.canvasWidth, + height: cropper.canvasHeight, + x: currentX, + y: currentY, + cutY: cropper.cutY, + cutX: cropper.cutX, + corner: 2 + }; + } else if (currentX > left_x1 && currentX < left_x2 && currentY > top_y1 && currentY < top_y2) { + moveDuring(); + cropper.flagCutTouch = true; + cropper.flagEndTouch = true; + cropper.CUT_START = { + width: cropper.canvasWidth, + height: cropper.canvasHeight, + cutY: cropper.cutY, + cutX: cropper.cutX, + x: currentX, + y: currentY, + corner: 3 + }; + } else if (currentX > left_x1 && currentX < left_x2 && currentY > bottom_y1 && currentY < bottom_y2) { + moveDuring(); + cropper.flagCutTouch = true; + cropper.flagEndTouch = true; + cropper.CUT_START = { + width: cropper.canvasWidth, + height: cropper.canvasHeight, + cutY: cropper.cutY, + cutX: cropper.cutX, + x: currentX, + y: currentY, + corner: 4 + }; + } +} + +function cutTouchMove(e, ins) { + if (!cropper.CUT_START || cropper.CUT_START === 'null') return; + if (cropper.flagCutTouch) { + var touch = e.touches || e.changedTouches; + var res = e.instance.getDataset(); + var lockRatio = bool(res.lockratio); + var lockWidth = bool(res.lockwidth); + var lockHeight = bool(res.lockheight); + if (lockRatio && (lockWidth || lockHeight)) return; + var width = cropper.canvasWidth, + height = cropper.canvasHeight, + cutY = cropper.cutY, + cutX = cropper.cutX; + + var size_correct = function() { + width = width <= cropper.maxWidth ? (width >= cropper.minWidth ? width : cropper.minWidth) : cropper.maxWidth; + height = height <= cropper.maxHeight ? (height >= cropper.minHeight ? height : cropper.minHeight) : cropper.maxHeight; + } + + var size_inspect = function() { + if ((width > cropper.maxWidth || width < cropper.minWidth || height > cropper.maxHeight || height < cropper.minHeight) && + lockRatio) { + size_correct(); + return false; + } else { + size_correct(); + return true; + } + }; + height = cropper.CUT_START.height + (cropper.CUT_START.corner > 1 && cropper.CUT_START.corner < 4 ? 1 : -1) * ( + cropper.CUT_START.y - touch[0].pageY); + switch (cropper.CUT_START.corner) { + case 1: + width = cropper.CUT_START.width - cropper.CUT_START.x + touch[0].pageX; + if (lockRatio) { + height = width / (cropper.canvasWidth / cropper.canvasHeight); + } + if (!size_inspect()) return; + break; + case 2: + width = cropper.CUT_START.width - cropper.CUT_START.x + touch[0].pageX; + if (lockRatio) { + height = width / (cropper.canvasWidth / cropper.canvasHeight); + } + if (!size_inspect()) return; + cutY = cropper.CUT_START.cutY - (height - cropper.CUT_START.height); + break; + case 3: + width = cropper.CUT_START.width + cropper.CUT_START.x - touch[0].pageX; + if (lockRatio) { + height = width / (cropper.canvasWidth / cropper.canvasHeight); + } + if (!size_inspect()) return; + cutY = cropper.CUT_START.cutY - (height - cropper.CUT_START.height); + cutX = cropper.CUT_START.cutX - (width - cropper.CUT_START.width); + break; + case 4: + width = cropper.CUT_START.width + cropper.CUT_START.x - touch[0].pageX; + if (lockRatio) { + height = width / (cropper.canvasWidth / cropper.canvasHeight); + } + if (!size_inspect()) return; + cutX = cropper.CUT_START.cutX - (width - cropper.CUT_START.width); + break; + default: + break; + } + if (!lockWidth && !lockHeight) { + cropper.canvasWidth = width; + cropper.cutX = cutX; + cropper.canvasHeight = height; + cropper.cutY = cutY; + canvasHeight(ins); + canvasWidth(ins); + } else if (!lockWidth) { + cropper.canvasWidth = width; + cropper.cutX = cutX; + canvasWidth(ins); + } else if (!lockHeight) { + cropper.canvasHeight = height; + cropper.cutY = cutY; + canvasHeight(ins); + } + styleUpdate(ins) + imgMarginDetectionScale(ins); + } +} + +//检测剪裁框位置是否在允许的范围内(屏幕内) +function cutDetectionPosition(ins) { + 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.cutY == null && cropper.cutX == null) { + var cutY = (windowHeight - cropper.canvasHeight) * 0.5; + var cutX = (windowWidth - cropper.canvasWidth) * 0.5; + cropper.cutY = cutY; //截取的框上边距 + cropper.cutX = cutX; //截取的框左边距 + } else if (cropper.cutY != null && cropper.cutX != null) { + cutDetectionPositionTop(); + cutDetectionPositionLeft(); + } else if (cropper.cutY != null && cropper.cutX == null) { + cutDetectionPositionTop(); + cropper.cutX = (windowWidth - cropper.canvasWidth) / 2; + } else if (cropper.cutY == null && cropper.cutX != null) { + cutDetectionPositionLeft(); + cropper.cutY = (windowHeight - cropper.canvasHeight) / 2; + } + + styleUpdate(ins) +} + +/** + * 图片边缘检测-缩放 + */ +function imgMarginDetectionScale(ins, delay) { + if (!cropper.limitMove) return; + var scale = cropper.scale; + var imgWidth = cropper.imgWidth; + var 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(ins, scale, delay); +} +/** + * 图片边缘检测-位置 + */ +function imgMarginDetectionPosition(ins, scale, delay) { + if (!cropper.limitMove) return; + var left = cropper.imgLeft; + var top = cropper.imgTop; + scale = scale || cropper.scale; + var imgWidth = cropper.imgWidth; + var imgHeight = cropper.imgHeight; + 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; + styleUpdate(ins) + if (!delay || delay === 'null') { + imgTransform(ins); + } +} + + +function cutTouchEnd(e, ins) { + moveStop(ins); + cropper.flagCutTouch = false; + updateData(ins) +} + + +//改变截取框大小 +function computeCutSize(ins) { + if (cropper.canvasWidth > cropper.windowWidth) { + cropper.canvasWidth = cropper.windowWidth; + // canvasWidth(ins) + } else if (cropper.canvasWidth + cropper.cutX > cropper.windowWidth) { + cropper.cutX = cropper.windowWidth - cropper.cutX; + } + if (cropper.canvasHeight > cropper.windowHeight) { + cropper.canvasHeight = cropper.windowHeight; + // canvasHeight(ins) + } else if (cropper.canvasHeight + cropper.cutY > cropper.windowHeight) { + cropper.cutY = cropper.windowHeight - cropper.cutY; + } + // styleUpdate(ins) +} + +function styleUpdate(ins) { + if (!ins) return; + ins.selectComponent('.tui-cropper-box').setStyle({ + 'width': cropper.canvasWidth + 'px', + 'height': cropper.canvasHeight + 'px' + }) + ins.selectComponent('.tui-content-middle').setStyle({ + 'height': cropper.canvasHeight + 'px' + }) + ins.selectComponent('.tui-content-top').setStyle({ + 'height': cropper.cutY + 'px' + }) + ins.selectComponent('.tui-wxs-bg').setStyle({ + 'width': cropper.cutX + 'px' + }) + +} + +function imgTransform(ins) { + var owner = ins.selectComponent('.tui-cropper-image') + if (!owner) return + var x = cropper.imgLeft - cropper.imgWidth / 2; + var y = cropper.imgTop - cropper.imgHeight / 2; + owner.setStyle({ + 'transform': 'translate3d(' + x + 'px,' + y + 'px,0) scale(' + cropper.scale + ') rotate(' + cropper.angle + 'deg)' + }) +} + +function imageReset(ins) { + cropper.scale = 1; + cropper.angle = 0; + imgTransform(ins); +} +//监听截取框宽高变化 +function canvasWidth(ins) { + if (cropper.canvasWidth < cropper.minWidth) { + cropper.canvasWidth = cropper.minWidth; + } + if (!ins) return; + computeCutSize(ins); +} + +function canvasHeight(ins) { + if (cropper.canvasHeight < cropper.minHeight) { + cropper.canvasHeight = cropper.minHeight; + } + if (!ins) return; + computeCutSize(ins); +} + +function updateData(ins) { + if (!ins) return; + ins.callMethod('change', { + cutX: cropper.cutX, + cutY: cropper.cutY, + canvasWidth: cropper.canvasWidth, + canvasHeight: cropper.canvasHeight, + imgWidth: cropper.imgWidth, + imgHeight: cropper.imgHeight, + scale: cropper.scale, + angle: cropper.angle, + imgTop: cropper.imgTop, + imgLeft: cropper.imgLeft + }) +} + +function propsChange(prop, oldProp, ownerInstance, ins) { + if (prop && prop !== 'null') { + var params = prop.split(',') + var type = +params[0] + var dataset = ins.getDataset(); + if (cropper.init || type == 4) { + cropper.maxHeight = +dataset.maxheight; + cropper.minHeight = +dataset.minheight; + cropper.maxWidth = +dataset.maxwidth; + cropper.minWidth = +dataset.minwidth; + 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.limitMove = bool(dataset.limitmove); + cropper.angle = +dataset.angle; + if (type == 3) { + imgTransform(ownerInstance); + } + switch (type) { + case 1: + setCutCenter(ownerInstance); + //设置裁剪框大小>设置图片尺寸>绘制canvas + 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; + } + } +} + +module.exports = { + touchstart: touchstart, + touchmove: touchmove, + touchend: touchend, + cutTouchStart: cutTouchStart, + cutTouchMove: cutTouchMove, + cutTouchEnd: cutTouchEnd, + propsChange: propsChange +} diff --git a/components/thorui/tui-popup/tui-popup.vue b/components/thorui/tui-popup/tui-popup.vue new file mode 100644 index 0000000..3349d0c --- /dev/null +++ b/components/thorui/tui-popup/tui-popup.vue @@ -0,0 +1,266 @@ + + + + + diff --git a/components/thorui/tui-rate/tui-rate.vue b/components/thorui/tui-rate/tui-rate.vue new file mode 100644 index 0000000..d670f3f --- /dev/null +++ b/components/thorui/tui-rate/tui-rate.vue @@ -0,0 +1,174 @@ + + + + + diff --git a/components/thorui/tui-round-progress/tui-round-progress.vue b/components/thorui/tui-round-progress/tui-round-progress.vue new file mode 100644 index 0000000..4b50fe9 --- /dev/null +++ b/components/thorui/tui-round-progress/tui-round-progress.vue @@ -0,0 +1,292 @@ + + + + + diff --git a/components/thorui/tui-scroll-top/tui-scroll-top.vue b/components/thorui/tui-scroll-top/tui-scroll-top.vue new file mode 100644 index 0000000..3c15cb6 --- /dev/null +++ b/components/thorui/tui-scroll-top/tui-scroll-top.vue @@ -0,0 +1,178 @@ + + + + + diff --git a/components/thorui/tui-skeleton/tui-skeleton.vue b/components/thorui/tui-skeleton/tui-skeleton.vue new file mode 100644 index 0000000..9d63ba4 --- /dev/null +++ b/components/thorui/tui-skeleton/tui-skeleton.vue @@ -0,0 +1,239 @@ + + + + + diff --git a/components/thorui/tui-slide-verify/tui-slide-verify.vue b/components/thorui/tui-slide-verify/tui-slide-verify.vue new file mode 100644 index 0000000..8f53909 --- /dev/null +++ b/components/thorui/tui-slide-verify/tui-slide-verify.vue @@ -0,0 +1,217 @@ + + + + + diff --git a/components/thorui/tui-slide-verify/tui-slide-verify.wxs b/components/thorui/tui-slide-verify/tui-slide-verify.wxs new file mode 100644 index 0000000..1ab80e7 --- /dev/null +++ b/components/thorui/tui-slide-verify/tui-slide-verify.wxs @@ -0,0 +1,73 @@ +var slideBarWidth = 200; +var slideBlockWidth = 32; +var errorRange = 2 +var disabled = false + +function bool(str) { + return str === 'true' || str == true ? true : false +} + +function touchstart(e, ins) { + var state=e.instance.getState() + var touch = e.touches[0] || e.changedTouches[0] + var dataset = e.instance.getDataset() + state.startX = touch.pageX + slideBarWidth = +dataset.slidebarwidth + slideBlockWidth = +dataset.slideblockwidth + errorRange = +dataset.errorrange + disabled = bool(dataset.disabled) +} + +function styleChange(left, ins) { + if (!ins) return; + ins.selectComponent('.tui-slider-block').setStyle({ + transform: 'translate3d(' + left + 'px,0,0)' + }) + ins.selectComponent('.tui-slide-glided').setStyle({ + width: left + 'px' + }) +} + +function touchmove(e, ins) { + if (disabled) return; + var state=e.instance.getState() + var touch = e.touches[0] || e.changedTouches[0] + var pageX = touch.pageX; + var left = pageX - state.startX + (state.lastLeft || 0); + left = left < 0 ? 0 : left; + var width = slideBarWidth - slideBlockWidth; + left = left >= width ? width : left; + state.startX = pageX + state.lastLeft = left + styleChange(left, ins) +} + +function touchend(e, ins) { + if (disabled) return; + var state=e.instance.getState() + let left = slideBarWidth - slideBlockWidth + if (left - state.lastLeft <= errorRange) { + styleChange(left, ins) + ins.callMethod('success') + } else { + state.startX = 0; + state.lastLeft = 0; + styleChange(0, ins) + } +} + +function slidereset(reset, oldreset, owner, ins) { + var state=ins.getState() + if (reset > 0) { + state.startX = 0; + state.lastLeft = 0; + styleChange(0, owner) + } +} + +module.exports = { + touchstart: touchstart, + touchmove: touchmove, + touchend: touchend, + slidereset: slidereset +} \ No newline at end of file diff --git a/components/thorui/tui-steps/tui-steps.vue b/components/thorui/tui-steps/tui-steps.vue new file mode 100644 index 0000000..e11fd2a --- /dev/null +++ b/components/thorui/tui-steps/tui-steps.vue @@ -0,0 +1,254 @@ + + + + + diff --git a/components/thorui/tui-sticky-wxs/tui-sticky-wxs.vue b/components/thorui/tui-sticky-wxs/tui-sticky-wxs.vue new file mode 100644 index 0000000..8eb8e03 --- /dev/null +++ b/components/thorui/tui-sticky-wxs/tui-sticky-wxs.vue @@ -0,0 +1,124 @@ + + + + + diff --git a/components/thorui/tui-sticky-wxs/tui-sticky.wxs b/components/thorui/tui-sticky-wxs/tui-sticky.wxs new file mode 100644 index 0000000..044a23d --- /dev/null +++ b/components/thorui/tui-sticky-wxs/tui-sticky.wxs @@ -0,0 +1,44 @@ +var stickyChange = function(scrollTop, oldScrollTop, ownerInstance, ins) { + if (!oldScrollTop && scrollTop === 0) return false; + var dataset = ins.getDataset() + var top = +dataset.top; + var height = +dataset.height; + var stickyTop = +dataset.stickytop; + var isNativeHeader = dataset.isnativeheader; + var isFixed = false; + var distance = stickyTop + // #ifdef H5 + if (isNativeHeader) { + distance = distance - 44 + distance = distance < 0 ? 0 : distance + } + // #endif + if (dataset.container) { + isFixed = (scrollTop + distance >= top && scrollTop + distance < top + height) ? true : false + } else { + isFixed = scrollTop + distance >= top ? true : false + } + if (isFixed) { + ownerInstance.selectComponent('.tui-sticky-bar').setStyle({ + "top": stickyTop + 'px' + }).addClass('tui-sticky-fixed') + ownerInstance.selectComponent('.tui-sticky-seat').setStyle({ + "display": 'block' + }) + } else { + ownerInstance.selectComponent('.tui-sticky-bar').setStyle({ + "top": 'auto' + }).removeClass('tui-sticky-fixed') + ownerInstance.selectComponent('.tui-sticky-seat').setStyle({ + "display": 'none' + }) + } + ownerInstance.triggerEvent("sticky", { + isFixed: isFixed, + index: parseInt(dataset.index) + }) +} + +module.exports = { + stickyChange: stickyChange +} diff --git a/components/thorui/tui-sticky/tui-sticky.vue b/components/thorui/tui-sticky/tui-sticky.vue new file mode 100644 index 0000000..9199d4f --- /dev/null +++ b/components/thorui/tui-sticky/tui-sticky.vue @@ -0,0 +1,152 @@ + + + + + diff --git a/components/thorui/tui-swipe-action/tui-swipe-action.vue b/components/thorui/tui-swipe-action/tui-swipe-action.vue new file mode 100644 index 0000000..634defc --- /dev/null +++ b/components/thorui/tui-swipe-action/tui-swipe-action.vue @@ -0,0 +1,304 @@ + + + + + diff --git a/components/thorui/tui-tab/tui-tab.vue b/components/thorui/tui-tab/tui-tab.vue new file mode 100644 index 0000000..13825bc --- /dev/null +++ b/components/thorui/tui-tab/tui-tab.vue @@ -0,0 +1,273 @@ + + + + + diff --git a/components/thorui/tui-tabbar/tui-tabbar.vue b/components/thorui/tui-tabbar/tui-tabbar.vue new file mode 100644 index 0000000..24d282c --- /dev/null +++ b/components/thorui/tui-tabbar/tui-tabbar.vue @@ -0,0 +1,279 @@ + + + + + diff --git a/components/thorui/tui-tabs/tui-tabs.vue b/components/thorui/tui-tabs/tui-tabs.vue new file mode 100644 index 0000000..5ee5837 --- /dev/null +++ b/components/thorui/tui-tabs/tui-tabs.vue @@ -0,0 +1,276 @@ + + + + + diff --git a/components/thorui/tui-tag/tui-tag.vue b/components/thorui/tui-tag/tui-tag.vue new file mode 100644 index 0000000..82b9d08 --- /dev/null +++ b/components/thorui/tui-tag/tui-tag.vue @@ -0,0 +1,354 @@ + + + + + diff --git a/components/thorui/tui-time-axis/tui-time-axis.vue b/components/thorui/tui-time-axis/tui-time-axis.vue new file mode 100644 index 0000000..dc346c0 --- /dev/null +++ b/components/thorui/tui-time-axis/tui-time-axis.vue @@ -0,0 +1,38 @@ + + + + + diff --git a/components/thorui/tui-timeaxis-item/tui-timeaxis-item.vue b/components/thorui/tui-timeaxis-item/tui-timeaxis-item.vue new file mode 100644 index 0000000..154b8f6 --- /dev/null +++ b/components/thorui/tui-timeaxis-item/tui-timeaxis-item.vue @@ -0,0 +1,50 @@ + + + + + diff --git a/components/thorui/tui-tips/tui-tips.vue b/components/thorui/tui-tips/tui-tips.vue new file mode 100644 index 0000000..bd6900a --- /dev/null +++ b/components/thorui/tui-tips/tui-tips.vue @@ -0,0 +1,129 @@ + + + + + diff --git a/components/thorui/tui-toast/tui-toast.vue b/components/thorui/tui-toast/tui-toast.vue new file mode 100644 index 0000000..31b6f8f --- /dev/null +++ b/components/thorui/tui-toast/tui-toast.vue @@ -0,0 +1,121 @@ + + + + + diff --git a/components/thorui/tui-top-dropdown/tui-top-dropdown.vue b/components/thorui/tui-top-dropdown/tui-top-dropdown.vue new file mode 100644 index 0000000..d343231 --- /dev/null +++ b/components/thorui/tui-top-dropdown/tui-top-dropdown.vue @@ -0,0 +1,104 @@ + + + + + diff --git a/components/thorui/tui-upload/tui-upload.vue b/components/thorui/tui-upload/tui-upload.vue new file mode 100644 index 0000000..0220e58 --- /dev/null +++ b/components/thorui/tui-upload/tui-upload.vue @@ -0,0 +1,467 @@ + + + + + diff --git a/components/thorui/tui-waterfall/tui-waterfall.vue b/components/thorui/tui-waterfall/tui-waterfall.vue new file mode 100644 index 0000000..1cee8bc --- /dev/null +++ b/components/thorui/tui-waterfall/tui-waterfall.vue @@ -0,0 +1,223 @@ + + + + + diff --git a/pages2/balance/balance.vue b/pages2/balance/balance.vue new file mode 100644 index 0000000..3db5b7e --- /dev/null +++ b/pages2/balance/balance.vue @@ -0,0 +1,526 @@ + + + + + + + diff --git a/pages2/setting/bind-mobile/bind-mobile.vue b/pages2/setting/bind-mobile/bind-mobile.vue new file mode 100644 index 0000000..6ccb152 --- /dev/null +++ b/pages2/setting/bind-mobile/bind-mobile.vue @@ -0,0 +1,104 @@ + + + + diff --git a/pages2/setting/cutImage.vue b/pages2/setting/cutImage.vue new file mode 100644 index 0000000..52e8e60 --- /dev/null +++ b/pages2/setting/cutImage.vue @@ -0,0 +1,57 @@ + + + + \ No newline at end of file diff --git a/pages2/setting/limeClipper/README.md b/pages2/setting/limeClipper/README.md new file mode 100644 index 0000000..9219f81 --- /dev/null +++ b/pages2/setting/limeClipper/README.md @@ -0,0 +1,227 @@ +> 插件来源:[https://ext.dcloud.net.cn/plugin?id=3594](https://ext.dcloud.net.cn/plugin?id=3594) +##### 以下是作者写的插件介绍: + +# Clipper 图片裁剪 +> uniapp 图片裁剪,可用于图片头像等裁剪处理 +> [查看更多](http://liangei.gitee.io/limeui/#/clipper)
+> Q群:458377637 + + +## 平台兼容 + +| H5 | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ 小程序 | App | +| --- | ---------- | ------------ | ---------- | ---------- | --------- | --- | +| √ | √ | √ | 未测 | √ | √ | √ | + + +## 代码演示 +### 基本用法 +`@success` 事件点击 👉 **确定** 后会返回生成的图片信息,包含 `url`、`width`、`height` + +```html + + + +``` + +```js +// 非uni_modules引入 +import lClipper from '@/components/lime-clipper/' +// uni_modules引入 +import lClipper from '@/uni_modules/lime-clipper/components/lime-clipper/' +export default { + components: {lClipper}, + data() { + return { + show: false, + url: '', + } + } +} +``` + + +### 传入图片 +`image-url`可传入**相对路径**、**临时路径**、**本地路径**、**网络图片**
+ +* **当为网络地址时** +* H5:👉 需要解决跨域问题。
+* 小程序:👉 需要配置 downloadFile 域名
+ + +```html + + + +``` + +```js +export default { + components: {lClipper}, + data() { + return { + imageUrl: 'https://img12.360buyimg.com/pop/s1180x940_jfs/t1/97205/26/1142/87801/5dbac55aEf795d962/48a4d7a63ff80b8b.jpg', + show: false, + url: '', + } + } +} +``` + + +### 确定按钮颜色 +样式变量名:`--l-clipper-confirm-color` +可放到全局样式的 `page` 里或节点的 `style` +```html + +``` +```css +// css 中为组件设置 CSS 变量 +.clipper { + --l-clipper-confirm-color: linear-gradient(to right, #ff6034, #ee0a24) +} +// 全局 +page { + --l-clipper-confirm-color: linear-gradient(to right, #ff6034, #ee0a24) +} +``` + + +### 使用插槽 +共五个插槽 `cancel` 取消按钮、 `photo` 选择图片按钮、 `rotate` 旋转按钮、 `confirm` 确定按钮和默认插槽。 + +```html + + + + 取消 + 选择图片 + 旋转 + 确定 + + + 显示取消按钮 + + + 显示选择图片按钮 + + + 显示旋转按钮 + + + 显示确定按钮 + + + 锁定裁剪框宽度 + + + 锁定裁剪框高度 + + + 锁定裁剪框比例 + + + 限制移动范围 + + + 禁止缩放 + + + 禁止旋转 + + + + + +``` + +```js +export default { + components: {lClipper}, + data() { + return { + show: false, + url: '', + isLockWidth: false, + isLockHeight: false, + isLockRatio: true, + isLimitMove: false, + isDisableScale: false, + isDisableRotate: false, + isShowCancelBtn: true, + isShowPhotoBtn: true, + isShowRotateBtn: true, + isShowConfirmBtn: true + } + } +} +``` + + +## API + +### Props + +| 参数 | 说明 | 类型 | 默认值 | +| ------------- | ------------ | ---------------- | ------------ | +| image-url | 图片路径 | string | | +| quality | 图片的质量,取值范围为 [0, 1],不在范围内时当作1处理 | number | `1` | +| source | `{album: '从相册中选择'}`key为图片来源类型,value为选项说明 | Object | | +| width | 裁剪框宽度,单位为 `rpx` | number | `400` | +| height | 裁剪框高度 | number | `400` | +| min-width | 裁剪框最小宽度 | number | `200` | +| min-height |裁剪框最小高度 | number | `200` | +| max-width | 裁剪框最大宽度 | number | `600` | +| max-height | 裁剪框最大宽度 | number | `600` | +| min-ratio | 图片最小缩放比 | number | `0.5` | +| max-ratio | 图片最大缩放比 | number | `2` | +| rotate-angle | 旋转按钮每次旋转的角度 | number | `90` | +| scale-ratio | 生成图片相对于裁剪框的比例, **比例越高生成图片越清晰** | number | `1` | +| is-lock-width | 是否锁定裁剪框宽度 | boolean | `false` | +| is-lock-height | 是否锁定裁剪框高度上 | boolean | `false` | +| is-lock-ratio | 是否锁定裁剪框比例 | boolean | `true` | +| is-disable-scale | 是否禁止缩放 | boolean | `false` | +| is-disable-rotate | 是否禁止旋转 | boolean | `false` | +| is-limit-move | 是否限制移动范围 | boolean | `false` | +| is-show-photo-btn | 是否显示选择图片按钮 | boolean | `true` | +| is-show-rotate-btn | 是否显示转按钮 | boolean | `true` | +| is-show-confirm-btn | 是否显示确定按钮 | boolean | `true` | +| is-show-cancel-btn | 是否显示关闭按钮 | boolean | `true` | + + + +### 事件 Events + +| 事件名 | 说明 | 回调 | +| ------- | ------------ | -------------- | +| success | 生成图片成功 | {`width`, `height`, `url`} | +| fail | 生成图片失败 | `error` | +| cancel | 关闭 | `false` | +| ready | 图片加载完成 | {`width`, `height`, `path`, `orientation`, `type`} | +| change | 图片大小改变时触发 | {`width`, `height`} | +| rotate | 图片旋转时触发 | `angle` | + +## 常见问题 +> 1、H5端使用网络图片需要解决跨域问题。
+> 2、小程序使用网络图片需要去公众平台增加下载白名单!二级域名也需要配!
+> 3、H5端生成图片是base64,有时显示只有一半可以使用原生标签``
+> 4、IOS APP 请勿使用HBX2.9.3.20201014的版本!这个版本无法生成图片。
+> 5、APP端无成功反馈、也无失败反馈时,请更新基座和HBX。
+ + +## 打赏 +如果你觉得本插件,解决了你的问题,赠人玫瑰,手留余香。
+![输入图片说明](https://images.gitee.com/uploads/images/2020/1122/222521_bb543f96_518581.jpeg "微信图片编辑_20201122220352.jpg") \ No newline at end of file diff --git a/pages2/setting/limeClipper/images/photo.svg b/pages2/setting/limeClipper/images/photo.svg new file mode 100644 index 0000000..7b4b590 --- /dev/null +++ b/pages2/setting/limeClipper/images/photo.svg @@ -0,0 +1,19 @@ + + + + + + + + + diff --git a/pages2/setting/limeClipper/images/rotate.svg b/pages2/setting/limeClipper/images/rotate.svg new file mode 100644 index 0000000..0143706 --- /dev/null +++ b/pages2/setting/limeClipper/images/rotate.svg @@ -0,0 +1,15 @@ + + + + + + + + + + diff --git a/pages2/setting/limeClipper/index.css b/pages2/setting/limeClipper/index.css new file mode 100644 index 0000000..ce542bf --- /dev/null +++ b/pages2/setting/limeClipper/index.css @@ -0,0 +1,160 @@ +.flex-auto { + flex: auto; +} +.bg-transparent { + background-color: rgba(0,0,0,0.9); + transition-duration: 0.35s; +} +.l-clipper { + width: 100vw; + height: calc(100vh - var(--window-top)); + background-color: rgba(0,0,0,0.9); + position: fixed; + top: var(--window-top); + left: 0; + z-index: 1; +} +.l-clipper-mask { + position: relative; + z-index: 2; + pointer-events: none; +} +.l-clipper__content { + pointer-events: none; + position: absolute; + border: 1rpx solid rgba(255,255,255,0.3); + box-sizing: border-box; + box-shadow: rgba(0,0,0,0.5) 0 0 0 80vh; + background: transparent; +} +.l-clipper__content::before, +.l-clipper__content::after { + content: ''; + position: absolute; + border: 1rpx dashed rgba(255,255,255,0.3); +} +.l-clipper__content::before { + width: 100%; + top: 33.33%; + height: 33.33%; + border-left: none; + border-right: none; +} +.l-clipper__content::after { + width: 33.33%; + left: 33.33%; + height: 100%; + border-top: none; + border-bottom: none; +} +.l-clipper__edge { + position: absolute; + width: 34rpx; + height: 34rpx; + border: 6rpx solid #fff; + pointer-events: auto; +} +.l-clipper__edge::before { + content: ''; + position: absolute; + width: 40rpx; + height: 40rpx; + background-color: transparent; +} +.l-clipper__edge:nth-child(1) { + left: -6rpx; + top: -6rpx; + border-bottom-width: 0 !important; + border-right-width: 0 !important; +} +.l-clipper__edge:nth-child(1):before { + top: -50%; + left: -50%; +} +.l-clipper__edge:nth-child(2) { + right: -6rpx; + top: -6rpx; + border-bottom-width: 0 !important; + border-left-width: 0 !important; +} +.l-clipper__edge:nth-child(2):before { + top: -50%; + left: 50%; +} +.l-clipper__edge:nth-child(3) { + left: -6rpx; + bottom: -6rpx; + border-top-width: 0 !important; + border-right-width: 0 !important; +} +.l-clipper__edge:nth-child(3):before { + bottom: -50%; + left: -50%; +} +.l-clipper__edge:nth-child(4) { + right: -6rpx; + bottom: -6rpx; + border-top-width: 0 !important; + border-left-width: 0 !important; +} +.l-clipper__edge:nth-child(4):before { + bottom: -50%; + left: 50%; +} +.l-clipper-image { + width: 100%; + border-style: none; + position: absolute; + top: 0; + left: 0; + z-index: 1; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + transform-origin: center; +} +.l-clipper-canvas { + position: fixed; + z-index: 10; + left: -200vw; + top: -200vw; + pointer-events: none; +} +.l-clipper-tools { + position: fixed; + left: 0; + bottom: 10px; + width: 100%; + z-index: 99; + color: #fff; +} +.l-clipper-tools__btns { + font-weight: bold; + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; + padding: 20rpx 40rpx; + box-sizing: border-box; +} +.l-clipper-tools__btns .cancel { + width: 112rpx; + height: 60rpx; + text-align: center; + line-height: 60rpx; +} +.l-clipper-tools__btns .confirm { + width: 112rpx; + height: 60rpx; + line-height: 60rpx; + background-color: #07c160; + border-radius: 6rpx; + text-align: center; +} +.l-clipper-tools__btns image { + display: block; + width: 60rpx; + height: 60rpx; +} +.l-clipper-tools__btns { + flex-direction: row; +} diff --git a/pages2/setting/limeClipper/limeClipper.vue b/pages2/setting/limeClipper/limeClipper.vue new file mode 100644 index 0000000..96cccf9 --- /dev/null +++ b/pages2/setting/limeClipper/limeClipper.vue @@ -0,0 +1,816 @@ + + + + + \ No newline at end of file diff --git a/pages2/setting/limeClipper/utils.js b/pages2/setting/limeClipper/utils.js new file mode 100644 index 0000000..980c439 --- /dev/null +++ b/pages2/setting/limeClipper/utils.js @@ -0,0 +1,244 @@ +/** + * 判断手指触摸位置 + */ +export function determineDirection(clipX, clipY, clipWidth, clipHeight, currentX, currentY) { + /* + * (右下>>1 右上>>2 左上>>3 左下>>4) + */ + let corner; + /** + * 思路:(利用直角坐标系) + * 1.找出裁剪框中心点 + * 2.如点击坐标在上方点与左方点区域内,则点击为左上角 + * 3.如点击坐标在下方点与右方点区域内,则点击为右下角 + * 4.其他角同理 + */ + const mainPoint = [clipX + clipWidth / 2, clipY + clipHeight / 2]; // 中心点 + const currentPoint = [currentX, currentY]; // 触摸点 + + if (currentPoint[0] <= mainPoint[0] && currentPoint[1] <= mainPoint[1]) { + corner = 3; // 左上 + } else if (currentPoint[0] >= mainPoint[0] && currentPoint[1] <= mainPoint[1]) { + corner = 2; // 右上 + } else if (currentPoint[0] <= mainPoint[0] && currentPoint[1] >= mainPoint[1]) { + corner = 4; // 左下 + } else if (currentPoint[0] >= mainPoint[0] && currentPoint[1] >= mainPoint[1]) { + corner = 1; // 右下 + } + + return corner; +} + +/** + * 图片边缘检测检测时,计算图片偏移量 + */ +export function calcImageOffset(data, scale) { + let left = data.imageLeft; + let top = data.imageTop; + scale = scale || data.scale; + + let imageWidth = data.imageWidth; + let imageHeight = data.imageHeight; + if ((data.angle / 90) % 2) { + imageWidth = data.imageHeight; + imageHeight = data.imageWidth; + } + const { + clipX, + clipWidth, + clipY, + clipHeight + } = data; + + // 当前图片宽度/高度 + const currentImageSize = (size) => (size * scale) / 2; + const currentImageWidth = currentImageSize(imageWidth); + const currentImageHeight = currentImageSize(imageHeight); + + left = clipX + currentImageWidth >= left ? left : clipX + currentImageWidth; + left = clipX + clipWidth - currentImageWidth <= left ? left : clipX + clipWidth - currentImageWidth; + top = clipY + currentImageHeight >= top ? top : clipY + currentImageHeight; + top = clipY + clipHeight - currentImageHeight <= top ? top : clipY + clipHeight - currentImageHeight; + return { + left, + top, + scale + }; +} + +/** + * 图片边缘检测时,计算图片缩放比例 + */ +export function calcImageScale(data, scale) { + scale = scale || data.scale; + let { + imageWidth, + imageHeight, + clipWidth, + clipHeight, + angle + } = data + if ((angle / 90) % 2) { + imageWidth = imageHeight; + imageHeight = imageWidth; + } + if (imageWidth * scale < clipWidth) { + scale = clipWidth / imageWidth; + } + if (imageHeight * scale < clipHeight) { + scale = Math.max(scale, clipHeight / imageHeight); + } + return scale; +} + +/** + * 计算图片尺寸 + */ +export function calcImageSize(width, height, data) { + let imageWidth = width, + imageHeight = height; + let { + clipWidth, + clipHeight, + sysinfo, + width: originWidth, + height: originHeight + } = data + if (imageWidth && imageHeight) { + if (imageWidth / imageHeight > (clipWidth || originWidth) / (clipWidth || originHeight)) { + imageHeight = clipHeight || originHeight; + imageWidth = (width / height) * imageHeight; + } else { + imageWidth = clipWidth || originWidth; + imageHeight = (height / width) * imageWidth; + } + } else { + let sys = sysinfo || uni.getSystemInfoSync(); + imageWidth = sys.windowWidth; + imageHeight = 0; + } + return { + imageWidth, + imageHeight + }; +} + +/** + * 勾股定理求斜边 + */ +export function calcPythagoreanTheorem(width, height) { + return Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)); +} + +/** + * 拖动裁剪框时计算 + */ +export function clipTouchMoveOfCalculate(data, event) { + const clientX = event.touches[0].clientX; + const clientY = event.touches[0].clientY; + + let { + clipWidth, + clipHeight, + clipY: oldClipY, + clipX: oldClipX, + clipStart, + isLockRatio, + maxWidth, + minWidth, + maxHeight, + minHeight + } = data; + maxWidth = maxWidth / 2; + minWidth = minWidth / 2; + minHeight = minHeight / 2; + maxHeight = maxHeight / 2; + + let width = clipWidth, + height = clipHeight, + clipY = oldClipY, + clipX = oldClipX, + // 获取裁剪框实际宽度/高度 + // 如果大于最大值则使用最大值 + // 如果小于最小值则使用最小值 + sizecorrect = () => { + width = width <= maxWidth ? (width >= minWidth ? width : minWidth) : maxWidth; + height = height <= maxHeight ? (height >= minHeight ? height : minHeight) : maxHeight; + }, + sizeinspect = () => { + sizecorrect(); + if ((width > maxWidth || width < minWidth || height > maxHeight || height < minHeight) && isLockRatio) { + return false; + } else { + return true; + } + }; + //if (clipStart.corner) { + height = clipStart.height + (clipStart.corner > 1 && clipStart.corner < 4 ? 1 : -1) * (clipStart.y - clientY); + //} + switch (clipStart.corner) { + case 1: + width = clipStart.width - clipStart.x + clientX; + if (isLockRatio) { + height = width / (clipWidth / clipHeight); + } + if (!sizeinspect()) return; + break; + case 2: + width = clipStart.width - clipStart.x + clientX; + if (isLockRatio) { + height = width / (clipWidth / clipHeight); + } + if (!sizeinspect()) { + return; + } else { + clipY = clipStart.clipY - (height - clipStart.height); + } + + break; + case 3: + width = clipStart.width + clipStart.x - clientX; + if (isLockRatio) { + height = width / (clipWidth / clipHeight); + } + if (!sizeinspect()) { + return; + } else { + clipY = clipStart.clipY - (height - clipStart.height); + clipX = clipStart.clipX - (width - clipStart.width); + } + + break; + case 4: + width = clipStart.width + clipStart.x - clientX; + if (isLockRatio) { + height = width / (clipWidth / clipHeight); + } + if (!sizeinspect()) { + return; + } else { + clipX = clipStart.clipX - (width - clipStart.width); + } + break; + default: + break; + } + return { + width, + height, + clipX, + clipY + }; +} + +/** + * 单指拖动图片计算偏移 + */ +export function imageTouchMoveOfCalcOffset(data, clientXForLeft, clientYForLeft) { + let left = clientXForLeft - data.touchRelative[0].x, + top = clientYForLeft - data.touchRelative[0].y; + return { + left, + top + }; +} diff --git a/pages2/setting/setting.vue b/pages2/setting/setting.vue new file mode 100644 index 0000000..f75ef82 --- /dev/null +++ b/pages2/setting/setting.vue @@ -0,0 +1,333 @@ + + + + + + diff --git a/pages2/withdraw/withdraw.vue b/pages2/withdraw/withdraw.vue new file mode 100644 index 0000000..69bc934 --- /dev/null +++ b/pages2/withdraw/withdraw.vue @@ -0,0 +1,343 @@ + + + + + + + diff --git a/static/center/withdraw.png b/static/center/withdraw.png new file mode 100644 index 0000000..3b3529a Binary files /dev/null and b/static/center/withdraw.png differ diff --git a/static/del.png b/static/del.png new file mode 100644 index 0000000..a05fdeb Binary files /dev/null and b/static/del.png differ diff --git a/static/money.png b/static/money.png new file mode 100644 index 0000000..4d8a887 Binary files /dev/null and b/static/money.png differ diff --git a/uniCloud-alipay/cloudfunctions/gift_info/index.obj.js b/uniCloud-alipay/cloudfunctions/gift_info/index.obj.js new file mode 100644 index 0000000..03fc4ac --- /dev/null +++ b/uniCloud-alipay/cloudfunctions/gift_info/index.obj.js @@ -0,0 +1,24 @@ +const db = uniCloud.database(); +const _ = db.command; +module.exports = { + _before: function () { // 通用预处理器 + + }, + async getGiftList() { + try { + const res = await db.collection("gifts").get(); + console.log(res.data); + return { + code: 200, + data: res.data + } + } catch(e) { + console.log(e.message); + return { + code: 500, + msg: e.message + } + } + }, + +} diff --git a/uniCloud-alipay/cloudfunctions/gift_info/package.json b/uniCloud-alipay/cloudfunctions/gift_info/package.json new file mode 100644 index 0000000..1881fce --- /dev/null +++ b/uniCloud-alipay/cloudfunctions/gift_info/package.json @@ -0,0 +1,7 @@ +{ + "name": "gift_info", + "dependencies": {}, + "extensions": { + "uni-cloud-jql": {} + } +} \ No newline at end of file diff --git a/uniCloud-alipay/cloudfunctions/user-info/index.obj.js b/uniCloud-alipay/cloudfunctions/user-info/index.obj.js new file mode 100644 index 0000000..4c46b01 --- /dev/null +++ b/uniCloud-alipay/cloudfunctions/user-info/index.obj.js @@ -0,0 +1,185 @@ +const db = uniCloud.database(); +const _ = db.command; + +let obj = { + isValidIP(ip) { + // ------------------------- IPv4 验证 ------------------------- + if (ip.includes('.')) { + const ipv4Regex = /^(?:(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])$/; + return ipv4Regex.test(ip); // 直接通过正则匹配[1,5](@ref) + } + + // ------------------------- IPv6 验证 ------------------------- + if (ip.includes(':')) { + const parts = ip.split(':'); + // 处理压缩的::符号(如::1或2001:db8::1) + const hasDoubleColon = ip.includes('::'); + if (hasDoubleColon && ip.indexOf('::') !== ip.lastIndexOf('::')) return false; // 禁止多个::[6](@ref) + + // 分割后的段数应在1到8之间(允许压缩) + if (parts.length < 3 || parts.length > 8) return false; + + // 展开压缩段(如将::替换为填充段) + let expandedParts = []; + let fillZeros = 8 - parts.filter(p => p !== '').length; + for (let part of parts) { + if (part === '') { + while (fillZeros-- > 0) expandedParts.push('0'); + } else { + expandedParts.push(part); + } + } + if (expandedParts.length !== 8) return false; + + // 验证每段是否为1-4位十六进制字符 + const hexRegex = /^[0-9a-fA-F]{1,4}$/; + return expandedParts.every(p => hexRegex.test(p)); // 每段必须符合规则[6,7](@ref) + } + + return false; + }, + isReservedOrLocalIP(ip) { + // ------------------------- IPv4 处理逻辑 ------------------------- + if (ip.includes('.')) { + const parts = ip.split('.').map(Number); + // 格式验证 + if (parts.length !== 4 || parts.some(n => n < 0 || n > 255)) return false; + + // 1. 局域网地址(私有地址) + if ( + parts[0] === 10 || // 10.0.0.0/8 [1,2,4](@ref) + (parts[0] === 172 && parts[1] >= 16 && parts[1] <= 31) || // 172.16.0.0/12 [1,2,4](@ref) + (parts[0] === 192 && parts[1] === 168) // 192.168.0.0/16 [1,2,4](@ref) + ) return true; + + // 2. 保留地址 + return ( + parts[0] === 127 || // 127.0.0.0/8(环回地址)[1,4](@ref) + (parts[0] === 169 && parts[1] === 254) || // 169.254.0.0/16(链路本地地址)[4,5](@ref) + (parts[0] >= 224 && parts[0] <= 239) || // 224.0.0.0/4(多播地址)[3,5](@ref) + ip === '0.0.0.0' || // 未指定地址 [1](@ref) + ip === '255.255.255.255' // 广播地址 [1](@ref) + ); + } + + // ------------------------- IPv6 处理逻辑 ------------------------- + if (ip.includes(':')) { + // 规范化IPv6(展开缩写) + const normalized = ip.replace(/(^:|:$)/g, '::').replace(/::/g, ':0:').split(':') + .map(seg => seg.padStart(4, '0')).join(':').padStart(39, '0:'); + + if (normalized.startsWith('fc00:') || normalized.startsWith('fd00:')) return true; + + // 2. 保留地址 + return ( + normalized === '0000:0000:0000:0000:0000:0000:0000:0001' || + normalized.startsWith('fe80:') || + normalized.startsWith('ff00:') || + normalized.startsWith('2001:0db8:') || + normalized === '0000:0000:0000:0000:0000:0000:0000:0000' + ); + } + + return false; + }, + async getIPAddress(ip) { + if (!obj.isValidIP(ip)) return "未知"; + if (obj.isReservedOrLocalIP(ip)) return "未知"; + + let address = ""; + + const res = await uniCloud.collection("ip").where({ + ip: ip + }) + .get(); + + console.log(res); + + if (res.data.length > 0) { + const res = await uniCloud.collection("ip").where({ + ip: ip + }) + .field({ + ip:true, + country: true, + economize: true, + market: true, + }) + .get(); + if (res.data[0].market === "") address = res.data[0].country + " " + res.data[0].economize; + else { + address = res.data[0].economize + " " + res.data[0].market; + } + return address; + } + + let url= "https://62cccca0.api.cn/ipdata?token=7cec107b2f759a84211c74d9d9d6b4c4&datatype=json&ip=" + ip; + const response = await uniCloud.httpclient.request(url, { + method: 'GET', + timeout: 1000 + }); + console.log(response); + if (response.status === 200) { + await uniCloud.collection("ip").add({ + ip: response.data.ip, + country: response.data.data[0]==="台湾"?"中国台湾":response.data.data[0], + economize: response.data.data[1], + market: response.data.data[2], + county: response.data.data[3], + operator: response.data.data[4], + postal_code: response.data.data[5], + area_code: response.data.data[6], + network: response.data.data[7] + }); + if (response.data.data[2] === "" ) { + address = response.data.data[0] + " " + response.data.data[1]; + }else { + address = response.data.data[1] + " " + response.data.data[2]; + } + + return address; + } + return address; + + } +} +module.exports = { + _before: function () { // 通用预处理器 + + }, + + async get_user_info(query) { + try { + let uid = query.uid; + console.log(uid); + if (!uid) throw new Error("uid不存在"); + console.log(uid); + let res = await db.collection("uni-id-users") + .doc(uid) + .field({ + _id: true, + nickname: true, + avatar_file: true, + last_login_ip:true, + register_date: true, + last_login_date:true, + personal_profile: true, + gender: true + }) + .get(); + res.data[0].last_login_ip = await obj.getIPAddress(res.data[0].last_login_ip); + console.log(res) + + return { + code: 200, + data: res.data[0] + } + } catch (e) { + console.log(e); + return { + code: 500, + msg: e.message + } + } + } +} diff --git a/uniCloud-alipay/cloudfunctions/user-info/package.json b/uniCloud-alipay/cloudfunctions/user-info/package.json new file mode 100644 index 0000000..3315045 --- /dev/null +++ b/uniCloud-alipay/cloudfunctions/user-info/package.json @@ -0,0 +1,7 @@ +{ + "name": "user-info", + "dependencies": {}, + "extensions": { + "uni-cloud-jql": {} + } +} \ No newline at end of file diff --git a/uniCloud-alipay/database/gifts.schema.json b/uniCloud-alipay/database/gifts.schema.json new file mode 100644 index 0000000..c952e73 --- /dev/null +++ b/uniCloud-alipay/database/gifts.schema.json @@ -0,0 +1,37 @@ +{ + "bsonType": "object", + "required": ["price"], // 添加 price 为必填字段 + "permission": { + "read": true, + "create": "'admin' in auth.role", + "update": "'admin' in auth.role", + "delete": "'admin' in auth.role" + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "url": { + "bsonType": "string", + "title": "资源地址", + "description": "带签名时效的静态资源 URL", + "trim": "both", + "pattern": "^https?://", // 基础 URL 格式校验 + "errorMessage": { + "format": "URL 必须以 http/https 开头" + } + }, + "price": { + "bsonType": "int", + "title": "商品价格", + "description": "单位:分(整数类型)", + "minimum": 0, + "maximum": 100000000, + "errorMessage": { + "type": "价格必须为整数类型", + "minimum": "价格不能为负数", + "maximum": "单件商品价格不得超过100万元" + } + } + } +} \ No newline at end of file diff --git a/uniCloud-alipay/database/users-give-gift.schema.json b/uniCloud-alipay/database/users-give-gift.schema.json new file mode 100644 index 0000000..d758733 --- /dev/null +++ b/uniCloud-alipay/database/users-give-gift.schema.json @@ -0,0 +1,48 @@ +{ + "bsonType": "object", + "required": ["user_id", "article_id", "months", "create_time"], // 必填字段 + "permission": { + "read": true, + "create": "doc._id == auth.uid || 'admin' in auth.role", + "update": "doc._id == auth.uid || 'admin' in auth.role", + "delete": "doc._id == auth.uid || 'admin' in auth.role" + }, + "properties": { + "_id": { + "description": "ID,系统自动生成" + }, + "months": { + "bsonType": "int", + "title": "累计月数", + "defaultValue": 0, + "minimum": 0 + }, + "user_id": { + "bsonType": "string", + "title": "用户ID", + "foreignKey": "uni-id-users._id", + "trim": "both", + "errorMessage": "用户ID不能为空" + }, + "article_id": { + "bsonType": "string", + "title": "文章ID", + "trim": "both", + "errorMessage": "文章ID不能为空" + }, + "gift_value": { + "bsonType": "int", + "title": "礼物价值", + "minimum": 0, + "defaultValue": 0, + "errorMessage": "礼物价值不能小于1" + }, + "create_time": { + "bsonType": "timestamp", + "title": "创建时间", + "defaultValue": { + "$env": "now" // 自动填充服务器时间[1](@ref) + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uni-notice-bar/changelog.md b/uni_modules/uni-notice-bar/changelog.md new file mode 100644 index 0000000..ce50674 --- /dev/null +++ b/uni_modules/uni-notice-bar/changelog.md @@ -0,0 +1,20 @@ +## 1.2.2(2023-12-20) +- 修复动态绑定title时,滚动速度不一致的问题 +## 1.2.1(2022-09-05) +- 新增 属性 fontSize,可修改文字大小。 +## 1.2.0(2021-11-19) +- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-notice-bar](https://uniapp.dcloud.io/component/uniui/uni-notice-bar) +## 1.1.1(2021-11-09) +- 新增 提供组件设计资源,组件样式调整 +## 1.1.0(2021-07-30) +- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) +## 1.0.9(2021-05-12) +- 新增 组件示例地址 +## 1.0.8(2021-04-21) +- 优化 添加依赖 uni-icons, 导入后自动下载依赖 +## 1.0.7(2021-02-05) +- 优化 组件引用关系,通过uni_modules引用组件 + +## 1.0.6(2021-02-05) +- 调整为uni_modules目录规范 diff --git a/uni_modules/uni-notice-bar/components/uni-notice-bar/uni-notice-bar.vue b/uni_modules/uni-notice-bar/components/uni-notice-bar/uni-notice-bar.vue new file mode 100644 index 0000000..47fb9b3 --- /dev/null +++ b/uni_modules/uni-notice-bar/components/uni-notice-bar/uni-notice-bar.vue @@ -0,0 +1,431 @@ + + + + + diff --git a/uni_modules/uni-notice-bar/package.json b/uni_modules/uni-notice-bar/package.json new file mode 100644 index 0000000..1e9762c --- /dev/null +++ b/uni_modules/uni-notice-bar/package.json @@ -0,0 +1,87 @@ +{ + "id": "uni-notice-bar", + "displayName": "uni-notice-bar 通告栏", + "version": "1.2.2", + "description": "NoticeBar 通告栏组件,常用于展示公告信息,可设为滚动公告", + "keywords": [ + "uni-ui", + "uniui", + "通告栏", + "公告", + "跑马灯" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, +"dcloudext": { + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", + "type": "component-vue" + }, + "uni_modules": { + "dependencies": [ + "uni-scss", + "uni-icons" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "u", + "联盟": "u" + }, + "Vue": { + "vue2": "y", + "vue3": "y" + } + } + } + } +} diff --git a/uni_modules/uni-notice-bar/readme.md b/uni_modules/uni-notice-bar/readme.md new file mode 100644 index 0000000..fb2ede2 --- /dev/null +++ b/uni_modules/uni-notice-bar/readme.md @@ -0,0 +1,13 @@ + + +## NoticeBar 通告栏 +> **组件名:uni-notice-bar** +> 代码块: `uNoticeBar` + + +通告栏组件 。 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-notice-bar) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 + +