diff --git a/static/animation/bj2.json b/static/animation/bj2.json new file mode 100644 index 0000000..c0bb468 --- /dev/null +++ b/static/animation/bj2.json @@ -0,0 +1 @@ +{"v":"4.8.0","meta":{"g":"LottieFiles AE 3.4.5","a":"","k":"","d":"","tc":""},"fr":25,"ip":0,"op":250,"w":1125,"h":2436,"nm":"bj 2","ddd":0,"assets":[{"id":"image_0","w":510,"h":1004,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_1","w":418,"h":1004,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_2","w":325,"h":956,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_3","w":232,"h":731,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_4","w":140,"h":476,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_5","w":47,"h":221,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC8AAADdCAYAAAArfSu+AAAACXBIWXMAAAABAAAAAQBPJcTWAAAAJHpUWHRDcmVhdG9yAAAImXNMyU9KVXBMK0ktUnBNS0tNLikGAEF6Bs5qehXFAAAEQUlEQVR4nO2dy1LjQAxFrxwI8P8fC+ThnsWMKY+x3U+1dKv6bEhCyjklriXZWYAQwhtImQBcQwgv1iIlTP9+vocQxNSkgEVeAHxYipQwrR5f2PI/bZ5fQwjb19yyJ/rBkv89+QnAe2+REo4i8hJCeO1qUsBZvt+85/9Mzn37jFV28tw+U2Lhdn1IzbTL9SFV3mX+c7qJu/UhtxW6Wh9KRNysDyXybtaH0gi4WB9q8mu+PtR8uHn7rK2c6frQ4s9utj60yqzJ+tBK3iT/LbtF9/Whdavruj5ofFC39UFDfgJwVTju7gdpcA0hXJSO/YNmPtXjoykvUI6PdmdQjU+PtqY2fXvIq3WfXgNFZXj1vJhofunYU/7SenXufRn31vLk7S3f9OS1uIB+bVV9C3kB0GTvt7p18dqidVred6nOvqV8dfWt7/hWDS5r+UtN9a3lgYrse5Avzr4HeaCw+l7ki6rvRR4Asr+scCWfu/N4khcAWfu+J3kg88T1Jj/l3CrxJg9knLgu5VNPXI/yQGL1h7wCU8rE9SoPJFTfs3x0YHmWj0bHszwQiY53+dPoeJc/jY53eeAkOgzyh9FhkD+MDoM8cFB9FvndHX/Id0D2rrBY5IGd3DPJU1eeWh7bfk8lj03u2eSpK/9f7tnkp/U9HTZ5YOXMKP8THUZ56spTy1PH5mfSUsrj71dAtPIXgFd+VN4UVvnRbcwIIQitPABqed7YAJiY5UdszGCWp44NtTx1bIa8GUPeiiFvxZC3YshbwSw/M8tTV37IW/FklqeuPK+8iIxWacEM8MoHgFd+VN6KJ8Arz1t5EaGt/Lw8YJQPywNG+efygFGeOja8lRcR2so/10+GfEeo5ef1Eyb5eX2yAlzyz+0LQ74TtPK/8g7wyD/2XmSR/xUZgEReRGgrvysODHl1aOUfIhKOfule/uyXQ16J08gAzuVjb/AqH0AsH40M4Ff+nvImj/Lzchc4hkf5pKoDQ74p95QTdcGb/C3nzZ7kn3vXqWd4kk/O+oIX+VlEaOWzsr7gQb6o6oAP+egCdoS1fEBhZAB7+ayhtMVSvqrqgK38d03VATv54g6zxkq+Ki4LFvLPFlUHbOS/Wx2ot/w99RIvhZ7y1a1xS0/5e+6+HqOX/CwizbK+0Ev+S+OgPeRvLU/SNdryzU/SNdryX7X7yxma8o+jryBboSUfoHSSrtGS/9SMy4KGvFp32dJaXmUYHdFSPgD4bHi8KC3lb613lxit5B8iojaMjmghP6NDW9yjhbzqFD2jVr5bW9yjRv7Zsy3uUSrfZfzHKJX/6t0W9yiRv2lvi6nkys9QvLjIJUc+oNO2mEqOfPfxHyNV3mT8x0iRNxv/MVLkzcZ/jJi86fiPcSZvPv5jHMm7GP8xjuRdjP8Ye/Juxn+Mrbyr8R9jLe9u/MdYy7sb/zEWeZfjP8YEx+M/Sum/bvfAH7/CK8vw+/BzAAAAAElFTkSuQmCC","e":1},{"id":"image_6","w":155,"h":139,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJsAAACLCAYAAAB2t+sXAAAACXBIWXMAAAABAAAAAQBPJcTWAAAAJHpUWHRDcmVhdG9yAAAImXNMyU9KVXBMK0ktUnBNS0tNLikGAEF6Bs5qehXFAAAEIUlEQVR4nO3d2W7bMBBA0Ym8xMn/f2rf2QePEkaWLIkajrjcAwQpCrR16oshtdj+EMBICOFDRIbo6yIi4+/9u5742FCpEMIgz4jGfi7yDOrj3Z8jNizSqMYJNcZ0Sf37iA0SQhhjmi59poitE9HSd4m+ry59loitMZP91Dihkpc+S8RWMT36u0RfrpNqL2KriE6taVzVILaC6eS6SqVxTRFbYXR6XUXkJpXHNUVsBdDAbvJ8PpoKLEZsJ+klsBixOdI92E0aXCK3IDYHIYRxD9b1/3fXP3xOvU+xOcRmTPdid/k9gw9FbEb0YvanFHJpqETEdhCRbUdsiYhsP2LbicjSEdtGRHYcsa2Iji5vZz+W2hHbAj1PdtcvGCC2GSGEmzwj42SsIWKL6JL5EPZlWRCbCiF8CktmVt3HpkeZD2HJzK7r2JhmvrqMTfdmX8I0c9VdbEyz83QTG0ea5+siNr1T9iHcX3aq5mNj2SxHs7Hp5aYvYdksRpOx6f7sW1g2i9JcbHpd83H248CrpmJjf1a2JmLT/dlDGvl5WlX9k6OhfQtXA4pXdWxcdqpLtbFxxFmfKmPT24K+hNCqUl1snNqoV1V7HUKrWzWxEVr9qoiN0NpQfGyE1o6iYyO0thQbW/SqJzSiyNiiKwNoSHGxcWWgXUXFFt1dS2gNKiY27t5oX0lPLG+B0Lginly9w7a667TY5/TYovdCQ+NOjS16lTo6cFps0ZEnOnHmZON27s6c8mTrAQGvVO+Me2x6zZMDgg65xsY+rW/ek41LUR1ziy2EcBf2aV1ziU3Pp316/Fsol9dkY5+G/LHpaQ7OpyFvBNEn2gHZJw7LJ35ki43lE1NZYtDlkw+DxR+5Jg+fOYAX5rHpB1xw8hYvTGPTa5+cvMUs68nGR11jkVkYHBRgjeUUugsHBXjDJDamGrawmmy8QgqrDsemt3lzqgOrLCYbpzqwyaHYmGrY4+hkY6phs+TYmGrY68hkY6phl6TYmGpIkTrZOIGL3XbHxtUCpEqZbISGJLti0/vViA1J9k62q3BnBxLtjY3XgCLZ5tj0dAd34SLZnnjYq+GQTbHpgQGfU4BDtk42Dgxw2NbYWEJx2GpsesWA66A4bMtkY68GE1tiYwmFibex6RLKuTWYWAuJJRRm1mJjCYWZxdhYQmHtXUwsoTD1LjbOrcEUkw1uZmPTtyoFTC1NNpZQmFuKjckGcy+x6b1rnPKAubmoWEKRBbHBzVxs7NeQxVxs7NeQxZ+w9OV6QBbTKcYSimymsbGEIhtigxtig5ufuDg4QG7xJCM2ZBXHxtsrICsmG9ww2eBmWPg1YG4Q4UgUPsZpxhKK7MbYmGzIbph8B7IhNrghNrgZ9A1kgOwG4UgUTgbh7lw4YbLBDW/4Bzd8xgHcMNXg5j8p6Qrbnbnt2QAAAABJRU5ErkJggg==","e":1},{"id":"image_7","w":220,"h":204,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_8","w":285,"h":269,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_9","w":349,"h":334,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_10","w":414,"h":399,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_11","w":479,"h":464,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_12","w":544,"h":529,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_13","w":609,"h":593,"u":"","p":"data:image/png;base64,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","e":1},{"id":"comp_0","layers":[{"ddd":0,"ind":2,"ty":0,"nm":"预合成 1","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[562.5,1218,0],"ix":2},"a":{"a":0,"k":[562.5,1218,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1125,"h":2436,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":0,"nm":"预合成 2","refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[562.5,1218,0],"ix":2},"a":{"a":0,"k":[562.5,1218,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1125,"h":2436,"ip":0,"op":250,"st":0,"bm":0}]},{"id":"comp_1","layers":[{"ddd":0,"ind":1,"ty":2,"nm":"图层 25","refId":"image_0","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":125,"s":[100]},{"t":152,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[254.887,678.385,0],"ix":2},"a":{"a":0,"k":[254.887,501.995,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":2,"nm":"图层 24","refId":"image_1","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":100,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":140,"s":[100]},{"t":171,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[208.575,678.385,0],"ix":2},"a":{"a":0,"k":[208.575,501.985,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":2,"nm":"图层 23","refId":"image_2","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":75,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":140,"s":[100]},{"t":194,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[162.262,678.385,0],"ix":2},"a":{"a":0,"k":[162.262,477.965,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":2,"nm":"图层 22","refId":"image_3","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":50,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":140,"s":[100]},{"t":215,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[115.95,678.385,0],"ix":2},"a":{"a":0,"k":[115.95,365.235,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":2,"nm":"图层 21","refId":"image_4","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.138],"y":[0.002]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":25,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":140,"s":[100]},{"t":236,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[69.638,678.385,0],"ix":2},"a":{"a":0,"k":[69.638,237.745,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":2,"nm":"图层 19","refId":"image_5","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[100]},{"i":{"x":[0.465],"y":[1.014]},"o":{"x":[0.338],"y":[0.001]},"t":140,"s":[100]},{"t":249,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[23.326,678.385,0],"ix":2},"a":{"a":0,"k":[23.326,110.265,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0}]},{"id":"comp_2","layers":[{"ddd":0,"ind":1,"ty":2,"nm":"图层 35","refId":"image_6","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":12,"s":[100]},{"i":{"x":[0.886],"y":[0.997]},"o":{"x":[0.986],"y":[0.003]},"t":138,"s":[100]},{"t":249,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1047.857,2366.6,0],"ix":2},"a":{"a":0,"k":[77.143,69.4,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":2,"nm":"图层 34","refId":"image_7","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.35],"y":[0.995]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":25,"s":[100]},{"i":{"x":[0.856],"y":[0.99]},"o":{"x":[1],"y":[0.007]},"t":138,"s":[100]},{"t":236,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1015.423,2334.165,0],"ix":2},"a":{"a":0,"k":[109.577,101.836,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":2,"nm":"图层 33","refId":"image_8","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.33],"y":[0.991]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":40,"s":[100]},{"i":{"x":[0.865],"y":[0.995]},"o":{"x":[1],"y":[0.008]},"t":138,"s":[100]},{"t":222,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[982.988,2301.73,0],"ix":2},"a":{"a":0,"k":[142.012,134.27,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":2,"nm":"图层 32","refId":"image_9","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.309],"y":[1.008]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":57,"s":[100]},{"i":{"x":[0.879],"y":[0.994]},"o":{"x":[1],"y":[-0.007]},"t":138,"s":[100]},{"t":209,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[950.553,2269.295,0],"ix":2},"a":{"a":0,"k":[174.447,166.705,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":2,"nm":"图层 31","refId":"image_10","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.264],"y":[0.997]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":76,"s":[100]},{"i":{"x":[0.874],"y":[1.002]},"o":{"x":[1],"y":[0.003]},"t":138,"s":[100]},{"t":194,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[918.118,2236.861,0],"ix":2},"a":{"a":0,"k":[206.882,199.139,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":2,"nm":"图层 30","refId":"image_11","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.346],"y":[0.998]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":95,"s":[100]},{"i":{"x":[0.836],"y":[0.999]},"o":{"x":[1],"y":[-0.007]},"t":138,"s":[100]},{"t":179,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[885.684,2204.426,0],"ix":2},"a":{"a":0,"k":[239.316,231.574,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":2,"nm":"图层 29","refId":"image_12","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.323],"y":[0.991]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":113,"s":[100]},{"i":{"x":[0.865],"y":[1.002]},"o":{"x":[1],"y":[0.012]},"t":138,"s":[100]},{"t":164,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[853.249,2171.991,0],"ix":2},"a":{"a":0,"k":[271.751,264.009,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":2,"nm":"图层 20","refId":"image_13","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.331],"y":[1.008]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":131,"s":[100]},{"i":{"x":[0.893],"y":[1]},"o":{"x":[1],"y":[0]},"t":138,"s":[100]},{"t":149,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[820.814,2139.556,0],"ix":2},"a":{"a":0,"k":[304.186,296.444,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":250,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"bj","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[562.5,1218,0],"ix":2},"a":{"a":0,"k":[562.5,1218,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1125,"h":2436,"ip":0,"op":250,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/static/animation/home.json b/static/animation/home.json new file mode 100644 index 0000000..7964467 --- /dev/null +++ b/static/animation/home.json @@ -0,0 +1 @@ +{"v":"4.8.0","meta":{"g":"LottieFiles AE 3.4.5","a":"","k":"","d":"","tc":""},"fr":25,"ip":0,"op":150,"w":428,"h":235,"nm":"首页背景 2","ddd":0,"assets":[{"id":"image_0","w":10,"h":45,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAtCAYAAACXm/ozAAAACXBIWXMAAAABAAAAAQBPJcTWAAAAJHpUWHRDcmVhdG9yAAAImXNMyU9KVXBMK0ktUnBNS0tNLikGAEF6Bs5qehXFAAAAxklEQVQ4jd3VwRKCMAxF0ZuCiv//sSAoz00ZEdsmC93YHZ0zL2naGQxnSeqANTnIgAGgCTNKTSjpDPTbdxFKSsB5v1dLvALWhJIupf10QB8la4lDpZUXzIPtXFgr+QZzb70LgVML7WEzDSDlst6dk2ic9AjdtN8lmquiaX8JH1G4fh3eQ9DM1kjqdmo3dYNLCEbK7wc+h6CZLa3U4xVOIWhmDyoTKD2KCZALzUzAGEncWphdmPGN3RS8hztS6Le4JJ3yHyy2ntNJPFxmo4R5AAAAAElFTkSuQmCC","e":1},{"id":"image_1","w":28,"h":96,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAABgCAYAAAAO7RIuAAAACXBIWXMAAAABAAAAAQBPJcTWAAAAJHpUWHRDcmVhdG9yAAAImXNMyU9KVXBMK0ktUnBNS0tNLikGAEF6Bs5qehXFAAAB8ElEQVRoge2Yy3LCMAxFr4AC+f+PLYSAuhEMpHnY8pW6aLwET87Yso4tAYlDVbtdIuwI4JACVNUdgCMAZK2wAyApQFU9vXNCgap6gG1lOFBVBcB5/HvkCl9xCwda3PZT/9GB7ykQDrS4dUtz2Cs8r32TBlTVLwCHtXkUoMXtVDKXtcLJFAgBjtUVCpxSVxhwTl1hQFTErRm4pC46cE1dVGCJuqhAFKiLBixVFwVYoy4KEM4UcAFr1dUE9KjLDfSqyw0EMW6rwBZ1VQNb1VUNRKO6qoBWw4XWG6+P26kM28pfQIPRT+USsFnMxUAzSko1/ISkrO5vgKq6R8JheQGRuLonMK059H+AqWMDbkAX8JEN1GzgfQNSgSKimdBnWtyygQOSTusOAGxbhzSgjT4VKCKPDOjYpT2CY/kBtFhe0oAGHRB4gOaupwuCbpFJYOTWzl7AInJHwKldvPFF5AqyZ0ueGBcQU2UVaEKgxbPoEWWpQolnzautByFVioGWKt9ojGfVu5Qh+OqHsIj0aFCf9+XtVp8L2KI+d23hVV9TMeNRH6N6qlJfM7BWfZT6sEZ9zIK0SH00YKn6qCV3ifroNf6a+qKaCrPqCwEuqS+sbTKnvtA+zZT6MhpDH+oLB47Vl9L6MvXd0oA2rkhus0FV5QekQqrBWNTHKQAAAABJRU5ErkJggg==","e":1},{"id":"image_2","w":47,"h":142,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC8AAACOCAYAAAChZ1HnAAAACXBIWXMAAAABAAAAAQBPJcTWAAAAJHpUWHRDcmVhdG9yAAAImXNMyU9KVXBMK0ktUnBNS0tNLikGAEF6Bs5qehXFAAADiUlEQVR4nO2d207sMAxFt8tt+P+P5Y55IK3CkNZNYseONOuNYQRLPmbbk1Q6hAlh5gUAL94ijTwDwHTyzPyE5D2VPDPfA3hcv55GnpkJwCV/bRp5/PY55S9MIZ/6/O769fDyKRYfS98LLZ/6/Hnv+6Hl8fsHuusYVp6ZHwDcH70npHzq8yfpfSHlUYjFEuHk8/EvEUqeme+wE4slwshLsVgijDxO9nlOCHlmfkRh/Eu4y5+NxRKu8i19nuNd+dOxWMJNPo3/h56f4SLf0+c5XpWvjsUSw+Vrxr/EUPna8S8xTL43FkuMrLxKn+cMkW8d/xLm8lqxWMJU3qLPc6wrrxaLJcx+sMb4lzCRt+zzHKvKq8diCXV5zfEvofpLtMe/hJq8dSyW0Kz8kD7PUZG3Gv8S3fKjYrFEl7xHn+f0Vn5YLJZo/sXpTtR0/Es0yac+v4hvNKa18sNjsUS1/MjxL1ElMXr8S5yW947FEjWVvyBAn+eckk/j//BO1ANR3nP8SxzKR+zzHKnyYWKxxK5YhPEvUZSPMv4l9iofYvxL/JOPNP4l/kgePRIVkesKh8zzPTb5tHSFm6JH5JUPHYslFmDr9TnlMVm7rKzy01UdAJbUMlPk+jULHI7ptJi26sCt8n4smGB73GPaqgM3eT9u8l5ML//lLdHKAuDbW6KV6eU/vSVaWYjoGwB7i7Swps2U1V/lP1wtGlkAgIi+MOEfbj6k3t0sGtnkiegDk1X/ej14c7Fo5I88EX1ionWhtJi9YpLc/yefhtarg0s1xZU4tU/47D/a598QPH125YmIAbwMdKnm8JNU6v+w8Sl+DCSidwRd3M5+hg0Zn6fko/b/6dODtHmGWt6qjj6IKFR8tpzbvCBI/1fLR1ofmk7MoqwPPcd97v3fLB8hPrsOWr3Xh+5T4rQ+uHz60jridolPFXmv/le7XPBYH1RvRkavDxbXOsP6X11+ZHyaXKilo0Pz9cHyNtC8/83kR8Sn6T2sdf+bXyJbrg+jbsBN4nOIvFX/D3v2wGJ9GPrghPb64PHUh1r/D5fXjE+X52201gfPh4W6+99NXiM+XR/T6u1/92fMetYHd/lEU3yGkG/t/xDyQNv6EEYeqF8fQsknTvU/EcX7DyNq4jOcPHBqffgEgsonjvo/tvxBfH6nf5m48sDW/9fxuX0dWh7Y4nNdH7aqAxPIJ9b4DHGFqsIPCggNMVkUJkcAAAAASUVORK5CYII=","e":1},{"id":"image_3","w":66,"h":172,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAACsCAYAAADPGnoaAAAACXBIWXMAAAABAAAAAQBPJcTWAAAAJHpUWHRDcmVhdG9yAAAImXNMyU9KVXBMK0ktUnBNS0tNLikGAEF6Bs5qehXFAAAEx0lEQVR4nO2d2XLbMAxFL5W9/f9fbRPHFvpg2KUdytBCEgCp85jJONQZCLiSKAfoGCIaiOg3ADxrL0YLInoB8AYgAJ2KYAnv8c8GpbWokZIAdCZiSgLQkQgiesaEBKATEUQ04IEEoBMRAD7A02GK5kUQ0RtmHGfTIojoCcDrnN9tVgQRBQh9IaZZEThLmH18TYogolcsTM3NieBROasvxDQlgvuCOCpTNCUC50pYdUzNiOAIvfiUuNCEiDkRWqIJEThLWNwXYtyL4Aj9tPVzXItYEqEl3IpYGqEl3IrAwggt4VLEmggt4U7E2ggt4UrElggt4UoENkRoCTcitkZoCRcickRoCRcikCFCS5gXkStCS5gWkTNCS5gVkTtCS5gVgcwRWsKkiBIRWsKciFIRWsKUiJIRWsKUCBSM0BJmRJSO0BImRNQelSlMiIBSX4hRF1ErQkuoitAalSnURESj0gSaFVE1QkuoLIQ3fpra/lxdBPeFt9p/V0KjItRHZYqqIubuedSg2qK0I7REFREWIrRErYow2RdiiouwEqElioqwFKEliomwFqElSlaEqQgtUWShFiO0RHYRViO0RImKMD8qU2QVYTlCS2RbtPUILZFFhIcILZGrIlz2hZjNIrxEaIlNIjxFaInVIrxFaIktFeEqQkusOhCPEVpisQivEVpiTUW4H5UpFonwHKElZh9UzT2PGswS0dqoTDG3IprsCzGiCN7z6D5CSzwU0eqoTDEpooe+EPOoIpodlSmSB8oR+qXyWlT5IaKnvhCTqojirw1Z5EYEnxLNj8oU9xXRbISWuIrgauhmStwTH3i31QCwCL6y7LYagP8H31VmSHER0dT9xzUMHKC6yw33DNirAcBZRJcB6p79tGD2imC6zg4xuwhmF8HsIphdBLOLYAYApL0ICwwARu1FWGAAcNJehAX2imD2imCGEMKIvSqu4/NbdRUGuIg4qq7CAAMA8OnRdVXEyfKgtgoDXEX0XhX31xoHdBq5b0RwVXR5ivy4+gwhHNBhyJq6DP9EZ6dIUgSfIp+V16LK5I2ZEMIRHfUL6Q7VAZ1chzwUEUIgAH/RQb8Q71n2MlJn3bzlkdr0hdmSu9ifaLhfzBbB/aLZkbrouUYI4YRG+8XiBzwhhC80GMHXPulqLoKvEtFiBF/97LO1CL71IXAzEXyTiJYi+OZtAa1E8Cz7I1qI4Dk3iriO4NlEeI/gWbcOeY7g2fdQcQR3d4qU2kzmbqQWEeExghfbXsgR3M2z1NL7LN30i6IioghunuI7b7lffJX+O1upsgXZQwSvuRfb9F2taiKs94uqu/MtR/DqrylYjeBa72uYi+AqIixGcLU3eKxFcO1Xmcz0C1URlkaqdkWYieDqIgAbEdyECEY1gpsRod0vzIgA1CL4CBgTAahEcJsimJoR/AQYFVE5gh8BoyKAahH8xNLtimBK94trkDMtovBIPfGUAmBcBFA0gt/0IPMigCKvVx0uveGCCxFMrpF64qxygxsRmfrFOPUZbkQAmyP4COAPC/2BKxHA6gh+xAMJgNMv7OPv4PwFef2Ec2MUq8ilCOD6rc2P/n/gNxLTYQq3IgCAiN5x+329I86nwfdcARe8iwg4ixgBjEsPPuYfCEp3252A2akAAAAASUVORK5CYII=","e":1},{"id":"image_4","w":84,"h":177,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAACxCAYAAABa4prwAAAACXBIWXMAAAABAAAAAQBPJcTWAAAAJHpUWHRDcmVhdG9yAAAImXNMyU9KVXBMK0ktUnBNS0tNLikGAEF6Bs5qehXFAAAFLElEQVR4nO2d2XbjOAwFL9Xpjnv+/1snibNgHkxpmFgytEAkAKLOyVscUxUaxpVIKSFgIaIBwBOAIf/8WvjVl6dqozJGlvgHN3nD2teF0B8Q0W/cRK6WWBJCM0T0BOAZO0WOdC+UiBKAC4RcdC00z8oLgCT1N7sVSkTPuNVKUboUSkQXAL/P+NuHCrBFzpQJdCb0bJlAR0Jzf3mqTKAToTn1XGq8l3uhuc/8W+v93AuFQPrZgmuhtepmiVuhuW4+135ft0Jxq5tikXItLoXmWNnk2NwJJaJfOCGjr8WV0Not0hyuhKJR3SxxI5SIxus/TXEhtFWLNId5oRrqZol5oagcLTnUDGQPLaIlh1mhmupmiVmhUNAizWFSaMtoyaFyUI9oHS05TAnV1iLNYUoolNbNEjNCtURLDhNCtbZIc6gXaqFulqgXCmXRkkP1QDVGSw61Qi3VzRK1QmGgRZpDpVDN0ZJD3aC1R0sOVUKttUhzqBIK4Q0ELVAjNEdL82v+VQi12iLN0Vyoh7pZ0lwojEVLjqYHkneymYqWHM2E1txIUJOWM9RktORoItRytOSoflDWoyVHVaHeWqQ5as9Q89GSo5pQL9GSo4pQT9GS43ShPdTNkhoz1G2LNMepB+oxWnKcJtRrtOQ4c4a6jJYcpwj1HC05xA/ae7TkEBXaW4s0h/QMdR8tOcSE9hItOUSE9hQtOQ4Ljbr5HYkZ2m2LNMchET1GS47dQnuNlhxHZmiX0ZJjl9CeoyXHZim9R0uOTUKLO2oHC2ydoZcdr+mK1XIiWq5jldDiuRgBAyu0iJbRIq1gzQzd/aCRHnkoKkfL+KhvYFFoRMt9PJqh3Z9938Os0Bwt1d+OQiN3QiNaHmNuhkbdPMA3oXEW6TiTvNzAx9n3g5Sz8Q/iW/0wpdA48SHAAEyJKGqnAKPEqJ1CjELj4y7EkBv5QIjxqdSBEOPjvQMhQqgwIVSYkClMCBUmhAoTQoUJocKEUGEGAF+tB+GJAQC1HoQnBgCfrQfhiRAqTAgVZkgpEYCP1gPxwtg2hVAhSqHxbS/AAAD5Y//eeCwuKJNSCBVgEppS+gJwbTgWF/zM8ldELT3EN6G5lr42GosL7s42pZQ+EPV0N0un794QZ6F2MSs0f/RfKo/FBYsnmPO3/lvFsbjg4Rn7lNIVcfJkE2sugbwgWqnVsEKjnm5j1UW6lNInIkWtYvVVz5RStFIr2HoZOeopwyah0UrxbF7okFJ6R0TTRfauHIl6usAuodFKLbN7bVPU03kOLRaLaHqPxOq7aKUKDguNevodkfWhEU3/R2zBbUTTG9IrmLuvp6JCo5U6YY19jqbdLj47a9PCKzqtp6cI7bmVOm1bTa9rpU7dp5Rbqa6iaY2NX121UqcL7W0BWpWtiXkBWhf1tNpez16iae3Ns+7raVWhPUTT6tu7vUfTVvvl3UbTJkI9R9Nmd3TwGk2b3iLDYzTVcM8RV61Uc6HeomlzoYCvaKpCKOAnmqoRmrFeT0mVUAfRVJdQwHw01Sc0YzGaUkpJp1Cj0fQD0PelNGEwml4BxUIBU9H0M08A3UIzr9DfSk2diXqh+T+vOZp+5PWxAAwIBVRH07t/tgmhmSt0tVIE4CV3JBNmhBatlJZ6+jZ+EZWYEQqoaaUIwGtOdHeYfAYdEf1Fm6fsfOH2MV8sPaZmaEGLaPoO4N9HMgGjMxSYnpD7T4W3+sStXq4KGGaFAtODXc947PB4198rNyN/YlooMM1UieOg8ednK7SF/wCkx4kWU6leTAAAAABJRU5ErkJggg==","e":1},{"id":"image_5","w":103,"h":177,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGcAAACxCAYAAADZJqPLAAAACXBIWXMAAAABAAAAAQBPJcTWAAAAJHpUWHRDcmVhdG9yAAAImXNMyU9KVXBMK0ktUnBNS0tNLikGAEF6Bs5qehXFAAAF2ElEQVR4nO2dbW/bNhRGD9VmLRpkTTfs//++fVibNmuaxEu4D2YMx7FNS+bLJfkcIECBts6VTq5IPRIZh4jivb8AfgMugPfhz4d4Bv4DVuHrwTn3tOT7uiX/aQSCkEvgA/DuzI9bAXfA/RxRkrOD9/4TaykXmb7FE3AP3DnnVsf+oeQEvPcfgc+c3yVzOCpqeDne+wm4Bj5WLuWNqKHlhG65Bqbatezw5Jz7+33tKmrhvb8CrmrXcYB3sJ4WDof3/hr4VLuOGNbaOTutiIHB5LQkBgaSE+5fmhEDg8gJd/vXteuYS/dywn3MH7XrWEL3coDfKXvXn4yu5bQ4zmzTrRzv/TvWXdMs3cphPc40fXxNF38I7/1n8kX+xehOjvf+A+vnMc3TlZwwbf5Su45UdCWHDsaZbbo5EO/9JcdfvGiOLuSEeOZz7TpS07ycluOZGM3LoeF4JkbTclqPZ2I0K6eHeCZGs3LobNq8jyYPrpd4JkZzcnqKZ2I0Jae3eCZGU3IYYJzZppkD7TGeidGEnF7jmRjm5fQcz8QwL4eO45kYpuX0Hs/EMCtnhHgmhlk5DDZt3ofJgx8lnolhTs5I8UwMU3JGi2dimJKDzcWz1TBzIkI8U3u5uSlMyBk1nolRXc7WJg1ih+pyWN9oDj9t3kdVOWEHjWHjmRjV5IR4RpezI9TsnOHjmRhVTk7Yd0bjTITickI8Y3VDIFMUlaN4Zh6lO0fxzAyKnSjFM/MpIkfxzDKyy1E8s5wSnaN4ZiFZ5SieOY9schTPnE/OzlE8cyZZTp7imTQkl6N4Jh1J5SieSUvqzlE8k5BkJ1LxTHqSyFE8k4ez5SieyUeKzlE8k4mz5CieyctiOYpn8nNO5yieycyik6t4pgyz5SieKccsOZo2l2Vu51wz6J4ANThZjuKZ8pwkJ8QzGmcKE5WzNc5o2lyYU064ps2VOConxDPaE6ASB+UonqnPsc75Evl7kZm9Jz/EM0Nt2WiRN3IUz9hhX+donDHCKznhcqZ4xggbOeFmU9NmQ2x3ziWanZliW4beBTDGBJskQGONMV46R11jkBc5ek5jkCncdAqDTCimMcuEntWYZUKzNLOocwyjRMAwkmMYyTGM5BhGcgwjOYaZgKfaRYj9SI5hJuChdhFiPxOwql2E2M8EPNYuQuxncs49A/e1CxFveZlKS45BtuU81yxEvGUCCJe2X5VrETtsJwT/VqtC7GUjxzn3BPysWIvYYTdbu0VjjxleyQljz02lWsQOb1Jp59w9cFehFrHDoUcGP1AgWp29csLl7WvhWsQOBx+2OedWwPeCtYgdjj4Jdc79RMFoNU55TP0VTa+rEJUTxp9vBWoRO5z0godz7gGlB8U5+e0b59x39NS0KHNfjdL4U5BZckI4+iNTLWKH2S8VOufuULxThKVvfCreKcAiOYp3yrD4XWnFO/k560V2xTt5SbHKQNPrTJwtR09P85FkfU54eqp4JzHJFk8p3klP6pVtN2j8SUZSOWF6rXgnEcnXhIZ4Ry/GJyDXgt0bFO+cTRY5infSkG2pexh/bnN9/ghk3YfAOXeL4p3FlNgkQvHOQrLLUbyznCLbqyjeWUaxvW8U78yn9MZEindmUFSO4p15FN/SS/HO6dTab03xzglUkaN45zSq7VSoeCdO1W0kFe8cx8Ien4p3DlBdjuKdw1SXA4p3DmFCDije2YcZOQHFO1uYkqN45zWm5IDincAjGJQTGD3eeQCjchTvrJd1mpQDQ8c7j2FhtF05MGy8s1kMbVpO4BvjTK8fw4QIaEBOaPFR4p1Xa2zNy4Fh4p3bMM5uaEJO4JZ+453HML6+ohk5W+l1b+PPigO3Dc3IgS6n1yvgn/CD94am5MBm74Me4p07jogBcAWLSYb3fgL+os1fev4M3IRJzlGalAPgvf8A/Fm7jhk8s55x/jzWLds0KwfAe38FXNWuI8KK9SXs16lSXmhaDmw6yNJx+PD1BDw75/zSD/ofE5yeY9/bbu8AAAAASUVORK5CYII=","e":1},{"id":"image_6","w":10,"h":45,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAtCAYAAACXm/ozAAAACXBIWXMAAAABAAAAAQBPJcTWAAAAJHpUWHRDcmVhdG9yAAAImXNMyU9KVXBMK0ktUnBNS0tNLikGAEF6Bs5qehXFAAAAuElEQVQ4jbXTSQ6DMBBE0V8ESLj/YTMwVFZISauBjkS8sq2nqvbC2L5SWA3Q224rEOBmWxUoYKhAgMvevE0497bjXQoBhmzeDDZAX4EAXRxhCyqmbsE1VRUI0J0Om/VRRxCgPR2Wq2VbFQhQhqXq/ySeD/P/8f9ESSU4V6vLcKzARdJSgdO6OYJjBY5r7RF8fR624FfaFjTwjJcZfEjyERwlTRFFuGSVGbxnlRE+4yszOEt67aGf1hsW1TteOvp33gAAAABJRU5ErkJggg==","e":1},{"id":"image_7","w":28,"h":96,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAABgCAYAAAAO7RIuAAAACXBIWXMAAAABAAAAAQBPJcTWAAAAJHpUWHRDcmVhdG9yAAAImXNMyU9KVXBMK0ktUnBNS0tNLikGAEF6Bs5qehXFAAAB1klEQVRoge3ay27CMBBA0Tvm3f//19JAMiyqSCGExI+ZWSC8aintUez4Oq2Kqp4IHAk4quo+EgQ4q6pEggJcIkGAXcR6ptnnR1Wdv+YKAlw813MJTMA5EgTYq+ohEgQ4eazn2g902SpbV5Cst0rOlJmmL3eNzNKXC5qtZ8ldaJK+0tu+OX0139yUvhqwKX2101Odvpb1qEpfC1i1VVrjXJw+i9OgKH1Wx092+qzA7PW0PGCz0md9om+mz+ORcDV9HuBq+rweet+mz/MpezF9nqCwMLWuv0fwv1WeKuQNAjztzQgwTW+gCBDgGA2m8Y6NAgEO0eA+GkyqmiJBgF00+PlXKB8/paHb4gu6DN+/HC6M4Qtajz4SVBEJBe8Quy1CQRWRUPA2fhABKtBFgjcR0ShwYHJ1EeB1enXeYCci/fxFL/BlKj1BBX7nU+kJdiIyvPuiNXgXkcWp9AAH4Lr1JkvwZQt4gotbwAvsReQv982toJKxbpbgdW0LWIPdeKhGgG/T5QGupssDXE2XNbiZLkswK12WYFa6rMDsdFmARelqBYvT1QoWp6sFrEpXLVidrhqwKV01YFO6SsHmdJWAJukqAU3SlQuapWtzqOpPCDQBQ/4JchwPzdCtzr22jekAAAAASUVORK5CYII=","e":1},{"id":"image_8","w":47,"h":147,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC8AAACTCAYAAAAeL0CiAAAACXBIWXMAAAABAAAAAQBPJcTWAAAAJHpUWHRDcmVhdG9yAAAImXNMyU9KVXBMK0ktUnBNS0tNLikGAEF6Bs5qehXFAAADV0lEQVR4nO2c2U7jQBBFbzkkwP9/LJCt5mHGqOVpu+zurk3KeYAskBw5V7fKCQLM/I6kTAAuzPzmLdLC9O/7BzOTq0kDszwB+PQUaWEqLp+y5X9aXL8w8/K2sNREP7PkvyY/AfiwFmlhLSJvzHw2NWlgK9/v0fO/JRe+PqUjO0Wuzz2xCLs+7M10yPVhr3zI/B9pk3Drw9EqDLU+tIiEWR9a5MOsD60RCLE+9OTXfX3oeXL3+uw9cq7rw4iX3W19GJVZl/VhlLxL/ke2hfn6MLrqTNcHjScyWx805M3WB62X2GR90Myn+vqg+eDq9andDKrrg0WtXZj5pPHAVp2sUp9W8ir5tzyZODHzZeQDWp8JDa1Pj9O4Yfn3kJ8ADKlPrxPo84j1wfPsvzv/nvLd9en9vmPX+uAtD3SsDxHkgcb6jCLflP8o8kDD+hBJHjhYn9HkgQP5jyi/e32IKA/sXB+iygM78h9ZXqzPyPKAsD5Elwc21ocM8sDKhxdZ5CcA/03fLPJA5b3/TPLA4uhnkz+XRz+bPAD8Tt6XvDE0f2idUR4ATkBe+dRHfvr9khFmntLKA4mPPADKLJ/6yL/k3XjJe5FZPs5fZDeQVp6JKK38A8ib+TvwkjfnTkQM5JS/zReyyT+J6D5fySZ/La9kkn8Q0a28IZP89/KGLPJXInoub8wg/ySin9od0eUZwNfandHlf2pxmYksf1u2y5Ko8k8A1ZyXRJX/mveXLSLKb+a8JJr8g4iu8o/9JZL8Zi3WiCS/K+clUeSvRPQ4+ksR5FfHv4S3/OGcl3jL767FGp7y4viX8JLfNf4lvOQP12IND/munJdYyx8a/xKW8l21WMNSfkjOS6zkm8a/hIV88/iX0JYfnvMSbflhtVhDU757/EtoyQ8Z/xJa8sNrsYaGfPVNUQ1Gyz+0arHGSHnVWqwxUv7bIuclo+Sv5QddVoyQVxv/Er3y5jkv6ZVXHf8SPfJ37fEv0Sr/ROWjRWta5U3Gv0SLvNn4lzgqbzr+JY7Iu9ZijSPy5uNfYq+8y/iX2CPvNv4lJPlwOS+R5F3Hv8SWvPv4l1iTDzH+JdbkQ4x/iZp8mPEvsZQPNf4lSvnQtVijlA83/iVm+ZDjX2JC4PEvEuUf4bfwB/pMEzicksBWAAAAAElFTkSuQmCC","e":1},{"id":"image_9","w":66,"h":177,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAACxCAYAAABwUmtfAAAACXBIWXMAAAABAAAAAQBPJcTWAAAAJHpUWHRDcmVhdG9yAAAImXNMyU9KVXBMK0ktUnBNS0tNLikGAEF6Bs5qehXFAAAEXUlEQVR4nO2d2VLbQBAAezgCPOT/vzQF+No8GLsEyB5ptcfM7vZDKhWEUTXSTONSEgkh/GU9JxH5F/F5ZnmI/bwQwkvSM6lMrAiAPyGEp2RnUpktIgBeQwiS5Ewqs1WEAG8pTqQ2W0UAPLYwL1KIgPO8SPVaVUh58m+e50VKEQ/Aa8LXK0rqy/kphPCc+DWLkOO+fvE4L3KcsMuVmus75y7Bc17CrhI8973sJsFzi3AzL0pMdxcJXmrNmU/wkidnOsFLijCd4KUvV7MJXuO+NZngNU7I5Eqt9Z0xl+A1L1FTCV77XjWT4LVFmJkXtUWAkQS3IAIMJLgVEVA5wS2JeACq3SKWRAA810pwayKgUoJbFFFlpVoUARUS3KoIOK/Ux1JfzLIIKLhSrYsoNi+si4Bzgv/J/UU8iIACK9WLCMg8LzyJyJrgnkRAxgT3JgIyzQuPIrKsVI8iIEOCexUBiRPcswhIuFK9i0g2L7yLgEQJ3oIISLBSWxEBG+dFSyI2JXhLImBDgrcmAiLnRYsiolZqiyIgIsFbFQErE7xlEbBipbYuYvG8aF0ELEzwHkTAgpXaiwhQ5kVPIu4meE8i4Jzgs8929iYCbjzb2aMIAX5tkR5FwMzjjL2KgB9XRc8inqazomcRAlw3SM8iYIi4cr09ehcB8AhDBAwRV4aILx6uv3TOGJZThggghCBDxBdDxBdDBCAi9v7Wfi2GCDjBEAEQYIgAOMIQAUPElSECOIjImBHA4fKbnkUEhggA9pfbAvoVEYDd9A96FfHtaoA+RZz4cTVAnyI+fl4N0J+InYgc5z7Qk4iTiHze+mAvIgLwfu+AXkR8isjp3gE9iDiIyF47qHURJ+BjyYGti3ifW5VztCxip82FKa2KON5blXO0KCKwcC5MaVHEx5pb4kJrInYictAP+01LImZ/qlxKKyICK1blHK2IWLUq52hBxEFEom+JC95FLE5oDe8iZt9tisGziJvvNsXgVcTqhNbwKCIqoTU8iohKaA1vIqITWsOTiE0JreFFxOaE1vAiYnNCa3gQkSShNayLSJbQGtZFJEtoDcsikia0hlURyRNaw6KILAmtYVFEloTWsCYiW0JrWBKRNaE1rIjIntAaVkRkT2gNCyKKJLRGbRHFElqjtohiCa1RU0TRhNaoJeLuM481qCFCfeaxBjVEVElojdIi9rUSWqOkiBNgai5MKSmiakJrlBKhPgtdmxIiTCS0Rm4RVd5tiiG3CNNzYUpOEaYSWiOXCHMJrZFDhMmE1sghwmRCa6QWYTahNVKKMJ3QGilFuFmVc6QSYT6hNVKIcJHQGltFuEloja0iXM+FKVtEuEpojVgR7hJaI0aEy4TWiBHhMqE11opwm9Aaa0S4TmiNNSKaWZVzLBXhPqE1log4tpDQGpqIJlflHJqIpufClHsimkpojVsi9q0ltMaciIOINPGj9Rp+/gd/+x4lwPcrolsJcL4iAudgUv/1rkEH/AcTK1j5Ej3VcgAAAABJRU5ErkJggg==","e":1},{"id":"image_10","w":84,"h":182,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAAC2CAYAAABH56pIAAAACXBIWXMAAAABAAAAAQBPJcTWAAAAJHpUWHRDcmVhdG9yAAAImXNMyU9KVXBMK0ktUnBNS0tNLikGAEF6Bs5qehXFAAAEu0lEQVR4nO2d2XLbMAxFL+yky0P//0/bxI7FPmjcygllaAFFgLznKYsnw5yxERzFcSSl9At1eReRS+UzmHGqfQAA31JKHs5hgodvRAD8TClJ7YNY4EEoMJ7jW+1DWOBFKDA+9F9qH2IvnoQCwI/o89Tb4QXAj9qH2IM3oQBwTil9r32IrXgUCozz9Fz7EFvwKhQY52m4Vcqz0BMCzlPPQgHgJaUUaj/1LhQIlqYRDhoqTSMIBQKlaRShQJA0jSQUCJCmrg+XwX2aRhMKOE/TiEIBx6uUy0MtxOUqFVmoyzSNLBQY0/S19iGmRBcKAN89zVM3B9mBAPhZ+xB3WhAKACcvq1QrQgEnadqSUMDBVf7WhFafp60JBSqnaYtCgYpp2qpQoFKatiy0Spq2LBSokKatCwUOTtMehB66SvUgFDgwTXsRChyUpj0JBQ5I096EFp+nvQkFCqdpj0KBgmnaq1CgUJr2LLRImvYsFCiQpr0LBYzTlEKNVykKHTFLUwr9j0maUugju9OUQh/ZPU8p9CvnPX8bRaF5Nq9SFDrPpjSl0HlOAFavUhT6nNe1aUqhOqvmKYXqrFqlKHQZi9OUQpez6GU7KHQd6ipFoetQ5ymFrudpmlLoNmZXKQrdTnaeUuh2si/bQaH7+PKECQrdz8O9lEL38zq9l1KoDf+uSFGoDRRqjNx/BU2hdlCoMWeAQi05pZSEQm2hUGPOFGoMhdpyolBjKNQYCjWGQo2hUFsGCjWGQm25Uagtfl53swEGEaFQQ24AZ6glHwCFWpFEhEINud7foFAbKNSQq4gM93codB8JwMN/HqfQfTzcOwEK3cMgIu+fP0ih20gA/uQ+QaHbuHx+qN+h0PV8iMhl7pMUuo4BwNuzG1DoOt5EJD27AYUu5yIiN+1GFLqMW25FykGhOgnK3JxCoTpvcytSDgp9zuV+nXMpFDrPgE8XPpZAoXkSgD/aipSDQvPMpqUGhX7laVpqUOgjalpqUOgjalpqUOh/FqWlBoWOLE5LDQpdmZYaFLoyLTV6F3pdm5YaPQsdAJjMzSk9C92Ulhq9Cn23nJtTehS6Ky01ehNquiLl6E1okbk5pSehJmmp0YvQ7BO7StCD0NkndpWgB6GmaanRulDztNRoWWiRtNRoWWjxFSlHq0KLpaVGi0KLpqVGa0KLp6VGa0KrzM0pLQk9JC01WhF6WFpqtCD00LTUaEHooWmpEV3o4WmpEVlolbTUiCy0+oqUI6rQammpEVFo1bTUiCa0elpqRBPqcm5OiSTURVpqRBHqJi01Igh1lZYaEYS6XZFyeBd6FZGrfjM/eBbqMi01PAt1vyLl8Co01Nyc4lHozXNaangTGmpFyuFNaMi5OcWT0BBpqeFFaJi01PAgNPzcnOJBaNgVKUdtoeHSUqOm0JBpqVFTaPgVKUctoU3NzSk1hIZOS42jhTa1IuU4WmiTc3PKkUKbSEuNo4Q2k5YaRwhtfm5OOULo71ZXpBylhbp6dvERlBT61lqnL+GlwNdM6OxhPsVa6IBx1+xSJmAr9NLLavQMC6E3dPjDZ449Qj/QSf2sYa3QAaPIL/+LjYxoQm8YJd4wXnajRAUBgJSSPHyw8StCJfkLKNpn3YzkUXUAAAAASUVORK5CYII=","e":1},{"id":"image_11","w":103,"h":182,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGcAAAC2CAYAAADEI5NzAAAACXBIWXMAAAABAAAAAQBPJcTWAAAAJHpUWHRDcmVhdG9yAAAImXNMyU9KVXBMK0ktUnBNS0tNLikGAEF6Bs5qehXFAAAFU0lEQVR4nO3c224TSRSF4bXtcWKFCTBczvs/3UgwIVasgBXvueh44sTt3n2ow66q9UlIEEIo9CvdnQVYVPVv1OEI4B8ROeY+SCir3AcIaAXga+5DhFRTHADYquqn3IcIpbY4APBFVTe5DxFCjXEA4KuqFv9nK/4PcMUGwOfch1iq1jgAcKeq29yHWKLmOEB3eVvnPsRctcdZAfgr9yHmqj0OANyo6n3uQ8zRQhwAuFfV29yHmKqVOECBj9dFHXahNQqbd1qKAxQ277QWB+juP0XMOy3GWaGQ+4/7A0ayAeD+8brVOADwyfu803IcwPm803oc1/NO63EAx/MO43RczjuM88bd47Wrw2Tmbt5hnPdczTuMc8nNvMM4l9zMO9kP4JSLeYdxrss+7zDOsKzzDuMMyzrvMI4t27zDOONkmXcYZ7zkj9eMM17yeYdxpkk67zDOdMnmHcaZLtm8wzjzJJl3GGe+6PMO4ywT9fLGOMusAHyL+cFpmWjzDuOEEeXxmnHC+Rb6/sM44QSfdxgnrK2q3oX6YIwT3udQ9x/GCS/YS4sxThwbVf2y9IMwTjyL5x3GiWvRvMM4cS2adxgnvtnzDuOkMWveYZx0Js87jJPO5HmHcdKaNO8wTnqj5x3GSW/0vMM4eYyadxgnH3PeYZy8BucdxslrcN5hnPxurv3jeMbx4b7v/54yjg8rABdPb4zjx/bjf21kHF/e3XsYx5ft+b2Hcfz58/QdxvHn/9WAcfxZn1ZrxvHpBmAcr24BxvGKlzXH1gDjuKWqwjh+MY5njOMY4zjGOI4xjl/5X3Wc+okI4zh1AHhZ8+oFYByvfgGM49UzwDgevYgIL2tO7U/fYRx/GMep/emSBjCON7vzHzCOH+8+awDG8eII4PHjGxnHh52IHD++kXHyexaRp76fYJy8jgAerv0k4+T1b9/l7IRx8tmJyK+hd2CcPA4isrPeiXHSOwL4MeYdGSe9h49fbF7DOGntReR57DszTjoH9KwAQxgnnYehx+Y+jJPGTxE5TP1FjBPf1XnGwjhxDc4zFsaJa3CesTBOPOY8Y2GcOEbNMxbGCW/0PGNhnPBGzzMWxglr0jxjYZxwJs8zFsYJZ/I8Y2GcMGbNMxbGWW72PGNhnGUWzTMWxllm0TxjYZz5Fs8zFsaZJ8g8Y2Gc6YLNMxbGmS7YPGNhnGmCzjMWxhnvBYHnGQvjjPcj5mNzH8YZJ8o8Y2Ec2+9Y84yFcYYle2zuwzjDos4zFsa57in2PGNhnH4HEfmZ+xCMcynrfeYc41x6TDXPWBjnvb2I7O13S4Nx3iSfZyyM8yb5PGNhnE6WecbCOBnnGUvrcdw8NvdpPU7WecbScpzs84yl1Tgu5hlLi3Fc32fOtRjHzTxjaS2Oq3nG0lIcd/OMpaU47uYZSytxXM4zlhbiuJ1nLLXHKeaxuU/tcVzPM5aa47ifZyy1xilinrHUGKfo+8y5GuMUM89YaovzXNI8Y6kpzgsiviZADjXFKW6esdQSZ1fiPGOpIc7vFK8JkEPpcap5bO5Tepzgr3HmSclxnlK+JkAOpcapYp6xlBgn6muceVJinMcaH5v7lBanqH89s1RJcQ4i0sTl7KSUOAcA33MfIrUS4hwAfK/565lr/sh9AMMe3QNAc2GALs4RPj+DdrVuZmMJAKjqLYDt67d11hN1l7GHVh6Xh8jHN6jqBsAd0oc6optkmv5sOXcR51yiUEcAT+jCNHlvuWYwzrnXUKdL3ybA7/2Myv7OP7TRcc6p6hrALYAbdA8VN8YveXn99gvdF5NVr8mhzIpzjarK+cfkZWqZ/wCrmnhi5H3u1gAAAABJRU5ErkJggg==","e":1},{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":0,"nm":"预合成 2","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[214,117.5,0],"ix":2},"a":{"a":0,"k":[214,117.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":428,"h":235,"ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"预合成 1","refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[214,117.5,0],"ix":2},"a":{"a":0,"k":[214,117.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":428,"h":235,"ip":0,"op":150,"st":0,"bm":0}]},{"id":"comp_1","layers":[{"ddd":0,"ind":1,"ty":2,"nm":"图层 22","refId":"image_0","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":75,"s":[100]},{"t":149,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[423.326,158.963,0],"ix":2},"a":{"a":0,"k":[4.674,22.094,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":2,"nm":"图层 21","refId":"image_1","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":10,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":75,"s":[100]},{"t":140,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[414.046,158.963,0],"ix":2},"a":{"a":0,"k":[13.954,47.641,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":2,"nm":"图层 20","refId":"image_2","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":20,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":75,"s":[100]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[404.766,156.317,0],"ix":2},"a":{"a":0,"k":[23.234,70.541,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":2,"nm":"图层 19","refId":"image_3","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":75,"s":[100]},{"t":120,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[395.485,148.952,0],"ix":2},"a":{"a":0,"k":[32.515,85.765,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":2,"nm":"图层 18","refId":"image_4","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":40,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":75,"s":[100]},{"t":110,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[386.205,146.687,0],"ix":2},"a":{"a":0,"k":[41.795,88.313,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":2,"nm":"图层 17","refId":"image_5","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":50,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":75,"s":[100]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[376.925,146.686,0],"ix":2},"a":{"a":0,"k":[51.075,88.314,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":150,"st":0,"bm":0}]},{"id":"comp_2","layers":[{"ddd":0,"ind":1,"ty":2,"nm":"图层 13","refId":"image_6","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":75,"s":[100]},{"t":149,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[4.828,80.467,0],"ix":2},"a":{"a":0,"k":[4.674,22.095,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":2,"nm":"图层 12","refId":"image_7","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":10,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":75,"s":[100]},{"t":140,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[14.108,80.467,0],"ix":2},"a":{"a":0,"k":[13.954,47.64,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":2,"nm":"图层 11","refId":"image_8","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":20,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":75,"s":[100]},{"t":130,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[23.388,80.467,0],"ix":2},"a":{"a":0,"k":[23.234,73.187,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":2,"nm":"图层 14","refId":"image_9","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":75,"s":[100]},{"t":120,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[32.668,88.121,0],"ix":2},"a":{"a":0,"k":[32.515,88.121,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":2,"nm":"图层 15","refId":"image_10","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":40,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":75,"s":[100]},{"t":110,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[41.948,90.528,0],"ix":2},"a":{"a":0,"k":[41.795,90.528,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":2,"nm":"图层 16","refId":"image_11","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":49,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":75,"s":[100]},{"t":100,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[51.229,90.529,0],"ix":2},"a":{"a":0,"k":[51.075,90.529,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":150,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"首页背景","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[214,117.5,0],"ix":2},"a":{"a":0,"k":[214,117.5,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":428,"h":235,"ip":0,"op":150,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/static/css/base.css b/static/css/base.css new file mode 100644 index 0000000..35b660c --- /dev/null +++ b/static/css/base.css @@ -0,0 +1,427 @@ +@charset "UTF-8"; + +* { + scrollbar-color: #e5e5e5 #f7f7f9; + scrollbar-width: thin; +} + +html { + margin: 0 auto; + +} + +body { + overflow-x: hidden; + +} + +.font-color, +.font-color-red { + color: #fc4141 !important +} + +.bg-color { + background-color: #e93323 +} + +.icon-color { + color: #ff3c2b +} + +.cart-color { + color: #ff3700 !important; + border: 1px solid #ff3700 !important +} + +.padding20 { + padding: 20rpx +} + +.pad20 { + padding: 0 20rpx +} + +.padding30 { + padding: 30rpx +} + +.pad30 { + padding: 0 30rpx +} + +.pull-left { + float: left; +} + +.pull-right { + float: right; +} + +.clearfix:after { + content: ''; + display: block; + height: 0; + clear: both +} + +.clearfix { + zoom: 1 +} + +.acea-row { + display: -webkit-box; + display: -moz-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-box-lines: multiple; + -moz-box-lines: multiple; + -o-box-lines: multiple; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap +} + +.acea-row.row-middle { + -webkit-box-align: center; + -moz-box-align: center; + -o-box-align: center; + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center +} + +.acea-row.row-top { + -webkit-box-align: start; + -moz-box-align: start; + -o-box-align: start; + -ms-flex-align: start; + -webkit-align-items: flex-start; + align-items: flex-start +} + +.acea-row.row-bottom { + -webkit-box-align: end; + -moz-box-align: end; + -o-box-align: end; + -ms-flex-align: end; + -webkit-align-items: flex-end; + align-items: flex-end +} + +.acea-row.row-center { + -webkit-box-pack: center; + -moz-box-pack: center; + -o-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center +} + +.acea-row.row-right { + -webkit-box-pack: end; + -moz-box-pack: end; + -o-box-pack: end; + -ms-flex-pack: end; + -webkit-justify-content: flex-end; + justify-content: flex-end +} + +.acea-row.row-left { + -webkit-box-pack: start; + -moz-box-pack: start; + -o-box-pack: start; + -ms-flex-pack: start; + -webkit-justify-content: flex-start; + justify-content: flex-start +} + +.acea-row.row-between { + -webkit-box-pack: justify; + -moz-box-pack: justify; + -o-box-pack: justify; + -ms-flex-pack: justify; + -webkit-justify-content: space-between; + justify-content: space-between +} + +.acea-row.row-around { + justify-content: space-around; + -webkit-justify-content: space-around +} + +.acea-row.row-column-around { + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + justify-content: space-around; + -webkit-justify-content: space-around +} + +.acea-row.row-column { + -webkit-box-orient: vertical; + -moz-box-orient: vertical; + -o-box-orient: vertical; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column +} + +.acea-row.row-column-between { + -webkit-box-orient: vertical; + -moz-box-orient: vertical; + -o-box-orient: vertical; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + -webkit-box-pack: justify; + -moz-box-pack: justify; + -o-box-pack: justify; + -ms-flex-pack: justify; + -webkit-justify-content: space-between; + justify-content: space-between +} + +.acea-row.row-center-wrapper { + -webkit-box-align: center; + -moz-box-align: center; + -o-box-align: center; + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center; + -webkit-box-pack: center; + -moz-box-pack: center; + -o-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center +} + +.acea-row.row-between-wrapper { + -webkit-box-align: center; + -moz-box-align: center; + -o-box-align: center; + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center; + -webkit-box-pack: justify; + -moz-box-pack: justify; + -o-box-pack: justify; + -ms-flex-pack: justify; + -webkit-justify-content: space-between; + justify-content: space-between +} + +.start { + width: 122rpx; + height: 30rpx; + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHoAAADMCAYAAAC8yreMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA4BpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTQ1IDc5LjE2MzQ5OSwgMjAxOC8wOC8xMy0xNjo0MDoyMiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpDMDg0NEE2QTVFNUQxMUU4QUI3RkNGOTgwNDYyRUZDOCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDozODU5QzVENDMwRjcxMUU5OTQ0QzlEOTQ5RkE1MTlBRiIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDozODU5QzVEMzMwRjcxMUU5OTQ0QzlEOTQ5RkE1MTlBRiIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOCAoV2luZG93cykiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpkN2ZhZTM5NC0wNmE4LTkzNGYtODA0OS0zNjBjNTcxOTU2YjAiIHN0UmVmOmRvY3VtZW50SUQ9ImFkb2JlOmRvY2lkOnBob3Rvc2hvcDpmYWI1M2NhMC04MWE1LTE5NGItYmJlYi1jMzI2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'); + background-repeat: no-repeat; + background-size: 122rpx auto; +} + +.start.star5 { + background-position: 0 3rpx; +} + +.start.star4 { + background-position: 0 -30rpx; +} + +.start.star3 { + background-position: 0 -70rpx; +} + +.start.star2 { + background-position: 0 -105rpx; +} + +.start.star1 { + background-position: 0 -140rpx; +} + +.start.star0 { + background-position: 0 -175rpx; +} + +* { + box-sizing: border-box +} + +page { + font-size: 28rpx; + background-color: #f5f5f5; + color: #333 +} + +body, +html { + height: unset +} + +button { + padding: 0; + margin: 0; + line-height: normal; + background-color: #fff +} + +button::after { + border: 0 +} + +radio .wx-radio-input { + border-radius: 50%; + width: 38rpx; + height: 38rpx +} + +radio .wx-radio-input.wx-radio-input-checked { + border: 1px solid #e93323; + background-color: #e93323; +} + +radio .uni-radio-input { + border-radius: 50%; + width: 38rpx; + height: 38rpx +} + +radio .uni-radio-input.uni-radio-input-checked { + border: 1px solid #e93323; + background-color: #e93323; +} + +.store-list uni-radio .uni-radio-input.uni-radio-input-checked, +.store-list uni-radio .uni-radio-input { + /* border-color: transparent; + background-color: transparent; */ +} + +.store-list uni-radio .uni-radio-input.uni-radio-input-checked:before { + /* color: #e93323!important; */ +} + +checkbox .wx-checkbox-input { + width: 38rpx; + height: 38rpx +} + +checkbox .wx-checkbox-input.wx-checkbox-input-checked::before { + color: #fff !important; +} + +checkbox .uni-checkbox-input { + /* border-radius: 50%; */ + width: 38rpx; + height: 38rpx +} + +checkbox .uni-checkbox-input.uni-checkbox-input-checked, +checkbox .wx-checkbox-input.wx-checkbox-input-checked { + border: 1px solid #20A162; + background-color: #20A162; + color: #fff !important; +} + +checkbox .uni-checkbox-input.uni-checkbox-input-checked::before { + font-size: 35rpx +} + +.line1 { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap +} + +.line2 { + word-break: break-all; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; + white-space: pre-wrap; +} + +.mask { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: #000; + opacity: .5; + z-index: 30 +} + +@keyframes load { + from { + transform: rotate(0) + } + + to { + transform: rotate(360deg) + } +} + +@-webkit-keyframes load { + from { + transform: rotate(0) + } + + to { + transform: rotate(360deg) + } +} + +.loadingpic { + animation: load 3s linear 1s infinite; + --webkit-animation: load 3s linear 1s infinite +} + +.loading-list { + animation: load linear 1s infinite; + -webkit-animation: load linear 1s infinite; + font-size: 40rpx; + margin-right: 22rpx +} + +.loading { + width: 100%; + height: 100rpx; + line-height: 100rpx; + align-items: center; + justify-content: center; + position: relative; + text-align: center +} + +.loading .line { + position: absolute; + width: 450rpx; + left: 150rpx; + top: 50rpx; + height: 1px; + border-top: 1px solid #eee +} + +.loading .text { + position: relative; + display: inline-block; + padding: 0 20rpx; + background: #fff; + z-index: 2; + color: #777 +} + +.loadingicon .loading { + animation: load linear 1s infinite; + font-size: 45rpx; + color: #000 +} + +.loadingicon { + width: 100%; + height: 80rpx; + overflow: hidden +} diff --git a/static/css/global.scss b/static/css/global.scss new file mode 100644 index 0000000..3d84be3 --- /dev/null +++ b/static/css/global.scss @@ -0,0 +1 @@ +$base-color: #0122c7; diff --git a/static/empty/data.png b/static/empty/data.png new file mode 100644 index 0000000..8b28751 Binary files /dev/null and b/static/empty/data.png differ diff --git a/static/empty/list.png b/static/empty/list.png new file mode 100644 index 0000000..77bbb95 Binary files /dev/null and b/static/empty/list.png differ diff --git a/static/iconfont/iconfont.css b/static/iconfont/iconfont.css new file mode 100644 index 0000000..438685f --- /dev/null +++ b/static/iconfont/iconfont.css @@ -0,0 +1,2530 @@ +@font-face { + font-family: "iconfont"; /* Project id 993865 */ + src: url('https://at.alicdn.com/t/c/font_993865_st57f1kxbxn.woff2?t=1676510581100') format('woff2'), + url('https://at.alicdn.com/t/c/font_993865_st57f1kxbxn.woff?t=1676510581100') format('woff'), + url('https://at.alicdn.com/t/c/font_993865_st57f1kxbxn.ttf?t=1676510581100') format('truetype'); +} + +.iconfont { + font-family: "iconfont" !important; + font-size: 16px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.icon-daifukuan1:before { + content: "\e836"; +} + +.icon-daifahuo1:before { + content: "\e837"; +} + +.icon-daipingjia1:before { + content: "\e839"; +} + +.icon-daishouhuo1:before { + content: "\e83a"; +} + +.icon-a-shouhoutuikuan1:before { + content: "\e83b"; +} + +.icon-baozhengjin:before { + content: "\e834"; +} + +.icon-tonglianzhifu1:before { + content: "\e835"; +} + +.icon-dianpu1:before { + content: "\e833"; +} + +.icon-paizhao:before { + content: "\e832"; +} + +.icon-24gf-play:before { + content: "\ea82"; +} + +.icon-yiquxiao:before { + content: "\e831"; +} + +.icon-wutouxiang:before { + content: "\e830"; +} + +.icon-fenxiang3:before { + content: "\e82d"; +} + +.icon-pinglun2:before { + content: "\e82e"; +} + +.icon-shipin1:before { + content: "\e827"; +} + +.icon-tuwen1:before { + content: "\e828"; +} + +.icon-shangpinye_fenxiang:before { + content: "\e8e4"; +} + +.icon-gou2:before { + content: "\e826"; +} + +.icon-daihexiao:before { + content: "\e825"; +} + +.icon-pengyouquan1:before { + content: "\e824"; +} + +.icon-shangpin1:before { + content: "\e823"; +} + +.icon-tishi2:before { + content: "\e821"; +} + +.icon-baoguo:before { + content: "\e822"; +} + +.icon-shipin:before { + content: "\e820"; +} + +.icon-fengmian:before { + content: "\e81f"; +} + +.icon-hexiaoma:before { + content: "\e81c"; +} + +.icon-tuwen:before { + content: "\e81d"; +} + +.icon-tianjiashipin:before { + content: "\e81e"; +} + +.icon-chehui:before { + content: "\e81a"; +} + +.icon-fuzhi:before { + content: "\e81b"; +} + +.icon-yue2:before { + content: "\e8b0"; +} + +.icon-gouwu_o:before { + content: "\eb60"; +} + +.icon-chengchangzhi:before { + content: "\e815"; +} + +.icon-fabu1:before { + content: "\e814"; +} + +.icon-qiandao:before { + content: "\e816"; +} + +.icon-pingjia3:before { + content: "\e817"; +} + +.icon-yaoqing1:before { + content: "\e819"; +} + +.icon-liebiao1:before { + content: "\e7f9"; +} + +.icon-liebiao2:before { + content: "\e7fa"; +} + +.icon-xiaofeijilu-rongcuo:before { + content: "\e853"; +} + +.icon-goumaishangpin:before { + content: "\e84e"; +} + +.icon-meiriqiandao:before { + content: "\e84f"; +} + +.icon-yaoqinghaoyou2:before { + content: "\e850"; +} + +.icon-xiaofeijilu1:before { + content: "\e851"; +} + +.icon-fufeihuiyuan1:before { + content: "\e852"; +} + +.icon-goumai:before { + content: "\e7f8"; +} + +.icon-dengdaizhifu:before { + content: "\e840"; +} + +.icon-xinghao:before { + content: "\e838"; +} + +.icon-shouji2:before { + content: "\e829"; +} + +.icon-dingwei4:before { + content: "\e82a"; +} + +.icon-sousuo8:before { + content: "\e82b"; +} + +.icon-erweima3:before { + content: "\e82c"; +} + +.icon-shoudanyouhui:before { + content: "\e818"; +} + +.icon-gouwuche-mendian:before { + content: "\e812"; +} + +.icon-kefu-mendian:before { + content: "\e813"; +} + +.icon-zhongwen:before { + content: "\e810"; +} + +.icon-yingwen:before { + content: "\e811"; +} + +.icon-shipindianzan-weidian1:before { + content: "\e80e"; +} + +.icon-shipindianzan-yidian:before { + content: "\e80f"; +} + +.icon-mendian1:before { + content: "\e807"; +} + +.icon-gouwuche8:before { + content: "\e808"; +} + +.icon-tianjiagouwuche:before { + content: "\e809"; +} + +.icon-shipindianzan-weidian:before { + content: "\e80a"; +} + +.icon-pingjia2:before { + content: "\e80b"; +} + +.icon-liwu:before { + content: "\e80c"; +} + +.icon-shipindianzan:before { + content: "\e80d"; +} + +.icon-dingwei2:before { + content: "\e7fb"; +} + +.icon-dianhua:before { + content: "\e7fc"; +} + +.icon-yingyeshijian1:before { + content: "\e7fd"; +} + +.icon-bianji4:before { + content: "\e7fe"; +} + +.icon-xuanzhong6:before { + content: "\e7ff"; +} + +.icon-shaixuan1:before { + content: "\e800"; +} + +.icon-yingyeshijian2:before { + content: "\e801"; +} + +.icon-dingwei3:before { + content: "\e802"; +} + +.icon-mendian:before { + content: "\e806"; +} + +.icon-fangda1:before { + content: "\e7f7"; +} + +.icon-meiyuan:before { + content: "\e7f5"; +} + +.icon-yilingqu2:before { + content: "\e7f6"; +} + +.icon-jifen:before { + content: "\e7f3"; +} + +.icon-youhuiquan2:before { + content: "\e7f4"; +} + +.icon-zuji-xuanzhong:before { + content: "\e7f2"; +} + +.icon-zuji:before { + content: "\e7f1"; +} + +.icon-fanhui3:before { + content: "\e7f0"; +} + +.icon-fenxiaodingdan:before { + content: "\e7e9"; +} + +.icon-tuiguangrenpaihang1:before { + content: "\e7ea"; +} + +.icon-huodongguize:before { + content: "\e7eb"; +} + +.icon-xingzhuangjiehe:before { + content: "\e7ec"; +} + +.icon-wodetuandui:before { + content: "\e7ed"; +} + +.icon-yaoqinghaoyou1:before { + content: "\e7ee"; +} + +.icon-yongjinpaihang1:before { + content: "\e7ef"; +} + +.icon-daohangdaodian:before { + content: "\e7e5"; +} + +.icon-yingyeshijian:before { + content: "\e7e6"; +} + +.icon-dingwei1:before { + content: "\e7e7"; +} + +.icon-zhidianzixun:before { + content: "\e7e8"; +} + +.icon-pc-jifen:before { + content: "\e7e3"; +} + +.icon-pc-youhuiquan:before { + content: "\e7e4"; +} + +.icon-qunliao:before { + content: "\e7e2"; +} + +.icon-dingdan-xuanzhong:before { + content: "\e7db"; +} + +.icon-jilu-xuanzhong:before { + content: "\e7dc"; +} + +.icon-kehu-xuanzhong:before { + content: "\e7dd"; +} + +.icon-jilu:before { + content: "\e7de"; +} + +.icon-dingdan1:before { + content: "\e7df"; +} + +.icon-kehu:before { + content: "\e7e1"; +} + +.icon-xingbie-nan:before { + content: "\e7d9"; +} + +.icon-xingbie-nv:before { + content: "\e7da"; +} + +.icon-v:before { + content: "\e7d7"; +} + +.icon-huangguan4:before { + content: "\e7d8"; +} + +.icon-yilingqu:before { + content: "\e7d6"; +} + +.icon-jinru3:before { + content: "\e7d5"; +} + +.icon-dingdanguanli:before { + content: "\e7d1"; +} + +.icon-kefujilu:before { + content: "\e7d2"; +} + +.icon-dingdanhexiao:before { + content: "\e7d3"; +} + +.icon-shangjiaguanli:before { + content: "\e7d4"; +} + +.icon-yaoqinghaoyou:before { + content: "\e7d0"; +} + +.icon-yongjinpaihang:before { + content: "\e7cb"; +} + +.icon-tuiguangrenpaihang:before { + content: "\e7cf"; +} + +.icon-mimatubiao:before { + content: "\e7ca"; +} + +.icon-xianshi:before { + content: "\e7cc"; +} + +.icon-zhekoujia:before { + content: "\e7cd"; +} + +.icon-zhu:before { + content: "\e7ce"; +} + +.icon-weizan:before { + content: "\e7c7"; +} + +.icon-zan:before { + content: "\e7c8"; +} + +.icon-pinglun1:before { + content: "\e7c9"; +} + +.icon-gou1:before { + content: "\e7c6"; +} + +.icon-banquan:before { + content: "\e7c2"; +} + +.icon-gengxinshijian:before { + content: "\e7c3"; +} + +.icon-xiazailiang:before { + content: "\e7c4"; +} + +.icon-wenjiandaxiao:before { + content: "\e7c5"; +} + +.icon-dizhi1:before { + content: "\e7bd"; +} + +.icon-guojiagaoxinqiye:before { + content: "\e7be"; +} + +.icon-yishoucang1:before { + content: "\e7bf"; +} + +.icon-wendang:before { + content: "\e7c0"; +} + +.icon-shoucangbenzhan1:before { + content: "\e7c1"; +} + +.icon-fenlei3:before { + content: "\e7bc"; +} + +.icon-shenheweitongguo:before { + content: "\e7b9"; +} + +.icon-shenhetongguo:before { + content: "\e7ba"; +} + +.icon-daishenhe:before { + content: "\e7bb"; +} + +.icon-shoufaxinpin:before { + content: "\e7b8"; +} + +.icon-cuxiaodanpin:before { + content: "\e7b7"; +} + +.icon-jingpintuijian1:before { + content: "\e7b5"; +} + +.icon-paihangbang:before { + content: "\e7b6"; +} + +.icon-yidianzan:before { + content: "\e7b4"; +} + +.icon-dianzan1:before { + content: "\e7b3"; +} + +.icon-haoyoudaizhifu:before { + content: "\e7b2"; +} + +.icon-baobeilianjie:before { + content: "\e7b0"; +} + +.icon-canyuhuati:before { + content: "\e7b1"; +} + +.icon-dianzan:before { + content: "\e7ac"; +} + +.icon-pinglun:before { + content: "\e7ad"; +} + +.icon-fenxiang2:before { + content: "\e7ae"; +} + +.icon-fabu:before { + content: "\e7af"; +} + +.icon-gengduo5:before { + content: "\e7ab"; +} + +.icon-fanhui2:before { + content: "\e7a9"; +} + +.icon-kanjialiebiao:before { + content: "\e7aa"; +} + +.icon-xunishangpin:before { + content: "\e7a8"; +} + +.icon-dingdanliebiao:before { + content: "\e7a6"; +} + +.icon-shujutongji1:before { + content: "\e7a7"; +} + +.icon-sousuo7:before { + content: "\e7a5"; +} + +.icon-zhibozhong1:before { + content: "\e7a4"; +} + +.icon-youhuiquanshisebeijing:before { + content: "\e7a2"; +} + +.icon-youhuiquantoumingbeijing:before { + content: "\e7a3"; +} + +.icon-yushouanniu:before { + content: "\e7a1"; +} + +.icon-gengduo4:before { + content: "\e7a0"; +} + +.icon-sousuo6:before { + content: "\e79b"; +} + +.icon-gerenzhongxin1:before { + content: "\e79c"; +} + +.icon-shoucang3:before { + content: "\e79d"; +} + +.icon-shouye8:before { + content: "\e79e"; +} + +.icon-gouwuche7:before { + content: "\e79f"; +} + +.icon-fuzhikouling1:before { + content: "\e79a"; +} + +.icon-zhuanti:before { + content: "\e799"; +} + +.icon-daifukuan-3:before { + content: "\e794"; +} + +.icon-shouhou-tuikuan-3:before { + content: "\e795"; +} + +.icon-daipingjia-3:before { + content: "\e796"; +} + +.icon-daifahuo-3:before { + content: "\e797"; +} + +.icon-quanbudingdan-3:before { + content: "\e798"; +} + +.icon-daifahuo-2:before { + content: "\e78e"; +} + +.icon-daishouhuo-2:before { + content: "\e78f"; +} + +.icon-daipingjia-2:before { + content: "\e791"; +} + +.icon-shouhou-tuikuan-2:before { + content: "\e792"; +} + +.icon-daifukuan-2:before { + content: "\e793"; +} + +.icon-duoshanghupc-shuomingdanchuang:before { + content: "\e78b"; +} + +.icon-duoshanghupc-daohuotongzhi:before { + content: "\e78c"; +} + +.icon-duoshanghupc-baozhang:before { + content: "\e78d"; +} + +.icon-dianpu:before { + content: "\e78a"; +} + +.icon-dengjitubiao:before { + content: "\e789"; +} + +.icon-daifahuo-xingerenzhongxin:before { + content: "\e782"; +} + +.icon-erweima-xingerenzhongxin:before { + content: "\e783"; +} + +.icon-quanbudingdan-xingerenzhongxin:before { + content: "\e784"; +} + +.icon-xiaoxi-xingerenzhongxin:before { + content: "\e785"; +} + +.icon-daipingjia-xingerenzhongxin:before { + content: "\e786"; +} + +.icon-a-shouhoutuikuan-xingerenzhongxin:before { + content: "\e787"; +} + +.icon-daifukuan-xingerenzhongxin:before { + content: "\e788"; +} + +.icon-fapiao2:before { + content: "\e781"; +} + +.icon-shouhou-tuikuan-lan:before { + content: "\e77c"; +} + +.icon-daipingjia-lan:before { + content: "\e780"; +} + +.icon-daishouhuo-lan:before { + content: "\e77d"; +} + +.icon-daifukuan-lan:before { + content: "\e77e"; +} + +.icon-daifahuo-lan:before { + content: "\e77f"; +} + +.icon-daifahuo-ju:before { + content: "\e777"; +} + +.icon-daifukuan-ju:before { + content: "\e778"; +} + +.icon-daishouhuo-ju:before { + content: "\e779"; +} + +.icon-shouhou-tuikuan-ju:before { + content: "\e77a"; +} + +.icon-daipingjia-ju:before { + content: "\e77b"; +} + +.icon-daishouhuo-fen:before { + content: "\e772"; +} + +.icon-daipingjia-fen:before { + content: "\e773"; +} + +.icon-daifukuan-fen:before { + content: "\e774"; +} + +.icon-a-shouhoutuikuan-fen:before { + content: "\e775"; +} + +.icon-daifahuo-fen:before { + content: "\e776"; +} + +.icon-daifahuo-lv:before { + content: "\e768"; +} + +.icon-shouhou-tuikuan-lv:before { + content: "\e76a"; +} + +.icon-daifukuan-lv:before { + content: "\e76d"; +} + +.icon-daishouhuo-lv:before { + content: "\e770"; +} + +.icon-daipingjia-lv:before { + content: "\e771"; +} + +.icon-daishouhuo:before { + content: "\e75d"; +} + +.icon-daipingjia:before { + content: "\e75e"; +} + +.icon-daifahuo:before { + content: "\e760"; +} + +.icon-daifukuan:before { + content: "\e766"; +} + +.icon-a-shouhoutuikuan:before { + content: "\e767"; +} + +.icon-gouwuche-yangshi1:before { + content: "\e75b"; +} + +.icon-gouwuche-yangshi2:before { + content: "\e75c"; +} + +.icon-rilitubiao:before { + content: "\e75a"; +} + +.icon-tishi1:before { + content: "\e759"; +} + +.icon-daituihuo1:before { + content: "\e752"; +} + +.icon-shenqingzhong:before { + content: "\e756"; +} + +.icon-fanyong:before { + content: "\e74d"; +} + +.icon-zizhizhengjian:before { + content: "\e743"; +} + +.icon-fenxiaodengji:before { + content: "\e742"; +} + +.icon-yijujue:before { + content: "\e741"; +} + +.icon-tuikuanzhong1:before { + content: "\e803"; +} + +.icon-tuikuanshibai:before { + content: "\e804"; +} + +.icon-tuikuanchenggong:before { + content: "\e805"; +} + +.icon-tuikuanzhong11:before { + content: "\e744"; +} + +.icon-yiwancheng:before { + content: "\e745"; +} + +.icon-yituikuan1:before { + content: "\e747"; +} + +.icon-tuikuan1:before { + content: "\e73a"; +} + +.icon-tuihuo:before { + content: "\e73c"; +} + +.icon-shenhe:before { + content: "\e73d"; +} + +.icon-shangchuantupian1:before { + content: "\e755"; +} + +.icon-shouye7:before { + content: "\e863"; +} + +.icon-shengqian:before { + content: "\e738"; +} + +.icon-xiaolian1:before { + content: "\e737"; +} + +.icon-fangda:before { + content: "\e736"; +} + +.icon-dianjichoujiang:before { + content: "\e730"; +} + +.icon-7jinianban:before { + content: "\e76f"; +} + +.icon-lingquyouhuiquananniu:before { + content: "\e72e"; +} + +.icon-qiandaochenggonganniu:before { + content: "\e72f"; +} + +.icon-s-xianshimiaosha:before { + content: "\e727"; +} + +.icon-s-pintuan1:before { + content: "\e726"; +} + +.icon-s-kanjia1:before { + content: "\e72d"; +} + +.icon-s-pingguo:before { + content: "\e722"; +} + +.icon-s-weixindenglu1:before { + content: "\e729"; +} + +.icon-s-yanzhengmadenglu1:before { + content: "\e72a"; +} + +.icon-s-mimadenglu1:before { + content: "\e72b"; +} + +.icon-s-yanzhengma:before { + content: "\e728"; +} + +.icon-pengyouquan:before { + content: "\e76e"; +} + +.icon-jifenzhongxin:before { + content: "\e71f"; +} + +.icon-s-chongzhijilu:before { + content: "\e71c"; +} + +.icon-s-xiaofeijilu:before { + content: "\e71e"; +} + +.icon-s-zhangdanjilu:before { + content: "\e720"; +} + +.icon-s-kefu:before { + content: "\e721"; +} + +.icon-s-bianji:before { + content: "\e71d"; +} + +.icon-s-pintuan:before { + content: "\e719"; +} + +.icon-s-kanjia:before { + content: "\e71a"; +} + +.icon-s-miaosha:before { + content: "\e71b"; +} + +.icon-fanhui1:before { + content: "\e718"; +} + +.icon-kefu3:before { + content: "\e716"; +} + +.icon-shouye6:before { + content: "\e717"; +} + +.icon-chakanditu:before { + content: "\e715"; +} + +.icon-haowuquan1:before { + content: "\e713"; +} + +.icon-haowuquan:before { + content: "\e712"; +} + +.icon-gengduozhankai1:before { + content: "\e70e"; +} + +.icon-biaoqing2:before { + content: "\e70f"; +} + +.icon-huashu1:before { + content: "\e710"; +} + +.icon-tupian2:before { + content: "\e711"; +} + +.icon-huifang:before { + content: "\e76c"; +} + +.icon-zhibozhong:before { + content: "\e76b"; +} + +.icon-huangguan3:before { + content: "\e769"; +} + +.icon-huiyuan2:before { + content: "\e70c"; +} + +.icon-fapiao1:before { + content: "\e70b"; +} + +.icon-cha3:before { + content: "\e709"; +} + +.icon-shezhi1:before { + content: "\e70a"; +} + +.icon-tianjia1:before { + content: "\e705"; +} + +.icon-bianji3:before { + content: "\e706"; +} + +.icon-jiahao2:before { + content: "\e707"; +} + +.icon-shanchu3:before { + content: "\e708"; +} + +.icon-fuzhikouling:before { + content: "\e704"; +} + +.icon-kefujiedai:before { + content: "\e703"; +} + +.icon-miaosha1:before { + content: "\e702"; +} + +.icon-bianji2:before { + content: "\e700"; +} + +.icon-qingkonghuancun:before { + content: "\e701"; +} + +.icon-shijian1:before { + content: "\e66b"; +} + +.icon-wenhao1:before { + content: "\e6ee"; +} + +.icon-zhanghaomima:before { + content: "\e763"; +} + +.icon-erweima2:before { + content: "\e765"; +} + +.icon-guanji:before { + content: "\e6ed"; +} + +.icon-tupian1:before { + content: "\e762"; +} + +.icon-biaoqing1:before { + content: "\e764"; +} + +.icon-guanbi5:before { + content: "\e761"; +} + +.icon-shengyinjingyinxianxing:before { + content: "\e94f"; +} + +.icon-shengyinyinliang:before { + content: "\e66a"; +} + +.icon-pingjia1:before { + content: "\e6ec"; +} + +.icon-xialazhankai:before { + content: "\e6dd"; +} + +.icon-cha2:before { + content: "\e6e6"; +} + +.icon-fanhuishouye:before { + content: "\e6df"; +} + +.icon-gengduo3:before { + content: "\e6e0"; +} + +.icon-fenxiang1:before { + content: "\e6e2"; +} + +.icon-sousuo5:before { + content: "\e6e3"; +} + +.icon-huiyuan1:before { + content: "\e6e5"; +} + +.icon-gou:before { + content: "\e6e7"; +} + +.icon-gouwuche6:before { + content: "\e6e8"; +} + +.icon-you1:before { + content: "\e6e9"; +} + +.icon-zuo1:before { + content: "\e6ea"; +} + +.icon-vip12:before { + content: "\e6eb"; +} + +.icon-youhuiquan1:before { + content: "\e6db"; +} + +.icon-kefu21:before { + content: "\e6da"; +} + +.icon-yue1:before { + content: "\e6dc"; +} + +.icon-huiyuanzhongxin:before { + content: "\e6d5"; +} + +.icon-kanjiajilu:before { + content: "\e6d6"; +} + +.icon-dizhixinxi:before { + content: "\e6d7"; +} + +.icon-wodetuiguang:before { + content: "\e6d8"; +} + +.icon-wodeshoucang:before { + content: "\e6d9"; +} + +.icon-huidaodingbu1:before { + content: "\e6d4"; +} + +.icon-saoyisao:before { + content: "\e6d3"; +} + +.icon-jiageshaixuanshang:before { + content: "\e6d0"; +} + +.icon-jiageshaixuanxia:before { + content: "\e6d1"; +} + +.icon-shouji1:before { + content: "\e6cf"; +} + +.icon-gengduo2:before { + content: "\e6cd"; +} + +.icon-cha1:before { + content: "\e6cb"; +} + +.icon-fasong:before { + content: "\e6be"; +} + +.icon-gengduozhankai:before { + content: "\e6c7"; +} + +.icon-biaoqing:before { + content: "\e6c8"; +} + +.icon-huashu:before { + content: "\e6c9"; +} + +.icon-tupian:before { + content: "\e6ca"; +} + +.icon-mima:before { + content: "\e6ba"; +} + +.icon-zhanghao:before { + content: "\e6bc"; +} + +.icon-fanhui:before { + content: "\e6b9"; +} + +.icon-jinru2:before { + content: "\e6bd"; +} + +.icon-shangpinxinxi:before { + content: "\e6bf"; +} + +.icon-tuichu:before { + content: "\e6c0"; +} + +.icon-jiaoyidingdan:before { + content: "\e6c1"; +} + +.icon-sousuo4:before { + content: "\e6c4"; +} + +.icon-xuanzhong5:before { + content: "\e6c6"; +} + +.icon-VIP2:before { + content: "\e6b8"; +} + +.icon-pinzhong:before { + content: "\e6a2"; +} + +.icon-hanghuo:before { + content: "\e6a3"; +} + +.icon-zhifa:before { + content: "\e6b6"; +} + +.icon-dijia:before { + content: "\e6b7"; +} + +.icon-gerenzhongxin-xuanzhong:before { + content: "\e6ae"; +} + +.icon-xuanzhong4:before { + content: "\e6af"; +} + +.icon-zanwumiaosha:before { + content: "\e6b0"; +} + +.icon-shangchuantupian:before { + content: "\e6b3"; +} + +.icon-fuwu:before { + content: "\e6b4"; +} + +.icon-tuikuantishi:before { + content: "\e6b5"; +} + +.icon-erweima-youxia:before { + content: "\e6ad"; +} + +.icon-erweimabianjiao:before { + content: "\e6ac"; +} + +.icon-weixindenglu1:before { + content: "\e6aa"; +} + +.icon-zhanghaodenglu1:before { + content: "\e6ab"; +} + +.icon-shangjiashijian:before { + content: "\e6a9"; +} + +.icon-jiageshaixuan:before { + content: "\e6a7"; +} + +.icon-gengduofenlei:before { + content: "\e6a8"; +} + +.icon-weixuan:before { + content: "\e6a6"; +} + +.icon-xuanzhong11:before { + content: "\e6a5"; +} + +.icon-pingjia:before { + content: "\e6a4"; +} + +.icon-guanbi4:before { + content: "\e6a0"; +} + +.icon-pinzhongqiquan:before { + content: "\e69d"; +} + +.icon-dijiachangxuan:before { + content: "\e69e"; +} + +.icon-zhengpinhanghuo:before { + content: "\e69f"; +} + +.icon-dizhi-tianjia:before { + content: "\e696"; +} + +.icon-shanchu2:before { + content: "\e69c"; +} + +.icon-yue:before { + content: "\e699"; +} + +.icon-weixinzhifu1:before { + content: "\e69a"; +} + +.icon-shangpinshuliang-jian:before { + content: "\e698"; +} + +.icon-shangpinshuliang-jia:before { + content: "\e697"; +} + +.icon-xuanzhong3:before { + content: "\e693"; +} + +.icon-dizhixiala:before { + content: "\e694"; +} + +.icon-jinru1:before { + content: "\e695"; +} + +.icon-shenqingtuikuan:before { + content: "\e692"; +} + +.icon-peihuo:before { + content: "\e68d"; +} + +.icon-xiadan:before { + content: "\e68e"; +} + +.icon-wancheng:before { + content: "\e68f"; +} + +.icon-fukuan:before { + content: "\e690"; +} + +.icon-fahuo:before { + content: "\e691"; +} + +.icon-saoma:before { + content: "\e68c"; +} + +.icon-tishi:before { + content: "\e68b"; +} + +.icon-xiala2:before { + content: "\e682"; +} + +.icon-VIP1:before { + content: "\e68a"; +} + +.icon-yishoucang:before { + content: "\e683"; +} + +.icon-shoucang2:before { + content: "\e686"; +} + +.icon-kefu2:before { + content: "\e689"; +} + +.icon-fapiao:before { + content: "\e680"; +} + +.icon-fapiaoguanli:before { + content: "\e681"; +} + +.icon-jinru:before { + content: "\e67e"; +} + +.icon-sousuo3:before { + content: "\e67b"; +} + +.icon-dingbu-gouwuche:before { + content: "\e67a"; +} + +.icon-huidaodingbu:before { + content: "\e678"; +} + +.icon-cedaohang-gouwuche:before { + content: "\e676"; +} + +.icon-weixin4:before { + content: "\e675"; +} + +.icon-lianxikefu:before { + content: "\e672"; +} + +.icon-zuo-miaosha:before { + content: "\e670"; +} + +.icon-you-miaosha:before { + content: "\e671"; +} + +.icon-zuo:before { + content: "\e66d"; +} + +.icon-you:before { + content: "\e66f"; +} + +.icon-shoucangbenzhan:before { + content: "\e66c"; +} + +.icon-lianxishangjia:before { + content: "\e668"; +} + +.icon-dingwei:before { + content: "\e667"; +} + +.icon-fenlei2:before { + content: "\e663"; +} + +.icon-wode:before { + content: "\e664"; +} + +.icon-shouye5:before { + content: "\e665"; +} + +.icon-gouwuche5:before { + content: "\e666"; +} + +.icon-jianhao1:before { + content: "\e661"; +} + +.icon-jiahao1:before { + content: "\e662"; +} + +.icon-yanzhengma1:before { + content: "\e65f"; +} + +.icon-shouji:before { + content: "\e660"; +} + +.icon-cha:before { + content: "\e658"; +} + +.icon-shoujihao:before { + content: "\e659"; +} + +.icon-qiye:before { + content: "\e65b"; +} + +.icon-yonghu3:before { + content: "\e65c"; +} + +.icon-yanzhengma:before { + content: "\e65d"; +} + +.icon-shangpin:before { + content: "\e653"; +} + +.icon-qiandao2:before { + content: "\e65a"; +} + +.icon-yaoqing:before { + content: "\ea39"; +} + +.icon-tuihuozhong:before { + content: "\e64f"; +} + +.icon-shenhezhong1:before { + content: "\e650"; +} + +.icon-daituihuo:before { + content: "\e652"; +} + +.icon-yihexiao:before { + content: "\e75f"; +} + +.icon-yijujue1:before { + content: "\e6a1"; +} + +.icon-gengduo1:before { + content: "\e674"; +} + +.icon-tuikuan:before { + content: "\e657"; +} + +.icon-xiaoxi:before { + content: "\e64b"; +} + +.icon-erweima1:before { + content: "\e647"; +} + +.icon-kefu1:before { + content: "\e648"; +} + +.icon-guanzhu:before { + content: "\e645"; +} + +.icon-xiangji:before { + content: "\e6bb"; +} + +.icon-zhuyi-copy:before { + content: "\e688"; +} + +.icon-pingfen:before { + content: "\e649"; +} + +.icon-yingyongAPP_o:before { + content: "\eb88"; +} + +.icon-yizhan_o:before { + content: "\ebc6"; +} + +.icon-shaixuan:before { + content: "\e651"; +} + +.icon-shangjiadingdan:before { + content: "\e64a"; +} + +.icon-shouye4:before { + content: "\e64d"; +} + +.icon-jinbi2:before { + content: "\e63f"; +} + +.icon-jinbi:before { + content: "\e63c"; +} + +.icon-zuobiao:before { + content: "\e6de"; +} + +.icon-jianhao:before { + content: "\e753"; +} + +.icon-jiahao:before { + content: "\e754"; +} + +.icon-zhibojieshux:before { + content: "\e63d"; +} + +.icon-zhibo:before { + content: "\e63e"; +} + +.icon-VIP:before { + content: "\e751"; +} + +.icon-tuiguang:before { + content: "\e63b"; +} + +.icon-geren1:before { + content: "\e750"; +} + +.icon-gouwuche4:before { + content: "\e74f"; +} + +.icon-fenlei1:before { + content: "\e74e"; +} + +.icon-shouye3:before { + content: "\e74c"; +} + +.icon-geren:before { + content: "\e74b"; +} + +.icon-gouwuche3:before { + content: "\e74a"; +} + +.icon-fenlei:before { + content: "\e749"; +} + +.icon-shouye2:before { + content: "\e748"; +} + +.icon-mzshopping:before { + content: "\e746"; +} + +.icon-gongneng:before { + content: "\e63a"; +} + +.icon-gerenzhongxin-copy:before { + content: "\ebc0"; +} + +.icon-shouye1-copy:before { + content: "\ebc1"; +} + +.icon-gerenzhongxin:before { + content: "\e636"; +} + +.icon-shouye1:before { + content: "\e637"; +} + +.icon-gouwuche2:before { + content: "\e638"; +} + +.icon-fenleiyemian:before { + content: "\e639"; +} + +.icon-gouwuche2-copy:before { + content: "\ebc2"; +} + +.icon-fenleiyemian-copy:before { + content: "\ebc3"; +} + +.icon-tonghua:before { + content: "\e740"; +} + +.icon-youjian:before { + content: "\e677"; +} + +.icon-dadianhua01:before { + content: "\e623"; +} + +.icon-paihang:before { + content: "\e73e"; +} + +.icon-weizhi:before { + content: "\e62d"; +} + +.icon-paihang1:before { + content: "\e633"; +} + +.icon-shuoming1:before { + content: "\e673"; +} + +.icon-dianhau:before { + content: "\e634"; +} + +.icon-shijian:before { + content: "\e635"; +} + +.icon-huabanfuben:before { + content: "\e654"; +} + +.icon-jian:before { + content: "\e621"; +} + +.icon-jia:before { + content: "\e7e0"; +} + +.icon-xiugai:before { + content: "\e61f"; +} + +.icon-anniu_jiantouzhankai_o:before { + content: "\eb89"; +} + +.icon-jiantou_xiayiye_o:before { + content: "\eb8f"; +} + +.icon-jiantou_shangxiaqiehuan_o:before { + content: "\eb90"; +} + +.icon-shangxiazhankai_o:before { + content: "\eb9a"; +} + +.icon-dianhua_o:before { + content: "\ebaf"; +} + +.icon-yunshangchuan_o:before { + content: "\ebb3"; +} + +.icon-bingtu_o:before { + content: "\ebb4"; +} + +.icon-baoguo_huanbaohe_o:before { + content: "\ebb6"; +} + +.icon-baoguo_quxiaoshouhuo_o:before { + content: "\ebb7"; +} + +.icon-baoguo_shouhuo_o:before { + content: "\ebb8"; +} + +.icon-baoguo_lingjian_o:before { + content: "\ebb9"; +} + +.icon-baoguo_shouna_o:before { + content: "\ebbe"; +} + +.icon-xianxiazhifu:before { + content: "\e6e1"; +} + +.icon-icon_im_keyboard:before { + content: "\eb97"; +} + +.icon-tupian-:before { + content: "\e73f"; +} + +.icon-icon_im_face:before { + content: "\eb96"; +} + +.icon-yuezhifu:before { + content: "\e65e"; +} + +.icon-yuezhifu1:before { + content: "\e61a"; +} + +.icon-weixinzhifu:before { + content: "\e632"; +} + +.icon-zhifubao:before { + content: "\e61d"; +} + +.icon-haibao:before { + content: "\e73b"; +} + +.icon-weixin3:before { + content: "\e618"; +} + +.icon-crmeb1:before { + content: "\e739"; +} + +.icon-crmeb:before { + content: "\e735"; +} + +.icon-xuanzhong2:before { + content: "\e731"; +} + +.icon-shujutongji:before { + content: "\e732"; +} + +.icon-xiangxishuju:before { + content: "\e733"; +} + +.icon-gengduo:before { + content: "\e734"; +} + +.icon-up:before { + content: "\e617"; +} + +.icon-yonghu2:before { + content: "\e60a"; +} + +.icon-zhinengkefu-:before { + content: "\e616"; +} + +.icon-xiangshang1:before { + content: "\e622"; +} + +.icon-xiangxia2:before { + content: "\ebbd"; +} + +.icon-code_:before { + content: "\e723"; +} + +.icon-code_1:before { + content: "\e724"; +} + +.icon-phone_:before { + content: "\e725"; +} + +.icon-xiala:before { + content: "\e67f"; +} + +.icon-shezhi:before { + content: "\e619"; +} + +.icon-bianji1:before { + content: "\e614"; +} + +.icon-shoucang1:before { + content: "\e714"; +} + +.icon-jiazai:before { + content: "\e62c"; +} + +.icon-2:before { + content: "\e684"; +} + +.icon-tuandui:before { + content: "\e685"; +} + +.icon-jinbi1:before { + content: "\e655"; +} + +.icon-guanbi3:before { + content: "\e6c5"; +} + +.icon-wenti:before { + content: "\e758"; +} + +.icon-ziyuan-xianxing:before { + content: "\e8a4"; +} + +.icon-yonghu1:before { + content: "\e644"; +} + +.icon-dingdan:before { + content: "\e61e"; +} + +.icon-suozi:before { + content: "\e631"; +} + +.icon-quanxianguanlisuozi:before { + content: "\e6d2"; +} + +.icon-lingxing:before { + content: "\e6ff"; +} + +.icon-miaosha:before { + content: "\e6c3"; +} + +.icon-hebingxingzhuang:before { + content: "\e656"; +} + +.icon-kanjia1:before { + content: "\e613"; +} + +.icon-qiandai:before { + content: "\e6b1"; +} + +.icon-tongji:before { + content: "\e687"; +} + +.icon-erweima:before { + content: "\e607"; +} + +.icon-icon34:before { + content: "\e62b"; +} + +.icon-yinhangqia:before { + content: "\e72c"; +} + +.icon-yituikuan:before { + content: "\e6fd"; +} + +.icon-tuikuanzhong:before { + content: "\e6fe"; +} + +.icon-sousuo2:before { + content: "\e757"; +} + +.icon-caidan:before { + content: "\e62a"; +} + +.icon-icon25201:before { + content: "\e70d"; +} + +.icon-shitixing:before { + content: "\e6fb"; +} + +.icon-kongxinxing:before { + content: "\e6fc"; +} + +.icon-pintuanchenggong:before { + content: "\e6f9"; +} + +.icon-pintuanshibai:before { + content: "\e6fa"; +} + +.icon-laba:before { + content: "\e612"; +} + +.icon-xiaolian:before { + content: "\e60f"; +} + +.icon-kanjia:before { + content: "\e69b"; +} + +.icon-shuoming:before { + content: "\e630"; +} + +.icon-mingxi:before { + content: "\e6f7"; +} + +.icon-tishengfenzhi:before { + content: "\e6f8"; +} + +.icon-guanbi2:before { + content: "\e61c"; +} + +.icon-yuandianxiao:before { + content: "\e82f"; +} + +.icon-webicon318:before { + content: "\e6c2"; +} + +.icon-tianjiadizhi:before { + content: "\e640"; +} + +.icon-shanchu:before { + content: "\e628"; +} + +.icon-weixin2:before { + content: "\e604"; +} + +.icon-icon-test:before { + content: "\e6f6"; +} + +.icon-guanbi1:before { + content: "\e6f5"; +} + +.icon-shoucang:before { + content: "\e606"; +} + +.icon-kefu:before { + content: "\e6b2"; +} + +.icon-biankuang:before { + content: "\e6f4"; +} + +.icon-zhuangshixian:before { + content: "\e6f1"; +} + +.icon-jishuzhichi:before { + content: "\e6f3"; +} + +.icon-xuanzhong1:before { + content: "\e6ef"; +} + +.icon-weixuanzhong:before { + content: "\e6f0"; +} + +.icon-xiangshang:before { + content: "\ebbb"; +} + +.icon-xiangxia:before { + content: "\e8ca"; +} + +.icon-cuxiaoguanli:before { + content: "\e60e"; +} + +.icon-shanchu1:before { + content: "\e611"; +} + +.icon-caigou-xianxing:before { + content: "\e887"; +} + +.icon-caigou:before { + content: "\e888"; +} + +.icon-yingyongchengxu-xianxing:before { + content: "\e8a1"; +} + +.icon-yingyongchengxu:before { + content: "\e8a2"; +} + +.icon-shouye:before { + content: "\e8b9"; +} + +.icon-shouye-xianxing:before { + content: "\e8ba"; +} + +.icon-yonghu-xianxing:before { + content: "\e8c8"; +} + +.icon-yonghu:before { + content: "\e8c9"; +} + +.icon-sousuo:before { + content: "\e67d"; +} + +.icon-sousuo1:before { + content: "\e64c"; +} + +.icon-kefu_o:before { + content: "\eb63"; +} + +.icon-liwu_o:before { + content: "\eb65"; +} + +.icon-huobiliu_o:before { + content: "\eb9f"; +} + +.icon-jinbi_o:before { + content: "\eba1"; +} + +.icon-gerentouxiang_o:before { + content: "\ebac"; +} + +.icon-qunzu_o:before { + content: "\ebad"; +} + +.icon-shoucang_o:before { + content: "\ebae"; +} + +.icon-didiandingwei_o:before { + content: "\ebba"; +} + +.icon-xiangyou:before { + content: "\e679"; +} + +.icon-jingpintuijian:before { + content: "\e60d"; +} + +.icon-xinpin:before { + content: "\e610"; +} + +.icon-remen:before { + content: "\e67c"; +} + +.icon-xiangzuo:before { + content: "\ebbc"; +} + +.icon-ditu:before { + content: "\e906"; +} + +.icon-guanbi:before { + content: "\e62f"; +} + +.icon-liulan:before { + content: "\e629"; +} + +.icon-shenhezhong:before { + content: "\e6ce"; +} + +.icon-chongzhi:before { + content: "\e602"; +} + +.icon-iconfontguanbi:before { + content: "\e643"; +} + +.icon-zhekou:before { + content: "\e790"; +} + +.icon-duihao2:before { + content: "\e601"; +} + +.icon-duihao:before { + content: "\e64e"; +} + +.icon-jingyanzhi:before { + content: "\e62e"; +} + +.icon-wuliu:before { + content: "\e6f2"; +} + +.icon-pintuan-copy:before { + content: "\ebbf"; +} + +.icon-arrow:before { + content: "\e627"; +} + +.icon-pintuan:before { + content: "\e60c"; +} + +.icon-youhuiquan:before { + content: "\e6e4"; +} + +.icon-gouwuche1:before { + content: "\e642"; +} + +.icon-pailie:before { + content: "\e61b"; +} + +.icon-tupianpailie:before { + content: "\e620"; +} + +.icon-xiazai5:before { + content: "\e605"; +} + +.icon-weixin1:before { + content: "\e66e"; +} + +.icon-gouwuche:before { + content: "\e669"; +} + +.icon-jiantou:before { + content: "\e641"; +} + +.icon-huiyuan:before { + content: "\e60b"; +} + +.icon-xuanzhong:before { + content: "\e615"; +} + +.icon-complete:before { + content: "\e646"; +} + +.icon-xiala1:before { + content: "\e609"; +} + +.icon-dizhi:before { + content: "\e608"; +} + +.icon-weixin:before { + content: "\e600"; +} + +.icon-fenxiang:before { + content: "\e603"; +} + +.icon-bianji:before { + content: "\e6cc"; +} + +.icon-huangguan:before { + content: "\e624"; +} + +.icon-huangguan1:before { + content: "\e625"; +} + +.icon-huangguan2:before { + content: "\e626"; +} diff --git a/static/images/DH.png b/static/images/DH.png new file mode 100644 index 0000000..8f76431 Binary files /dev/null and b/static/images/DH.png differ diff --git a/static/images/QS.png b/static/images/QS.png new file mode 100644 index 0000000..c72f4ab Binary files /dev/null and b/static/images/QS.png differ diff --git a/static/images/SJ.png b/static/images/SJ.png new file mode 100644 index 0000000..bc6a8c9 Binary files /dev/null and b/static/images/SJ.png differ diff --git a/static/images/che.png b/static/images/che.png new file mode 100644 index 0000000..ef44868 Binary files /dev/null and b/static/images/che.png differ diff --git a/static/images/er.png b/static/images/er.png new file mode 100644 index 0000000..52099c7 Binary files /dev/null and b/static/images/er.png differ diff --git a/static/images/logo.png b/static/images/logo.png new file mode 100644 index 0000000..d1ea5f3 Binary files /dev/null and b/static/images/logo.png differ diff --git a/static/images/xiangyou.png b/static/images/xiangyou.png new file mode 100644 index 0000000..276637c Binary files /dev/null and b/static/images/xiangyou.png differ diff --git a/static/images/yan.png b/static/images/yan.png new file mode 100644 index 0000000..7cfe088 Binary files /dev/null and b/static/images/yan.png differ diff --git a/static/images/zanwu.png b/static/images/zanwu.png new file mode 100644 index 0000000..b218466 Binary files /dev/null and b/static/images/zanwu.png differ diff --git a/static/images/zzw.png b/static/images/zzw.png new file mode 100644 index 0000000..c405081 Binary files /dev/null and b/static/images/zzw.png differ diff --git a/static/mp3/im.mp3 b/static/mp3/im.mp3 new file mode 100644 index 0000000..dc94c50 Binary files /dev/null and b/static/mp3/im.mp3 differ diff --git a/static/mp3/im.wav b/static/mp3/im.wav new file mode 100644 index 0000000..b3a2c2e Binary files /dev/null and b/static/mp3/im.wav differ diff --git a/static/mp3/order.mp3 b/static/mp3/order.mp3 new file mode 100644 index 0000000..3bec7be Binary files /dev/null and b/static/mp3/order.mp3 differ diff --git a/static/server/archives.js b/static/server/archives.js new file mode 100644 index 0000000..54bf388 --- /dev/null +++ b/static/server/archives.js @@ -0,0 +1,13 @@ +export const comonentList = [{ + id: 7, + name: 'plant' + }, + { + id: 8, + name: 'store' + }, + { + id: 32, + name: 'breeding' + } +] \ No newline at end of file diff --git a/static/server/contract.js b/static/server/contract.js new file mode 100644 index 0000000..d034a5a --- /dev/null +++ b/static/server/contract.js @@ -0,0 +1,4 @@ + +export const companyContractType = [23, 24, 25, 29] // 公司合同 +export const personnerContractType = [19, 20, 21, 22] // 个人合同 +export const shareholderContractType = [40] // 股金合同 \ No newline at end of file diff --git a/static/server/server.js b/static/server/server.js new file mode 100644 index 0000000..282381e --- /dev/null +++ b/static/server/server.js @@ -0,0 +1,469 @@ +export const avatar = 'https://cdn.uviewui.com/uview/album/1.jpg' +export const defaultAvatar = + 'https://thirdwx.qlogo.cn/mmopen/vi_32/POgEwh4mIHO4nibH0KlMECNjjGxQUq24ZEaGT4poC6icRiccVGKSyXwibcPq4BWmiaIGuG1icwxaQX6grC9VemZoJ8rg/132' +export const prefix = 'https://lihai001.oss-cn-chengdu.aliyuncs.com/public/kk/' +export const urls = [ + 'https://cdn.uviewui.com/uview/album/1.jpg', + 'https://cdn.uviewui.com/uview/album/2.jpg', + 'https://cdn.uviewui.com/uview/album/3.jpg', + 'https://cdn.uviewui.com/uview/album/4.jpg', + 'https://cdn.uviewui.com/uview/album/7.jpg', + 'https://cdn.uviewui.com/uview/album/6.jpg', + 'https://cdn.uviewui.com/uview/album/5.jpg' +] + +export const wenluData = [ + 'gxsy/fangsahn@2x.png', + 'gxsy/laojiao@2x.png', + 'gxsy/zbgy@2x.png' +] +export const marketData = [{ + title: '江阳区', + text: '醉美泸州 • 中国酒城', + src: 'gxsy/jiangyang@2x.png', + bg: 'gxsy/jiangyang@2x(1).png', + code: '510502' + }, + { + title: '龙马潭区', + text: '中国酒城 • 文明泸州', + src: 'gxsy/longmatan@2x.png', + bg: 'gxsy/longmatan@2x(1).png', + code: '510504' + }, + { + title: '纳溪区', + text: '山水神韵 • 醇香酒城', + src: 'gxsy/naxiqu@2x.png', + bg: 'gxsy/naxi@2x.png', + code: '510503' + }, + { + title: '泸县', + text: '千年古县 • 宋韵龙城', + src: 'gxsy/luxian@2x.png', + bg: 'gxsy/luxian@2x(1).png', + code: '510521' + }, + { + title: '叙永县', + text: '康养竹乡 • 画稿叙永', + src: 'gxsy/xuyongxian@2x.png', + bg: 'gxsy/xuyong@2x.png', + code: '510524' + }, + { + title: '古蔺县', + text: '梦里郎酒 • 画里古蔺', + src: 'gxsy/gulinxian@2x.png', + bg: 'gxsy/jiangyang@2x(1).png', + code: '510525' + }, { + title: '合江县', + text: '千年荔城 • 甜美合江', + src: 'gxsy/hejaingxian@2x.png', + bg: 'gxsy/hejaing@2x.png', + code: '510522' + } +] +export const shichangData = [{ + url: 'img4@2x.png', + title: 'rexiao@2x.png', + text: '农业生产产品' + }, + { + url: 'img5@2x.png', + title: 'dangji@2x.png', + text: '村名生活用品' + } +] +export const openList = [{ + title: '党建在线', + text: '党建资讯文章', + src: 'djzx@2x.png', + color: '#FF614D', + pid: 295, + navCallBack: (pid, t, id) => { + uni.navigateTo({ + url: `/pages/service_hall/party_building?pid=${pid}&title=${t}&village_id=${id}` + }) + } + }, + { + title: '村务动态', + text: '村务信息公开', + src: 'cwdt@2x.png', + color: '#4DB896', + pid: 300, + navCallBack: (pid, t, id) => { + uni.navigateTo({ + url: `/pages/service_hall/party_building?pid=${pid}&title=${t}&village_id=${id}` + }) + } + }, + { + title: '村镇新闻', + text: '村镇新闻资讯', + src: 'czxw@2x.png', + color: '#FFAA33', + pid: 304, + navCallBack: (pid, t, id) => { + uni.navigateTo({ + url: `/pages/service_hall/list?id=${pid}&title=${t}&village_id=${id}` + }) + } + }, + { + title: '文明实践', + text: '文明创建实践', + src: 'wmsj@2x.png', + color: '#FF7A3D', + pid: '', + navCallBack: (pid, t, id) => { + uni.navigateTo({ + url: `/pages/service_hall/opens` + }) + } + } +] +export const quickLink = [{ + icon: 'scfw', + src: 'scfw.png', + name: '商超服务', + url: '/pages/fast_track/production', + category_id: 25 + }, + { + icon: 'nfcp', + src: 'nfcp.png', + name: '农副产品', + url: '/pages/fast_track/production', + category_id: 26 + }, { + icon: 'sczl', + src: 'sczl.png', + name: '生产资料', + url: '/pages/fast_track/production', + category_id: 22 + }, { + icon: 'shfw', + src: 'shfw.png', + name: '生活服务', + // url: '/pages/fast_track/service_life', + url: '/pages/fast_track/production', + category_id: 23 + }, { + icon: 'hbxs', + src: 'hbxs.png', + name: '红白喜事', + // url: '/pages/fast_track/red_white_thing', + url: '/pages/fast_track/production', + category_id: 21 + }, { + icon: 'wyly', + src: 'wyly.png', + name: '文娱旅游', + // url: '/pages/fast_track/travel' + }, { + icon: 'fwzx', + src: 'fwzx.png', + name: '房屋装修', + // url: '/pages/fast_track/fitment' + }, { + icon: 'jypx', + src: 'jypx.png', + name: '教育资讯', + // url: '/pages/fast_track/education' + }, { + icon: 'msgy', + src: 'msgy.png', + name: '民生资讯', + // url: '/pages/fast_track/public_benefit' + }, { + icon: 'ylbj', + src: 'ylbj.png', + name: '医疗资讯' + } +] + +// oaHOme快速入口数据 +export const oaHomeData = [{ + name: '公司信息', + icon: '../../static/img/home/GSXX.png', + paths: '/subpkg/companyInfo/companyInfo', + admin: true + }, + { + name: '人员管理', + icon: '../../static/img/home/RYGL.png', + paths: '/subpkg/personnel/personnel', + admin: true + }, + { + name: '固定资产', + icon: '../../static/img/home/GDZC.png', + paths: '/subpkg/property/index', + admin: true + }, + { + name: '合同管理', + icon: '../../static/img/home/HTGL.png', + paths: '/subpkg/contract/contract' + }, + // { + // name: '公司管理', + // icon: '../../static/img/home/GSXX.png', + // paths: '/subpkg/companyAdmin/companyAdmin', + // admin: true + // }, + { + name: '任务管理', + icon: '../../static/img/home/RWGL.png', + paths: '/subpkg/taskAdmin/taskAdmin', + }, + { + name: '档案管理', + icon: '../../static/img/home/DAGL.png', + paths: '/subpkg/captain/captain', + admin: true + }, + { + name: '档案管理', + icon: '../../static/img/home/DAGL.png', + paths: '/subpkg/archives/archives', + captain: true + }, + // { + // name: '片区经理', + // icon: '../../static/img/home/GRCW.png', + // paths: '/pages/oaManager/oaManager', + // admin: true + // }, + { + name: '个人财务', + icon: '../../static/img/home/GRCW.png', + paths: '/subpkg/finance/finance' + }, + { + name: '待取驿站', + icon: '../../static/img/home/YZ.png', + paths: '/pages/logistics/post', + // captain: true + }, + // { + // name: '出差申请', + // icon: prefix + 'oa/ccsq@2x.png' + // }, + // { + // name: '外出申请', + // icon: prefix + 'oa/wcsq@2x.png' + // }, + // { + // name: '采购申请', + // icon: prefix + 'oa/cgsq@2x.png' + // }, + // { + // name: '物品维修', + // icon: prefix + 'oa/bxsq@2x.png' + // }, + // { + // name: '用章申请', + // icon: prefix + 'oa/yzsq@2x.png' + // }, + // { + // name: '报销申请', + // icon: prefix + 'oa/gengduo@2x.png' + // }, + { + name: '更多', + icon: prefix + 'oa/wpwx@2x.png', + paths: '/pages/views/application' + } +] + +/** + * oa-应用中心数据 + */ +export const appDataList = [{ + title: '假勤', + data: [{ + name: '请假申请', + src: prefix + 'oa/qjsq@2x.png', + url: '/pages/views/leave_request' + }, + { + name: '出差申请', + src: prefix + 'oa/ccsq@2x.png', + url: '' + }, + { + name: '外出申请', + src: prefix + 'oa/wcsq@2x.png', + url: '' + } + ] + }, + { + title: '行政', + data: [{ + name: '物品维修', + src: prefix + 'oa/bxsq@2x.png', + url: '' + }, + { + name: '用章审批', + src: prefix + 'oa/yzsq@2x.png', + url: '' + }, + { + name: '领用审批', + src: prefix + 'oa/lysp@2x.png', + url: '' + } + ] + }, + { + title: '财务', + data: [{ + name: '借款申请', + src: prefix + 'oa/jksq@2x.png', + url: '' + }, + { + name: '付款申请', + src: prefix + 'oa/fksq@2x.png', + url: '' + }, + { + name: '报销申请', + src: prefix + 'oa/gengduo@2x.png', + url: '' + }, + { + name: '采购申请', + src: prefix + 'oa/cgsq@2x.png', + url: '' + }, + { + name: '奖励申请', + src: prefix + 'oa/jlsq@2x.png', + url: '' + }, + { + name: '活动经费', + src: prefix + 'oa/hdjf@2x.png', + url: '' + } + ] + }, + { + title: '人事', + data: [{ + name: '招聘需求', + src: prefix + 'oa/zpxq@2x.png', + url: '' + }] + }, + { + title: '其他', + data: [{ + name: '通用审批', + src: prefix + 'oa/tysp@2x.png', + url: '/pages/views/com_approve' + }] + } +] + +/** + * oa-个人中心 + */ +export const myOaData = [ + // { + // name: '流水详情', + // icon: '../../static/icons/runningWater.png', + // url: '/subpkg/orderDetail/orderDetail' + // }, + // { + // name: '管理后台', + // icon: '../../static/icons/backstage.png', + // // url: '/pages/views/personal_center_two' + // }, + { + name: '片区经理', + icon: '../../static/icons/manager.png', + url: '/pages/oaManager/oaManager' + }, + { + name: '安全设置', + icon: '../../static/icons/setting.png', + url: '/pages/updatePassword/updatePassword' + }, + // { + // name: '管理后台', + // icon: 'custom-icongongzi', + // // url: '/pages/views/personal_center_two' + // }, + // { + // name: '片区经理', + // icon: 'custom-icongongzi', + // url: '/pages/oaManager/oaManager' + // }, + // { + // name: '工资详情', + // icon: 'custom-icongongzi', + // url: '/pages/views/personal_center_two' + // }, + // { + // name: '公示文档', + // icon: 'custom-iconwendang', + // url: '/pages/views/public_document' + // }, + // { + // name: '绑定公众号', + // icon: 'custom-iconweixin' + // }, + // { + // name: '意见反馈', + // icon: 'custom-iconyijian' + // } +] +/* + oa-请假类型 + */ +export const oaLeaveData = [{ + name: '事假', + id: 1 + }, + { + name: '年假', + id: 2 + }, + { + name: '调休假', + id: 3 + }, + { + name: '病假', + id: 4 + }, + { + name: '婚假', + id: 5 + }, + { + name: '丧假', + id: 6 + }, + { + name: '产假', + id: 7 + }, + { + name: '陪产假', + id: 8 + }, + { + name: '其他', + id: 9 + } +] \ No newline at end of file diff --git a/static/tabbar_icon/a-a.png b/static/tabbar_icon/a-a.png new file mode 100644 index 0000000..53ffacd Binary files /dev/null and b/static/tabbar_icon/a-a.png differ diff --git a/static/tabbar_icon/a.png b/static/tabbar_icon/a.png new file mode 100644 index 0000000..df23792 Binary files /dev/null and b/static/tabbar_icon/a.png differ diff --git a/static/tabbar_icon/b-b.png b/static/tabbar_icon/b-b.png new file mode 100644 index 0000000..fbbf19e Binary files /dev/null and b/static/tabbar_icon/b-b.png differ diff --git a/static/tabbar_icon/b.png b/static/tabbar_icon/b.png new file mode 100644 index 0000000..cc734f5 Binary files /dev/null and b/static/tabbar_icon/b.png differ diff --git a/static/tabbar_icon/c-c.png b/static/tabbar_icon/c-c.png new file mode 100644 index 0000000..3a701f0 Binary files /dev/null and b/static/tabbar_icon/c-c.png differ diff --git a/static/tabbar_icon/c.png b/static/tabbar_icon/c.png new file mode 100644 index 0000000..ae51402 Binary files /dev/null and b/static/tabbar_icon/c.png differ diff --git a/static/tabbar_icon/d-d.png b/static/tabbar_icon/d-d.png new file mode 100644 index 0000000..2effa74 Binary files /dev/null and b/static/tabbar_icon/d-d.png differ diff --git a/static/tabbar_icon/d.png b/static/tabbar_icon/d.png new file mode 100644 index 0000000..21b035f Binary files /dev/null and b/static/tabbar_icon/d.png differ diff --git a/store/getters.js b/store/getters.js new file mode 100644 index 0000000..d4d2ad0 --- /dev/null +++ b/store/getters.js @@ -0,0 +1,13 @@ +export default { + token: state => state.app.token, + isLogin: state => !!state.app.token, + userInfo: state => state.app.userInfo || {}, + eyeType: state => state.config.eyeType || true, + config: state => state.config.config || {} +}; +// export default { +// token: state => 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJrYWlmYS5jcm1lYi5uZXQiLCJhdWQiOiJrYWlmYS5jcm1lYi5uZXQiLCJpYXQiOjE1NzcwODM1MzQsIm5iZiI6MTU3NzA4MzUzNCwiZXhwIjoxNTc3MDk0MzM0LCJqdGkiOnsiaWQiOjExMCwidHlwZSI6InVzZXIifX0.U-i1pbdRjyXI1gr79Uq2XBPZ89T8f5Ai9jwrR8woTwE', +// isLogin: state => true, +// backgroundColor: state => state.app.backgroundColor, +// userInfo: state => state.app.userInfo || {} +// }; diff --git a/store/index.js b/store/index.js new file mode 100644 index 0000000..bf9c8ff --- /dev/null +++ b/store/index.js @@ -0,0 +1,20 @@ +// +---------------------------------------------------------------------- +// | CRMEB [ CRMEB赋能开发者,助力企业发展 ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权 +// +---------------------------------------------------------------------- +// | Author: CRMEB Team +// +---------------------------------------------------------------------- +import Vue from "vue"; +import Vuex from "vuex"; +import modules from "./modules"; +import getters from "./getters"; + +Vue.use(Vuex); + +export default new Vuex.Store({ + modules, + getters, +}); diff --git a/store/modules/app.js b/store/modules/app.js new file mode 100644 index 0000000..bb3aab9 --- /dev/null +++ b/store/modules/app.js @@ -0,0 +1,121 @@ +import { commonAuth } from '@/api/pubic.js' +import { loginMobile } from '@/api/user.js' +import { loginAccount } from '@/api/oaUser.js' +import Routine from '@/libs/routine.js' +import Cache from '@/utils/cache'; +import encrypt from '@/utils/encrypt.js'; +import oaHttp from '@/utils/oahttp.js'; + +const state = { + userInfo: JSON.parse(Cache.get('USER_INFO') || '{}') || null, + token: Cache.get("TOKEN") || null +}; + +const mutations = { + setUserInfo(state, data) { + state.userInfo = data + Cache.set("USER_INFO", data) + }, + LOGOUT(state) { + Cache.clear('USER_INFO') + Cache.clear('TOKEN') + uni.showModal({ + content: '登录已过期,是否重新登录?', + success(e) { + if (e.confirm) uni.reLaunch({ + url: '/pages/oaLogin/oaLogin' + }) + } + }) + }, + CLEAR(state) { + state.userInfo = null; + state.token = null; + Cache.clear('USER_INFO') + Cache.clear('TOKEN') + }, + UPDATE_USERINFO(state, data) { + let time = res.data.result.expires_time - Cache.time(); + state.userInfo = data.result.user + state.token = data.result.token + Cache.set("USER_INFO", data.result.user, time) + Cache.set("TOKEN", data.result.token, time) + }, + SET_USERINFO(state, data) { + let time = Cache.time(); + state.userInfo = data.user + state.token = data.token + Cache.set("USER_INFO", data.user, time) + Cache.set("TOKEN", data.token, time) + }, + SET_TOKEN(state, data) { + let time = Cache.time(); + state.token = data.token; + Cache.set("TOKEN", data.token, time); + }, +}; + +const actions = { + RE_LOGIN({ state, commit }, data) { + return new Promise((resolve, reject) => { + let fromData = encrypt.decode('ACT'); + if(fromData) { + loginAccount({ ...fromData }, true).then((res) => { + commit('SET_TOKEN', res.data); + oaHttp[data.method](data.url, data.data, data.opt).then((e) => { + resolve(e); + }).catch((err) => { + reject(err) + }) + }).catch((err) => { + commit('LOGOUT') + reject(err) + }) + }else { + commit('LOGOUT') + reject(); + } + }) + }, + MobileLogin({ state, commit }, force) { + let data = { + auth_token: uni.getStorageSync('auth_token'), + phone: force.account, + sms_code: force.captcha, + spread: that.$Cache.get("spread"), + // #ifdef APP-PLUS + user_type: 'app', + // #endif + // #ifdef H5 + user_type: 'h5', + // #endif + } + loginMobile(data).then(res => { + console.log('手机号登录', res); + }) + }, + async getWxLogin({ state, commit }, force) { + let newCode = null + Routine.getCode().then(code => { + newCode = code; + }) + Routine.getUserProfile().then(res => { + let userInfo = res.userInfo; + userInfo.code = newCode; + commonAuth({ + auth: { + type: 'routine', + auth: userInfo + } + }).then(res => { + commit("UPDATE_USERINFO", res.data); + }) + }) + } +}; + +export default { + state, + mutations, + actions +}; \ No newline at end of file diff --git a/store/modules/config.js b/store/modules/config.js new file mode 100644 index 0000000..9a99176 --- /dev/null +++ b/store/modules/config.js @@ -0,0 +1,83 @@ +import Cache from '@/utils/cache'; +import { getConfig } from "@/api/config.js"; + + + + + + +const state = { + eyeType: Cache.get('eyeType') || true, // 小眼睛 + request: Cache.get('request') || true, // 网络请求 + config: JSON.parse(Cache.get('config')||'{}'), + updateFlag: true +}; + +const mutations = { + SET_EYE_TYPE(state){ + state.eyeType=!state.eyeType; + Cache.set('eyeType', state.eyeType); + }, + SET_REQUEST(state, data=true){ + state.request = data; + Cache.set('request', state.request); + }, + SET_CONFIG(state, data){ + state.config = {...data}; + Cache.set('config', JSON.stringify(state.config)); + }, + SET_UPDATEFLAG(state, data){ + state.updateFlag = data; + }, +}; + +const actions = { + async initConfig({ state, commit }, data = false) { + let res = await getConfig(); + commit('SET_CONFIG', res.data); + // console.log(compareVersions(res.data.version, '1.0.0')==1&&compareVersions(res.data.version, Cache.get('wgt_version'))==1); + if(uni.getStorageSync('uniMP')||!state.updateFlag) return ;//是小程序环境时不进行更新 + let os = uni.getSystemInfoSync(); + // uni.showModal({ + // title: `当前:${os.appVersion},WGT:${Cache.get('wgt_version')},返回:${res.data.version}` + // }) + // #ifdef APP-PLUS + if(data) uni.showLoading({ + title: '检查更新中' + }) + const wgt_v = uni.getStorageSync('wgt_version')||'1.0.0'; + commit('SET_UPDATEFLAG', false); + // 版本更新 + if(compareVersions(res.data.version, os.appWgtVersion||wgt_v)==1&&compareVersions(res.data.version, wgt_v)==1){ + try{ + let info = res.data.version_info||{}; + let version = { + title: info.title||'发现新版本', + content: info.content||'修复了部分BUG', + versionName: info.version||'1.0.1', + downUrl: info.dow_url||'', + force: info.force==1?true:false, // 是否强制更新 + quiet: info.quiet==1?true:false // 是否静默更新 + } + Updater.update(version);; + }catch(e){ + console.log(e); + } + if(data) uni.hideLoading(); + }else if(data){ + uni.hideLoading(); + uni.showToast({ + title: '已经是最新版本了', + icon: 'none' + }) + } + // #endif + } +}; + + +export default { + state, + mutations, + actions +}; diff --git a/store/modules/index.js b/store/modules/index.js new file mode 100644 index 0000000..4a6214d --- /dev/null +++ b/store/modules/index.js @@ -0,0 +1,15 @@ +// +---------------------------------------------------------------------- +// | CRMEB [ CRMEB赋能开发者,助力企业发展 ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2016~2021 https://www.crmeb.com All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权 +// +---------------------------------------------------------------------- +// | Author: CRMEB Team +// +---------------------------------------------------------------------- +import app from "./app"; +import config from "./config"; +export default { + app, + config +}; diff --git a/uni_modules/hx-lottie/changelog.md b/uni_modules/hx-lottie/changelog.md new file mode 100644 index 0000000..101fd5e --- /dev/null +++ b/uni_modules/hx-lottie/changelog.md @@ -0,0 +1,2 @@ +## 1.0.0(2022-04-15) +1.0.0 diff --git a/uni_modules/hx-lottie/components/hx-lottie/hx-lottie.vue b/uni_modules/hx-lottie/components/hx-lottie/hx-lottie.vue new file mode 100644 index 0000000..b3a5a74 --- /dev/null +++ b/uni_modules/hx-lottie/components/hx-lottie/hx-lottie.vue @@ -0,0 +1,152 @@ + + + + diff --git a/uni_modules/hx-lottie/components/hx-lottie/lottie-miniprogram.min.js b/uni_modules/hx-lottie/components/hx-lottie/lottie-miniprogram.min.js new file mode 100644 index 0000000..d42af38 --- /dev/null +++ b/uni_modules/hx-lottie/components/hx-lottie/lottie-miniprogram.min.js @@ -0,0 +1,9 @@ +!function(t,e){for(var r in e)t[r]=e[r]}(exports,function(t){var e={};function r(i){if(e[i])return e[i].exports;var s=e[i]={i:i,l:!1,exports:{}};return t[i].call(s.exports,s,s.exports,r),s.l=!0,s.exports}return r.m=t,r.c=e,r.d=function(t,e,i){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(t,e){if(1&e&&(t=r(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var i=Object.create(null);if(r.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var s in t)r.d(i,s,function(e){return t[e]}.bind(null,s));return i},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=1)}([function(t,e,r){"use strict";function i(t,e){for(var r=0;r1?e-1:0),i=1;i0&&void 0!==arguments[0]?arguments[0]:"";if(this.readyState!==t.OPENED)throw new Error("Failed to execute 'send' on 'XMLHttpRequest': The object's state must be OPENED.");wx.request({data:r,url:a.get(this),method:n.get(this),header:o.get(this),success:function(r){var i=r.data,s=r.statusCode,a=r.header;if("string"!=typeof i&&!(i instanceof ArrayBuffer))try{i=JSON.stringify(i)}catch(t){}if(e.status=s,h.set(e,a),p.call(e,"loadstart"),f.call(e,t.HEADERS_RECEIVED),f.call(e,t.LOADING),e.response=i,i instanceof ArrayBuffer){e.responseText="";for(var n=new Uint8Array(i),o=n.byteLength,l=0;l1?r[1]=1:r[1]<=0&&(r[1]=0),HSVtoRGB(r[0],r[1],r[2])}function addBrightnessToRGB(t,e){var r=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return r[2]+=e,r[2]>1?r[2]=1:r[2]<0&&(r[2]=0),HSVtoRGB(r[0],r[1],r[2])}function addHueToRGB(t,e){var r=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return r[0]+=e/360,r[0]>1?r[0]-=1:r[0]<0&&(r[0]+=1),HSVtoRGB(r[0],r[1],r[2])}var rgbToHex=function(){var t,e,r=[];for(t=0;t<256;t+=1)e=t.toString(16),r[t]=1==e.length?"0"+e:e;return function(t,e,i){return t<0&&(t=0),e<0&&(e=0),i<0&&(i=0),"#"+r[t]+r[e]+r[i]}}();function BaseEvent(){}BaseEvent.prototype={triggerEvent:function(t,e){if(this._cbs[t])for(var r=this._cbs[t].length,i=0;i0||t>-1e-6&&t<0?i(1e4*t)/1e4:t}function I(){var t=this.props;return"matrix("+M(t[0])+","+M(t[1])+","+M(t[4])+","+M(t[5])+","+M(t[12])+","+M(t[13])+")"}return function(){this.reset=s,this.rotate=a,this.rotateX=n,this.rotateY=o,this.rotateZ=h,this.skew=p,this.skewFromAxis=f,this.shear=l,this.scale=m,this.setTransform=c,this.translate=d,this.transform=u,this.applyToPoint=P,this.applyToX=_,this.applyToY=x,this.applyToZ=S,this.applyToPointArray=A,this.applyToTriplePoints=C,this.applyToPointStringified=k,this.toCSS=D,this.to2dCSS=I,this.clone=v,this.cloneFromProps=b,this.equals=g,this.inversePoints=E,this.inversePoint=T,this._t=this.transform,this.isIdentity=y,this._identity=!0,this._identityCalculated=!1,this.props=createTypedArray("float32",16),this.reset()}}(); +/*! + Transformation Matrix v2.0 + (c) Epistemex 2014-2015 + www.epistemex.com + By Ken Fyrstenberg + Contributions by leeoniya. + License: MIT, header required. + */!function(t,e){var r,i=this,s=256,a=6,n="random",o=e.pow(s,a),h=e.pow(2,52),l=2*h,p=s-1;function f(t){var e,r=t.length,i=this,a=0,n=i.i=i.j=0,o=i.S=[];for(r||(t=[r++]);a=l;)t/=2,e/=2,r>>>=1;return(t+r)/e};return P.int32=function(){return 0|b.g(4)},P.quick=function(){return b.g(4)/4294967296},P.double=P,c(d(b.S),t),(u.pass||y||function(t,r,i,s){return s&&(s.S&&m(s,b),t.state=function(){return m(b,{})}),i?(e[n]=t,r):t})(P,v,"global"in u?u.global:this==e,u.state)},c(e.random(),t)}([],BMMath);var BezierFactory=function(){var t={getBezierEasing:function(t,r,i,s,a){var n=a||("bez_"+t+"_"+r+"_"+i+"_"+s).replace(/\./g,"p");if(e[n])return e[n];var o=new c([t,r,i,s]);return e[n]=o,o}},e={};var r=4,i=1e-7,s=10,a=11,n=1/(a-1),o="function"==typeof Float32Array;function h(t,e){return 1-3*e+3*t}function l(t,e){return 3*e-6*t}function p(t){return 3*t}function f(t,e,r){return((h(e,r)*t+l(e,r))*t+p(e))*t}function m(t,e,r){return 3*h(e,r)*t*t+2*l(e,r)*t+p(e)}function c(t){this._p=t,this._mSampleValues=o?new Float32Array(a):new Array(a),this._precomputed=!1,this.get=this.get.bind(this)}return c.prototype={get:function(t){var e=this._p[0],r=this._p[1],i=this._p[2],s=this._p[3];return this._precomputed||this._precompute(),e===r&&i===s?t:0===t?0:1===t?1:f(this._getTForX(t),r,s)},_precompute:function(){var t=this._p[0],e=this._p[1],r=this._p[2],i=this._p[3];this._precomputed=!0,t===e&&r===i||this._calcSampleValues()},_calcSampleValues:function(){for(var t=this._p[0],e=this._p[2],r=0;r=.001?function(t,e,i,s){for(var a=0;a0?r=h:e=h}while(Math.abs(o)>i&&++l-.001&&n<.001}var e=function(t,e,r,i){var s,a,n,o,h,l,p=defaultCurveSegments,f=0,m=[],c=[],d=bezier_length_pool.newElement();for(n=r.length,s=0;sn?-1:1,l=!0;l;)if(i[a]<=n&&i[a+1]>n?(o=(n-i[a])/(i[a+1]-i[a]),l=!1):a+=h,a<0||a>=s-1){if(a===s-1)return r[a];l=!1}return r[a]+(r[a+1]-r[a])*o}var o=createTypedArray("float32",8);return{getSegmentsLength:function(t){var r,i=segments_length_pool.newElement(),s=t.c,a=t.v,n=t.o,o=t.i,h=t._length,l=i.lengths,p=0;for(r=0;r1?1:s,h),f=n(a=a>1?1:a,h),m=t.length,c=1-p,d=1-f,u=c*c*c,y=p*c*c*3,g=p*p*c*3,v=p*p*p,b=c*c*d,P=p*c*d+c*p*d+c*c*f,_=p*p*d+c*p*f+p*c*f,x=p*p*f,S=c*d*d,T=p*d*d+c*f*d+c*d*f,E=p*f*d+c*f*f+p*d*f,C=p*f*f,A=d*d*d,k=f*d*d+d*f*d+d*d*f,D=f*f*d+d*f*f+f*d*f,M=f*f*f;for(l=0;lm?f>c?f-m-c:c-m-f:c>m?c-m-f:m-f-c)>-1e-4&&p<1e-4}}}!function(){for(var t=0,e=["ms","moz","webkit","o"],r=0;r=0;i-=1)if("sh"==t[i].ty){if(t[i].ks.k.i)r(t[i].ks.k);else for(a=t[i].ks.k.length,s=0;sr[0]||!(r[0]>t[0])&&(t[1]>r[1]||!(r[1]>t[1])&&(t[2]>r[2]||!(r[2]>t[2])&&void 0))}var s,a=function(){var t=[4,4,14];function e(t){var e,r,i,s=t.length;for(e=0;e=0;r-=1)if("sh"==t[r].ty){if(t[r].ks.k.i)t[r].ks.k.c=t[r].closed;else for(s=t[r].ks.k.length,i=0;i0&&(p=!1),p){var f=createTag("style");f.setAttribute("f-forigin",a[r].fOrigin),f.setAttribute("f-origin",a[r].origin),f.setAttribute("f-family",a[r].fFamily),f.type="text/css",f.innerHTML="@font-face {font-family: "+a[r].fFamily+"; font-style: normal; src: url('"+a[r].fPath+"');}",e.appendChild(f)}}else if("g"===a[r].fOrigin||1===a[r].origin){for(h=document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]'),l=0;l=n.t-s){a.h&&(a=n),c=0;break}if(n.t-s>t){c=d;break}d=v||t=v?P.points.length-1:0;for(h=P.points[_].point.length,o=0;o=T&&S=v)r[0]=g[0],r[1]=g[1],r[2]=g[2];else if(t<=b)r[0]=a.s[0],r[1]=a.s[1],r[2]=a.s[2];else{!function(t,e){var r=e[0],i=e[1],s=e[2],a=e[3],n=Math.atan2(2*i*a-2*r*s,1-2*i*i-2*s*s),o=Math.asin(2*r*i+2*s*a),h=Math.atan2(2*r*a-2*i*s,1-2*r*r-2*s*s);t[0]=n/degToRads,t[1]=o/degToRads,t[2]=h/degToRads}(r,function(t,e,r){var i,s,a,n,o,h=[],l=t[0],p=t[1],f=t[2],m=t[3],c=e[0],d=e[1],u=e[2],y=e[3];(s=l*c+p*d+f*u+m*y)<0&&(s=-s,c=-c,d=-d,u=-u,y=-y);1-s>1e-6?(i=Math.acos(s),a=Math.sin(i),n=Math.sin((1-r)*i)/a,o=Math.sin(r*i)/a):(n=1-r,o=r);return h[0]=n*l+o*c,h[1]=n*p+o*d,h[2]=n*f+o*u,h[3]=n*m+o*y,h}(i(a.s),i(g),(t-b)/(v-b)))}else for(d=0;d=v?l=1:t=i&&e>=i||this._caching.lastFrame=e&&(this._caching._lastKeyframeIndex=-1,this._caching.lastIndex=0);var s=this.interpolateValue(e,this._caching);this.pv=s}return this._caching.lastFrame=e,this.pv}function a(t){var r;if("unidimensional"===this.propType)r=t*this.mult,e(this.v-r)>1e-5&&(this.v=r,this._mdf=!0);else for(var i=0,s=this.v.length;i1e-5&&(this.v[i]=r,this._mdf=!0),i+=1}function n(){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{this.lock=!0,this._mdf=this._isFirstFrame;var t,e=this.effectsSequence.length,r=this.kf?this.pv:this.data.k;for(t=0;t=this.p.keyframes[this.p.keyframes.length-1].t?(e=this.p.getValueAtTime(this.p.keyframes[this.p.keyframes.length-1].t/i,0),r=this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length-1].t-.01)/i,0)):(e=this.p.pv,r=this.p.getValueAtTime((this.p._caching.lastFrame+this.p.offsetTime-.01)/i,this.p.offsetTime));else if(this.px&&this.px.keyframes&&this.py.keyframes&&this.px.getValueAtTime&&this.py.getValueAtTime){e=[],r=[];var s=this.px,a=this.py;s._caching.lastFrame+s.offsetTime<=s.keyframes[0].t?(e[0]=s.getValueAtTime((s.keyframes[0].t+.01)/i,0),e[1]=a.getValueAtTime((a.keyframes[0].t+.01)/i,0),r[0]=s.getValueAtTime(s.keyframes[0].t/i,0),r[1]=a.getValueAtTime(a.keyframes[0].t/i,0)):s._caching.lastFrame+s.offsetTime>=s.keyframes[s.keyframes.length-1].t?(e[0]=s.getValueAtTime(s.keyframes[s.keyframes.length-1].t/i,0),e[1]=a.getValueAtTime(a.keyframes[a.keyframes.length-1].t/i,0),r[0]=s.getValueAtTime((s.keyframes[s.keyframes.length-1].t-.01)/i,0),r[1]=a.getValueAtTime((a.keyframes[a.keyframes.length-1].t-.01)/i,0)):(e=[s.pv,a.pv],r[0]=s.getValueAtTime((s._caching.lastFrame+s.offsetTime-.01)/i,s.offsetTime),r[1]=a.getValueAtTime((a._caching.lastFrame+a.offsetTime-.01)/i,a.offsetTime))}this.v.rotate(-Math.atan2(e[1]-r[1],e[0]-r[0]))}this.data.p&&this.data.p.s?this.data.p.z?this.v.translate(this.px.v,this.py.v,-this.pz.v):this.v.translate(this.px.v,this.py.v,0):this.v.translate(this.p.v[0],this.p.v[1],-this.p.v[2])}this.frameId=this.elem.globalData.frameId}},precalculateMatrix:function(){if(!this.a.k&&(this.pre.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations=1,!this.s.effectsSequence.length)){if(this.pre.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.appliedTransformations=2,this.sk){if(this.sk.effectsSequence.length||this.sa.effectsSequence.length)return;this.pre.skewFromAxis(-this.sk.v,this.sa.v),this.appliedTransformations=3}if(this.r){if(this.r.effectsSequence.length)return;this.pre.rotate(-this.r.v),this.appliedTransformations=4}else this.rz.effectsSequence.length||this.ry.effectsSequence.length||this.rx.effectsSequence.length||this.or.effectsSequence.length||(this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.appliedTransformations=4)}},autoOrient:function(){}},extendPrototype([DynamicPropertyContainer],t),t.prototype.addDynamicProperty=function(t){this._addDynamicProperty(t),this.elem.addDynamicProperty(t),this._isDirty=!0},t.prototype._addDynamicProperty=DynamicPropertyContainer.prototype.addDynamicProperty,{getTransformProperty:function(e,r,i){return new t(e,r,i)}}}();function ShapePath(){this.c=!1,this._length=0,this._maxLength=8,this.v=createSizedArray(this._maxLength),this.o=createSizedArray(this._maxLength),this.i=createSizedArray(this._maxLength)}ShapePath.prototype.setPathData=function(t,e){this.c=t,this.setLength(e);for(var r=0;r=this._maxLength&&this.doubleArrayLength(),r){case"v":a=this.v;break;case"i":a=this.i;break;case"o":a=this.o}(!a[i]||a[i]&&!s)&&(a[i]=point_pool.newElement()),a[i][0]=t,a[i][1]=e},ShapePath.prototype.setTripleAt=function(t,e,r,i,s,a,n,o){this.setXYAt(t,e,"v",n,o),this.setXYAt(r,i,"o",n,o),this.setXYAt(s,a,"i",n,o)},ShapePath.prototype.reverse=function(){var t=new ShapePath;t.setPathData(this.c,this._length);var e=this.v,r=this.o,i=this.i,s=0;this.c&&(t.setTripleAt(e[0][0],e[0][1],i[0][0],i[0][1],r[0][0],r[0][1],0,!1),s=1);var a,n=this._length-1,o=this._length;for(a=s;a=c[c.length-1].t-this.offsetTime)i=c[c.length-1].s?c[c.length-1].s[0]:c[c.length-2].e[0],a=!0;else{for(var d,u,y=m,g=c.length-1,v=!0;v&&(d=c[y],!((u=c[y+1]).t-this.offsetTime>t));)y=u.t-this.offsetTime)p=1;else if(ti&&e>i)||(this._caching.lastIndex=s=1?a.push({s:t-1,e:e-1}):(a.push({s:t,e:1}),a.push({s:0,e:e-1}));var n,o,h=[],l=a.length;for(n=0;ni+r);else p=o.s*s<=i?0:(o.s*s-i)/r,f=o.e*s>=i+r?1:(o.e*s-i)/r,h.push([p,f])}return h.length||h.push([0,0]),h},TrimModifier.prototype.releasePathsData=function(t){var e,r=t.length;for(e=0;e1?1:this.s.v<0?0:this.s.v)+s)>(r=(this.e.v>1?1:this.e.v<0?0:this.e.v)+s)){var a=e;e=r,r=a}e=1e-4*Math.round(1e4*e),r=1e-4*Math.round(1e4*r),this.sValue=e,this.eValue=r}else e=this.sValue,r=this.eValue;var n,o,h,l,p,f,m=this.shapes.length,c=0;if(r===e)for(n=0;n=0;n-=1)if((d=this.shapes[n]).shape._mdf){for((u=d.localShapeCollection).releaseShapes(),2===this.m&&m>1?(g=this.calculateShapeEdges(e,r,d.totalShapeLength,P,c),P+=d.totalShapeLength):g=[[v,b]],h=g.length,o=0;o=1?y.push({s:d.totalShapeLength*(v-1),e:d.totalShapeLength*(b-1)}):(y.push({s:d.totalShapeLength*v,e:d.totalShapeLength}),y.push({s:0,e:d.totalShapeLength*(b-1)}));var _=this.addShapes(d,y[0]);if(y[0].s!==y[0].e){if(y.length>1)if(d.shape.paths.shapes[d.shape.paths._length-1].c){var x=_.pop();this.addPaths(_,u),_=this.addShapes(d,y[1],x)}else this.addPaths(_,u),_=this.addShapes(d,y[1]);this.addPaths(_,u)}}d.shape.paths=u}}},TrimModifier.prototype.addPaths=function(t,e){var r,i=t.length;for(r=0;re.e){r.c=!1;break}e.s<=d&&e.e>=d+n.addedLength?(this.addSegment(m[i].v[s-1],m[i].o[s-1],m[i].i[s],m[i].v[s],r,o,y),y=!1):(l=bez.getNewSegment(m[i].v[s-1],m[i].v[s],m[i].o[s-1],m[i].i[s],(e.s-d)/n.addedLength,(e.e-d)/n.addedLength,h[s-1]),this.addSegmentFromArray(l,r,o,y),y=!1,r.c=!1),d+=n.addedLength,o+=1}if(m[i].c&&h.length){if(n=h[s-1],d<=e.e){var g=h[s-1].addedLength;e.s<=d&&e.e>=d+g?(this.addSegment(m[i].v[s-1],m[i].o[s-1],m[i].i[0],m[i].v[0],r,o,y),y=!1):(l=bez.getNewSegment(m[i].v[s-1],m[i].v[0],m[i].o[s-1],m[i].i[0],(e.s-d)/g,(e.e-d)/g,h[s-1]),this.addSegmentFromArray(l,r,o,y),y=!1,r.c=!1)}else r.c=!1;d+=n.addedLength,o+=1}if(r._length&&(r.setXYAt(r.v[p][0],r.v[p][1],"i",p),r.setXYAt(r.v[r._length-1][0],r.v[r._length-1][1],"o",r._length-1)),d>e.e)break;i0;)r-=1,this._elements.unshift(e[r]),1;this.dynamicProperties.length?this.k=!0:this.getValue(!0)},RepeaterModifier.prototype.resetElements=function(t){var e,r=t.length;for(e=0;e0?Math.floor(l):Math.ceil(l),m=(this.tr.v.props,this.pMatrix.props),c=this.rMatrix.props,d=this.sMatrix.props;this.pMatrix.reset(),this.rMatrix.reset(),this.sMatrix.reset(),this.tMatrix.reset(),this.matrix.reset();var u,y,g=0;if(l>0){for(;gf;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!0),g-=1;p&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,-p,!0),g-=p)}for(i=1===this.data.m?0:this._currentCopies-1,s=1===this.data.m?1:-1,a=this._currentCopies;a;){if(y=(r=(e=this.elemsData[i].it)[e.length-1].transform.mProps.v.props).length,e[e.length-1].transform.mProps._mdf=!0,e[e.length-1].transform.op._mdf=!0,e[e.length-1].transform.op.v=this.so.v+(this.eo.v-this.so.v)*(i/(this._currentCopies-1)),0!==g){for((0!==i&&1===s||i!==this._currentCopies-1&&-1===s)&&this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),this.matrix.transform(c[0],c[1],c[2],c[3],c[4],c[5],c[6],c[7],c[8],c[9],c[10],c[11],c[12],c[13],c[14],c[15]),this.matrix.transform(d[0],d[1],d[2],d[3],d[4],d[5],d[6],d[7],d[8],d[9],d[10],d[11],d[12],d[13],d[14],d[15]),this.matrix.transform(m[0],m[1],m[2],m[3],m[4],m[5],m[6],m[7],m[8],m[9],m[10],m[11],m[12],m[13],m[14],m[15]),u=0;u.01)return!1;r+=1}return!0},GradientProperty.prototype.checkCollapsable=function(){if(this.o.length/2!=this.c.length/4)return!1;if(this.data.k.k[0].s)for(var t=0,e=this.data.k.k.length;t=o+ot||!d?(v=(o+ot-l)/h.partialLength,z=c.point[0]+(h.point[0]-c.point[0])*v,B=c.point[1]+(h.point[1]-c.point[1])*v,T.translate(-_[0]*A[s].an/200,-_[1]*V/100),p=!1):d&&(l+=h.partialLength,(f+=1)>=d.length&&(f=0,u[m+=1]?d=u[m].points:P.v.c?(f=0,d=u[m=0].points):(l-=h.partialLength,d=null)),d&&(c=h,y=(h=d[f]).partialLength));O=A[s].an/2-A[s].add,T.translate(-O,0,0)}else O=A[s].an/2-A[s].add,T.translate(-O,0,0),T.translate(-_[0]*A[s].an/200,-_[1]*V/100,0);for(A[s].l/2,I=0;I1,this.kf&&this.addEffect(this.getKeyframeValue.bind(this)),this.kf},TextProperty.prototype.addEffect=function(t){this.effectsSequence.push(t),this.elem.addDynamicProperty(this)},TextProperty.prototype.getValue=function(t){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length||t){this.currentData.t=this.data.d.k[this.keysIndex].s.t;var e=this.currentData,r=this.keysIndex;if(this.lock)this.setCurrentData(this.currentData);else{this.lock=!0,this._mdf=!1;var i,s=this.effectsSequence.length,a=t||this.data.d.k[this.keysIndex].s;for(i=0;ie));)r+=1;return this.keysIndex!==r&&(this.keysIndex=r),this.data.d.k[this.keysIndex].s},TextProperty.prototype.buildFinalText=function(t){for(var e,r=FontManager.getCombinedCharacterCodes(),i=[],s=0,a=t.length;s=55296&&e<=56319&&(e=t.charCodeAt(s+1))>=56320&&e<=57343?(i.push(t.substr(s,2)),++s):i.push(t.charAt(s)),s+=1;return i},TextProperty.prototype.completeTextData=function(t){t.__complete=!0;var e,r,i,s,a,n,o,h=this.elem.globalData.fontManager,l=this.data,p=[],f=0,m=l.m.g,c=0,d=0,u=0,y=[],g=0,v=0,b=h.getFontByName(t.f),P=0,_=b.fStyle?b.fStyle.split(" "):[],x="normal",S="normal";for(r=_.length,e=0;eD&&" "!==A[e]?(-1===I?r+=1:e=I,C+=t.finalLineHeight||1.2*t.finalSize,A.splice(e,I===e?1:0,"\r"),I=-1,g=0):(g+=P,g+=E);C+=b.ascent*t.finalSize/100,this.canResize&&t.finalSize>this.minimumFontSize&&Mv?g:v,g=-2*E,s="",i=!0,u+=1):s=t.finalText[e],h.chars?(o=h.getCharData(w,b.fStyle,h.getFontByName(t.f).fFamily),P=i?0:o.w*t.finalSize/100):P=h.measureText(s,t.f,t.finalSize)," "===w?F+=P+E:(g+=P+E+F,F=0),p.push({l:P,an:P,add:c,n:i,anIndexes:[],val:s,line:u,animatorJustifyOffset:0}),2==m){if(c+=P,""===s||" "===s||e===r-1){for(""!==s&&" "!==s||(c-=P);d<=e;)p[d].an=c,p[d].ind=f,p[d].extra=P,d+=1;f+=1,c=0}}else if(3==m){if(c+=P,""===s||e===r-1){for(""===s&&(c-=P);d<=e;)p[d].an=c,p[d].ind=f,p[d].extra=P,d+=1;c=0,f+=1}}else p[f].ind=f,p[f].extra=0,f+=1;if(t.l=p,v=g>v?g:v,y.push(g),t.sz)t.boxWidth=t.sz[0],t.justifyOffset=0;else switch(t.boxWidth=v,t.j){case 1:t.justifyOffset=-t.boxWidth;break;case 2:t.justifyOffset=-t.boxWidth/2;break;default:t.justifyOffset=0}t.lineWidths=y;var V,R,L=l.a;n=L.length;var O,z,B=[];for(a=0;a=o?1:0:t(0,e(.5/(o-n)+(i-n)/(o-n),1)));else if(3==h)a=s(a=o===n?i>=o?0:1:1-t(0,e(.5/(o-n)+(i-n)/(o-n),1)));else if(4==h)o===n?a=0:(a=t(0,e(.5/(o-n)+(i-n)/(o-n),1)))<.5?a*=2:a=1-2*(a-.5),a=s(a);else if(5==h){if(o===n)a=0;else{var l=o-n,p=-l/2+(i=e(t(0,i+.5-n),o-n)),f=l/2;a=Math.sqrt(1-p*p/(f*f))}a=s(a)}else 6==h?(o===n?a=0:(i=e(t(0,i+.5-n),o-n),a=(1+Math.cos(Math.PI+2*Math.PI*i/(o-n)))/2),a=s(a)):(i>=r(n)&&(a=i-n<0?1-(n-i):t(0,e(o-i,1))),a=s(a));return a*this.a.v},getValue:function(t){this.iterateDynamicProperties(),this._mdf=t||this._mdf,this._currentTextLength=this.elem.textProperty.currentData.l.length||0,t&&2===this.data.r&&(this.e.v=this._currentTextLength);var e=2===this.data.r?1:100/this.data.totalChars,r=this.o.v/e,i=this.s.v/e+r,s=this.e.v/e+r;if(i>s){var a=i;i=s,s=a}this.finalS=i,this.finalE=s}},extendPrototype([DynamicPropertyContainer],i),{getTextSelectorProp:function(t,e,r){return new i(t,e,r)}}}(),pool_factory=function(t,e,r,i){var s=0,a=t,n=createSizedArray(a);function o(){return s?n[s-=1]:e()}return{newElement:o,release:function(t){s===a&&(n=pooling.double(n),a*=2),r&&r(t),n[s]=t,s+=1}}},pooling={double:function(t){return t.concat(createSizedArray(t.length))}},point_pool=pool_factory(8,function(){return createTypedArray("float32",2)}),shape_pool=(factory=pool_factory(4,function(){return new ShapePath},function(t){var e,r=t._length;for(e=0;e0&&(this.maskElement.setAttribute("id",y),this.element.maskedElement.setAttribute(v,"url("+locationHref+"#"+y+")"),s.appendChild(this.maskElement)),this.viewData.length&&this.element.addRenderableComponent(this)}function HierarchyElement(){}function FrameElement(){}function TransformElement(){}function RenderableElement(){}function RenderableDOMElement(){}function ProcessedElement(t,e){this.elem=t,this.pos=e}function SVGShapeData(t,e,r){this.caches=[],this.styles=[],this.transformers=t,this.lStr="",this.sh=r,this.lvl=e,this._isAnimated=!!r.k;for(var i=0,s=t.length;i=0;e--)this.elements[e]||(r=this.layers[e]).ip-r.st<=t-this.layers[e].st&&r.op-r.st>t-this.layers[e].st&&this.buildItem(e),this.completeLayers=!!this.elements[e]&&this.completeLayers;this.checkPendingElements()},BaseRenderer.prototype.createItem=function(t){switch(t.ty){case 2:return this.createImage(t);case 0:return this.createComp(t);case 1:return this.createSolid(t);case 3:return this.createNull(t);case 4:return this.createShape(t);case 5:return this.createText(t);case 13:return this.createCamera(t)}return this.createNull(t)},BaseRenderer.prototype.createCamera=function(){throw new Error("You're using a 3d camera. Try the html renderer.")},BaseRenderer.prototype.buildAllItems=function(){var t,e=this.layers.length;for(t=0;t=0;e--)(this.completeLayers||this.elements[e])&&this.elements[e].prepareFrame(t-this.layers[e].st);if(this.globalData._mdf)for(e=0;er&&"meet"===a||ir&&"slice"===a)?(t-this.transformCanvas.w*(e/this.transformCanvas.h))/2*this.renderConfig.dpr:"xMax"===o&&(ir&&"slice"===a)?(t-this.transformCanvas.w*(e/this.transformCanvas.h))*this.renderConfig.dpr:0,this.transformCanvas.ty="YMid"===h&&(i>r&&"meet"===a||ir&&"meet"===a||i=0;t-=1)this.elements[t]&&this.elements[t].destroy();this.elements.length=0,this.globalData.canvasContext=null,this.animationItem.container=null,this.destroyed=!0},CanvasRenderer.prototype.renderFrame=function(t,e){if((this.renderedFrame!==t||!0!==this.renderConfig.clearCanvas||e)&&!this.destroyed&&-1!==t){this.renderedFrame=t,this.globalData.frameNum=t-this.animationItem._isFirstFrame,this.globalData.frameId+=1,this.globalData._mdf=!this.renderConfig.clearCanvas||e,this.globalData.projectInterface.currentFrame=t;var r,i=this.layers.length;for(this.completeLayers||this.checkLayers(t),r=0;r=0;r-=1)(this.completeLayers||this.elements[r])&&this.elements[r].renderFrame();!0!==this.renderConfig.clearCanvas&&this.restore()}}},CanvasRenderer.prototype.buildItem=function(t){var e=this.elements;if(!e[t]&&99!=this.layers[t].ty){var r=this.createItem(this.layers[t],this,this.globalData);e[t]=r,r.initExpressions()}},CanvasRenderer.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){this.pendingElements.pop().checkParenting()}},CanvasRenderer.prototype.hide=function(){this.animationItem.container.style.display="none"},CanvasRenderer.prototype.show=function(){this.animationItem.container.style.display="block"},MaskElement.prototype.getMaskProperty=function(t){return this.viewData[t].prop},MaskElement.prototype.renderFrame=function(t){var e,r=this.element.finalTransform.mat,i=this.masksProperties.length;for(e=0;e1&&(a+=" C"+e.o[i-1][0]+","+e.o[i-1][1]+" "+e.i[0][0]+","+e.i[0][1]+" "+e.v[0][0]+","+e.v[0][1]),r.lastPath!==a){var n="";r.elem&&(e.c&&(n=t.inv?this.solidPath+a:a),r.elem.setAttribute("d",n)),r.lastPath=a}},MaskElement.prototype.destroy=function(){this.element=null,this.globalData=null,this.maskElement=null,this.data=null,this.masksProperties=null},HierarchyElement.prototype={initHierarchy:function(){this.hierarchy=[],this._isParent=!1,this.checkParenting()},setHierarchy:function(t){this.hierarchy=t},setAsParent:function(){this._isParent=!0},checkParenting:function(){void 0!==this.data.parent&&this.comp.buildElementParenting(this,this.data.parent,[])}},FrameElement.prototype={initFrame:function(){this._isFirstFrame=!1,this.dynamicProperties=[],this._mdf=!1},prepareProperties:function(t,e){var r,i=this.dynamicProperties.length;for(r=0;rt?!0!==this.isInRange&&(this.globalData._mdf=!0,this._mdf=!0,this.isInRange=!0,this.show()):!1!==this.isInRange&&(this.globalData._mdf=!0,this.isInRange=!1,this.hide())},renderRenderable:function(){var t,e=this.renderableComponents.length;for(t=0;t=0;i-=1)r=t.transforms[i].transform.mProps.v.props,t.finalTransform.transform(r[0],r[1],r[2],r[3],r[4],r[5],r[6],r[7],r[8],r[9],r[10],r[11],r[12],r[13],r[14],r[15]);t._mdf=a},processSequences:function(t){var e,r=this.sequenceList.length;for(e=0;e=0;t-=1)this.shapeModifiers[t].processShapes(this._isFirstFrame)}},lcEnum:{1:"butt",2:"round",3:"square"},ljEnum:{1:"miter",2:"round",3:"bevel"},searchProcessedElement:function(t){for(var e=this.processedElements,r=0,i=e.length;r=0;r-=1)(this.completeLayers||this.elements[r])&&(this.elements[r].prepareFrame(this.renderedFrame-this.layers[r].st),this.elements[r]._mdf&&(this._mdf=!0))}},ICompElement.prototype.renderInnerContent=function(){var t,e=this.layers.length;for(t=0;t1&&o&&this.setShapesAsAnimated(n)}},SVGShapeElement.prototype.setShapesAsAnimated=function(t){var e,r=t.length;for(e=0;e=0;o-=1){if((m=this.searchProcessedElement(t[o]))?e[o]=r[m-1]:t[o]._render=n,"fl"==t[o].ty||"st"==t[o].ty||"gf"==t[o].ty||"gs"==t[o].ty)m?e[o].style.closed=!1:e[o]=this.createStyleElement(t[o],s),t[o]._render&&i.appendChild(e[o].style.pElem),u.push(e[o].style);else if("gr"==t[o].ty){if(m)for(l=e[o].it.length,h=0;ho&&"xMidYMid slice"===h||n=0;t-=1)(this.completeLayers||this.elements[t])&&this.elements[t].renderFrame()},CVCompElement.prototype.destroy=function(){var t;for(t=this.layers.length-1;t>=0;t-=1)this.elements[t]&&this.elements[t].destroy();this.layers=null,this.elements=null},CVMaskElement.prototype.renderFrame=function(){if(this.hasMasks){var t,e,r,i,s=this.element.finalTransform.mat,a=this.element.canvasContext,n=this.masksProperties.length;for(a.beginPath(),t=0;t=0;a-=1){if((h=this.searchProcessedElement(t[a]))?e[a]=r[h-1]:t[a]._shouldRender=i,"fl"==t[a].ty||"st"==t[a].ty||"gf"==t[a].ty||"gs"==t[a].ty)h?e[a].style.closed=!1:e[a]=this.createStyleElement(t[a],d),m.push(e[a].style);else if("gr"==t[a].ty){if(h)for(o=e[a].it.length,n=0;n=0;s-=1)"tr"==e[s].ty?(a=r[s].transform,this.renderShapeTransform(t,a)):"sh"==e[s].ty||"el"==e[s].ty||"rc"==e[s].ty||"sr"==e[s].ty?this.renderPath(e[s],r[s]):"fl"==e[s].ty?this.renderFill(e[s],r[s],a):"st"==e[s].ty?this.renderStroke(e[s],r[s],a):"gf"==e[s].ty||"gs"==e[s].ty?this.renderGradientFill(e[s],r[s],a):"gr"==e[s].ty?this.renderShape(a,e[s].it,r[s].it):e[s].ty;i&&this.drawLayer()},CVShapeElement.prototype.renderStyledShape=function(t,e){if(this._isFirstFrame||e._mdf||t.transforms._mdf){var r,i,s,a=t.trNodes,n=e.paths,o=n._length;a.length=0;var h=t.transforms.finalTransform;for(s=0;s=1?.99:e.h.v<=-1?-.99:e.h.v),p=Math.cos(h+e.a.v)*l+a[0],f=Math.sin(h+e.a.v)*l+a[1],m=s.createRadialGradient(p,f,0,a[0],a[1],o);var c,d=t.g.p,u=e.g.c,y=1;for(c=0;c=0;r-=1)e[r].animation.destroy(t)},t.freeze=function(){n=!0},t.unfreeze=function(){n=!1,d()},t.getRegisteredAnimations=function(){var t,r=e.length,i=[];for(t=0;tthis.animationData.op&&(this.animationData.op=t.op,this.totalFrames=Math.floor(t.op-this.animationData.ip));var e,r,i=this.animationData.layers,s=i.length,a=t.layers,n=a.length;for(r=0;rthis.timeCompleted&&(this.currentFrame=this.timeCompleted),this.trigger("enterFrame"),this.renderFrame()},AnimationItem.prototype.renderFrame=function(){!1!==this.isLoaded&&this.renderer.renderFrame(this.currentFrame+this.firstFrame)},AnimationItem.prototype.play=function(t){t&&this.name!=t||!0===this.isPaused&&(this.isPaused=!1,this._idle&&(this._idle=!1,this.trigger("_active")))},AnimationItem.prototype.pause=function(t){t&&this.name!=t||!1===this.isPaused&&(this.isPaused=!0,this._idle=!0,this.trigger("_idle"))},AnimationItem.prototype.togglePause=function(t){t&&this.name!=t||(!0===this.isPaused?this.play():this.pause())},AnimationItem.prototype.stop=function(t){t&&this.name!=t||(this.pause(),this.playCount=0,this._completedLoop=!1,this.setCurrentRawFrameValue(0))},AnimationItem.prototype.goToAndStop=function(t,e,r){r&&this.name!=r||(e?this.setCurrentRawFrameValue(t):this.setCurrentRawFrameValue(t*this.frameModifier),this.pause())},AnimationItem.prototype.goToAndPlay=function(t,e,r){this.goToAndStop(t,e,r),this.play()},AnimationItem.prototype.advanceTime=function(t){if(!0!==this.isPaused&&!1!==this.isLoaded){var e=this.currentRawFrame+t*this.frameModifier,r=!1;e>=this.totalFrames-1&&this.frameModifier>0?this.loop&&this.playCount!==this.loop?e>=this.totalFrames?(this.playCount+=1,this.checkSegments(e%this.totalFrames)||(this.setCurrentRawFrameValue(e%this.totalFrames),this._completedLoop=!0,this.trigger("loopComplete"))):this.setCurrentRawFrameValue(e):this.checkSegments(e>this.totalFrames?e%this.totalFrames:0)||(r=!0,e=this.totalFrames-1):e<0?this.checkSegments(e%this.totalFrames)||(!this.loop||this.playCount--<=0&&!0!==this.loop?(r=!0,e=0):(this.setCurrentRawFrameValue(this.totalFrames+e%this.totalFrames),this._completedLoop?this.trigger("loopComplete"):this._completedLoop=!0)):this.setCurrentRawFrameValue(e),r&&(this.setCurrentRawFrameValue(e),this.pause(),this.trigger("complete"))}},AnimationItem.prototype.adjustSegment=function(t,e){this.playCount=0,t[1]0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(-1)),this.timeCompleted=this.totalFrames=t[0]-t[1],this.firstFrame=t[1],this.setCurrentRawFrameValue(this.totalFrames-.001-e)):t[1]>t[0]&&(this.frameModifier<0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(1)),this.timeCompleted=this.totalFrames=t[1]-t[0],this.firstFrame=t[0],this.setCurrentRawFrameValue(.001+e)),this.trigger("segmentStart")},AnimationItem.prototype.setSegment=function(t,e){var r=-1;this.isPaused&&(this.currentRawFrame+this.firstFramee&&(r=e-t)),this.firstFrame=t,this.timeCompleted=this.totalFrames=e-t,-1!==r&&this.goToAndStop(r,!0)},AnimationItem.prototype.playSegments=function(t,e){if(e&&(this.segments.length=0),"object"===_typeof(t[0])){var r,i=t.length;for(r=0;rr){var i=r;r=e,e=i}return Math.min(Math.max(t,e),r)}function radiansToDegrees(t){return t/degToRads}var radians_to_degrees=radiansToDegrees;function degreesToRadians(t){return t*degToRads}var degrees_to_radians=radiansToDegrees,helperLengthArray=[0,0,0,0,0,0];function length(t,e){if("number"==typeof t||t instanceof Number)return e=e||0,Math.abs(t-e);e||(e=helperLengthArray);var r,i=Math.min(t.length,e.length),s=0;for(r=0;r.5?l/(2-n-o):l/(n+o),n){case i:e=(s-a)/l+(s1&&(r-=1),r<1/6?t+6*(e-t)*r:r<.5?e:r<2/3?t+(e-t)*(2/3-r)*6:t}function hslToRgb(t){var e,r,i,s=t[0],a=t[1],n=t[2];if(0===a)e=r=i=n;else{var o=n<.5?n*(1+a):n+a-n*a,h=2*n-o;e=hue2rgb(h,o,s+1/3),r=hue2rgb(h,o,s),i=hue2rgb(h,o,s-1/3)}return[e,r,i,t[3]]}function linear(t,e,r,i,s){if(void 0!==i&&void 0!==s||(i=e,s=r,e=0,r=1),r=r)return s;var n=r===e?0:(t-e)/(r-e);if(!i.length)return i+(s-i)*n;var o,h=i.length,l=createTypedArray("float32",h);for(o=0;o1){for(i=0;i1?1:e<0?0:e);if($bm_isInstanceOfArray(s)){var o,h=s.length,l=createTypedArray("float32",h);for(o=0;odata.k[e].t&&tdata.k[e+1].t-t?(r=e+2,i=data.k[e+1].t):(r=e+1,i=data.k[e].t);break}}-1===r&&(r=e+1,i=data.k[e].t)}else r=0,i=0;var a={};return a.index=r,a.time=i/elem.comp.globalData.frameRate,a}function key(t){var e,r,i;if(!data.k.length||"number"==typeof data.k[0])throw new Error("The property has no keyframe at index "+t);t-=1,e={time:data.k[t].t/elem.comp.globalData.frameRate,value:[]};var s=data.k[t].hasOwnProperty("s")?data.k[t].s:data.k[t-1].e;for(i=s.length,r=0;rl.length-1)&&(e=l.length-1),i=p-(s=l[l.length-1-e].t)),"pingpong"===t){if(Math.floor((h-s)/i)%2!=0)return this.getValueAtTime((i-(h-s)%i+s)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var f=this.getValueAtTime(s/this.comp.globalData.frameRate,0),m=this.getValueAtTime(p/this.comp.globalData.frameRate,0),c=this.getValueAtTime(((h-s)%i+s)/this.comp.globalData.frameRate,0),d=Math.floor((h-s)/i);if(this.pv.length){for(n=(o=new Array(f.length)).length,a=0;a=p)return this.pv;if(r?s=p+(i=e?Math.abs(elem.comp.globalData.frameRate*e):Math.max(0,this.elem.data.op-p)):((!e||e>l.length-1)&&(e=l.length-1),i=(s=l[e].t)-p),"pingpong"===t){if(Math.floor((p-h)/i)%2==0)return this.getValueAtTime(((p-h)%i+p)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var f=this.getValueAtTime(p/this.comp.globalData.frameRate,0),m=this.getValueAtTime(s/this.comp.globalData.frameRate,0),c=this.getValueAtTime((i-(p-h)%i+p)/this.comp.globalData.frameRate,0),d=Math.floor((p-h)/i)+1;if(this.pv.length){for(n=(o=new Array(f.length)).length,a=0;a1?(s+t-a)/(e-1):1,o=0,h=0;for(r=this.pv.length?createTypedArray("float32",this.pv.length):0;on){var p=o,f=r.c&&o===h-1?0:o+1,m=(n-l)/a[o].addedLength;i=bez.getPointInSegment(r.v[p],r.v[f],r.o[p],r.i[f],m,a[o]);break}l+=a[o].addedLength,o+=1}return i||(i=r.c?[r.v[0][0],r.v[0][1]]:[r.v[r._length-1][0],r.v[r._length-1][1]]),i},vectorOnPath:function(t,e,r){t=1==t?this.v.c?0:.999:t;var i=this.pointOnPath(t,e),s=this.pointOnPath(t+.001,e),a=s[0]-i[0],n=s[1]-i[1],o=Math.sqrt(Math.pow(a,2)+Math.pow(n,2));return 0===o?[0,0]:"tangent"===r?[a/o,n/o]:[-n/o,a/o]},tangentOnPath:function(t,e){return this.vectorOnPath(t,e,"tangent")},normalOnPath:function(t,e){return this.vectorOnPath(t,e,"normal")},setGroupProperty:expressionHelpers.setGroupProperty,getValueAtTime:expressionHelpers.getStaticValueAtTime},extendPrototype([o],a),extendPrototype([o],n),n.prototype.getValueAtTime=function(t){return this._cachingAtTime||(this._cachingAtTime={shapeValue:shape_pool.clone(this.pv),lastIndex:0,lastTime:initialDefaultFrame}),t*=this.elem.globalData.frameRate,(t-=this.offsetTime)!==this._cachingAtTime.lastTime&&(this._cachingAtTime.lastIndex=this._cachingAtTime.lastTime1&&(defaultCurveSegments=t);roundValues(!(defaultCurveSegments>=50))}function inBrowser(){return void 0!==navigator}function installPlugin(t,e){"expressions"===t&&(expressionsPlugin=e)}function getFactory(t){switch(t){case"propertyFactory":return PropertyFactory;case"shapePropertyFactory":return ShapePropertyFactory;case"matrix":return Matrix}}function checkReady(){"complete"===document.readyState&&(clearInterval(readyStateCheckInterval),searchAnimations())}function getQueryVariable(t){for(var e=queryString.split("&"),r=0;r1?r[1]=1:r[1]<=0&&(r[1]=0),HSVtoRGB(r[0],r[1],r[2])}function addBrightnessToRGB(t,e){var r=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return r[2]+=e,r[2]>1?r[2]=1:r[2]<0&&(r[2]=0),HSVtoRGB(r[0],r[1],r[2])}function addHueToRGB(t,e){var r=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return r[0]+=e/360,r[0]>1?r[0]-=1:r[0]<0&&(r[0]+=1),HSVtoRGB(r[0],r[1],r[2])}var rgbToHex=function(){var t,e,r=[];for(t=0;t<256;t+=1)e=t.toString(16),r[t]=1===e.length?"0"+e:e;return function(t,e,i){return t<0&&(t=0),e<0&&(e=0),i<0&&(i=0),"#"+r[t]+r[e]+r[i]}}(),setSubframeEnabled=function(t){subframeEnabled=!!t},getSubframeEnabled=function(){return subframeEnabled},setExpressionsPlugin=function(t){expressionsPlugin=t},getExpressionsPlugin=function(){return expressionsPlugin},setDefaultCurveSegments=function(t){defaultCurveSegments=t},getDefaultCurveSegments=function(){return defaultCurveSegments},setIdPrefix=function(t){idPrefix=t},getIdPrefix=function(){return idPrefix};function createNS(t){return document.createElementNS(svgNS,t)}function _typeof$5(t){return _typeof$5="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$5(t)}var dataManager=function(){var t,e,r=1,i=[],s={onmessage:function(){},postMessage:function(e){t({data:e})}},a={postMessage:function(t){s.onmessage({data:t})}};function n(){e||(e=function(e){if(window.Worker&&window.Blob&&getWebWorker()){var r=new Blob(["var _workerSelf = self; self.onmessage = ",e.toString()],{type:"text/javascript"}),i=URL.createObjectURL(r);return new Worker(i)}return t=e,s}((function(t){if(a.dataManager||(a.dataManager=function(){function t(s,a){var n,o,h,l,p,m,c=s.length;for(o=0;o=0;e-=1)if("sh"===t[e].ty)if(t[e].ks.k.i)i(t[e].ks.k);else for(a=t[e].ks.k.length,s=0;sr[0]||!(r[0]>t[0])&&(t[1]>r[1]||!(r[1]>t[1])&&(t[2]>r[2]||!(r[2]>t[2])&&null))}var a,n=function(){var t=[4,4,14];function e(t){var e,r,i,s=t.length;for(e=0;e=0;r-=1)if("sh"===t[r].ty)if(t[r].ks.k.i)t[r].ks.k.c=t[r].closed;else for(s=t[r].ks.k.length,i=0;i500)&&(this._imageLoaded(),clearInterval(r)),e+=1}.bind(this),50)}function a(t){var e={assetData:t},r=i(t,this.assetsPath,this.path);return dataManager.loadData(r,function(t){e.img=t,this._footageLoaded()}.bind(this),function(){e.img={},this._footageLoaded()}.bind(this)),e}function n(){this._imageLoaded=e.bind(this),this._footageLoaded=r.bind(this),this.testImageLoaded=s.bind(this),this.createFootageData=a.bind(this),this.assetsPath="",this.path="",this.totalImages=0,this.totalFootages=0,this.loadedAssets=0,this.loadedFootagesCount=0,this.imagesLoadedCb=null,this.images=[]}return n.prototype={loadAssets:function(t,e){var r;this.imagesLoadedCb=e;var i=t.length;for(r=0;rthis.animationData.op&&(this.animationData.op=t.op,this.totalFrames=Math.floor(t.op-this.animationData.ip));var e,r,i=this.animationData.layers,s=i.length,a=t.layers,n=a.length;for(r=0;rthis.timeCompleted&&(this.currentFrame=this.timeCompleted),this.trigger("enterFrame"),this.renderFrame(),this.trigger("drawnFrame")},AnimationItem.prototype.renderFrame=function(){if(!1!==this.isLoaded&&this.renderer)try{this.renderer.renderFrame(this.currentFrame+this.firstFrame)}catch(t){this.triggerRenderFrameError(t)}},AnimationItem.prototype.play=function(t){t&&this.name!==t||!0===this.isPaused&&(this.isPaused=!1,this.audioController.resume(),this._idle&&(this._idle=!1,this.trigger("_active")))},AnimationItem.prototype.pause=function(t){t&&this.name!==t||!1===this.isPaused&&(this.isPaused=!0,this._idle=!0,this.trigger("_idle"),this.audioController.pause())},AnimationItem.prototype.togglePause=function(t){t&&this.name!==t||(!0===this.isPaused?this.play():this.pause())},AnimationItem.prototype.stop=function(t){t&&this.name!==t||(this.pause(),this.playCount=0,this._completedLoop=!1,this.setCurrentRawFrameValue(0))},AnimationItem.prototype.getMarkerData=function(t){for(var e,r=0;r=this.totalFrames-1&&this.frameModifier>0?this.loop&&this.playCount!==this.loop?e>=this.totalFrames?(this.playCount+=1,this.checkSegments(e%this.totalFrames)||(this.setCurrentRawFrameValue(e%this.totalFrames),this._completedLoop=!0,this.trigger("loopComplete"))):this.setCurrentRawFrameValue(e):this.checkSegments(e>this.totalFrames?e%this.totalFrames:0)||(r=!0,e=this.totalFrames-1):e<0?this.checkSegments(e%this.totalFrames)||(!this.loop||this.playCount--<=0&&!0!==this.loop?(r=!0,e=0):(this.setCurrentRawFrameValue(this.totalFrames+e%this.totalFrames),this._completedLoop?this.trigger("loopComplete"):this._completedLoop=!0)):this.setCurrentRawFrameValue(e),r&&(this.setCurrentRawFrameValue(e),this.pause(),this.trigger("complete"))}},AnimationItem.prototype.adjustSegment=function(t,e){this.playCount=0,t[1]0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(-1)),this.totalFrames=t[0]-t[1],this.timeCompleted=this.totalFrames,this.firstFrame=t[1],this.setCurrentRawFrameValue(this.totalFrames-.001-e)):t[1]>t[0]&&(this.frameModifier<0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(1)),this.totalFrames=t[1]-t[0],this.timeCompleted=this.totalFrames,this.firstFrame=t[0],this.setCurrentRawFrameValue(.001+e)),this.trigger("segmentStart")},AnimationItem.prototype.setSegment=function(t,e){var r=-1;this.isPaused&&(this.currentRawFrame+this.firstFramee&&(r=e-t)),this.firstFrame=t,this.totalFrames=e-t,this.timeCompleted=this.totalFrames,-1!==r&&this.goToAndStop(r,!0)},AnimationItem.prototype.playSegments=function(t,e){if(e&&(this.segments.length=0),"object"===_typeof$4(t[0])){var r,i=t.length;for(r=0;r=0;r-=1)e[r].animation.destroy(t)},t.freeze=function(){n=!0},t.unfreeze=function(){n=!1,d()},t.setVolume=function(t,r){var s;for(s=0;s=.001?function(t,e,r,i){for(var s=0;s<4;++s){var a=h(e,r,i);if(0===a)return e;e-=(o(e,r,i)-t)/a}return e}(t,l,e,i):0===p?l:function(t,e,r,i,s){var a,n,h=0;do{(a=o(n=e+(r-e)/2,i,s)-t)>0?r=n:e=n}while(Math.abs(a)>1e-7&&++h<10);return n}(t,a,a+r,e,i)}},t}(),pooling={double:function(t){return t.concat(createSizedArray(t.length))}},poolFactory=function(t,e,r){var i=0,s=t,a=createSizedArray(s);return{newElement:function(){return i?a[i-=1]:e()},release:function(t){i===s&&(a=pooling.double(a),s*=2),r&&r(t),a[i]=t,i+=1}}},bezierLengthPool=poolFactory(8,(function(){return{addedLength:0,percents:createTypedArray("float32",getDefaultCurveSegments()),lengths:createTypedArray("float32",getDefaultCurveSegments())}})),segmentsLengthPool=poolFactory(8,(function(){return{lengths:[],totalLength:0}}),(function(t){var e,r=t.lengths.length;for(e=0;e-.001&&n<.001}var r=function(t,e,r,i){var s,a,n,o,h,l,p=getDefaultCurveSegments(),f=0,m=[],c=[],d=bezierLengthPool.newElement();for(n=r.length,s=0;sn?-1:1,l=!0;l;)if(i[a]<=n&&i[a+1]>n?(o=(n-i[a])/(i[a+1]-i[a]),l=!1):a+=h,a<0||a>=s-1){if(a===s-1)return r[a];l=!1}return r[a]+(r[a+1]-r[a])*o}var h=createTypedArray("float32",8);return{getSegmentsLength:function(t){var e,i=segmentsLengthPool.newElement(),s=t.c,a=t.v,n=t.o,o=t.i,h=t._length,l=i.lengths,p=0;for(e=0;e1&&(a=1);var p,f=o(a,l),m=o(n=n>1?1:n,l),c=e.length,d=1-f,u=1-m,y=d*d*d,g=f*d*d*3,v=f*f*d*3,b=f*f*f,P=d*d*u,E=f*d*u+d*f*u+d*d*m,x=f*f*u+d*f*m+f*d*m,S=f*f*m,C=d*u*u,A=f*u*u+d*m*u+d*u*m,_=f*m*u+d*m*m+f*u*m,T=f*m*m,k=u*u*u,D=m*u*u+u*m*u+u*u*m,M=m*m*u+u*m*m+m*u*m,F=m*m*m;for(p=0;pc?m>d?m-c-d:d-c-m:d>c?d-c-m:c-m-d)>-1e-4&&f<1e-4}}}var bez=bezFunction(),PropertyFactory=function(){var t=initialDefaultFrame,e=Math.abs;function r(t,e){var r,s=this.offsetTime;"multidimensional"===this.propType&&(r=createTypedArray("float32",this.pv.length));for(var a,n,o,h,l,p,f,m,c,d=e.lastIndex,u=d,y=this.keyframes.length-1,g=!0;g;){if(a=this.keyframes[u],n=this.keyframes[u+1],u===y-1&&t>=n.t-s){a.h&&(a=n),d=0;break}if(n.t-s>t){d=u;break}u=k||t=k?M.points.length-1:0;for(l=M.points[F].point.length,h=0;h=V&&I=k)r[0]=v[0],r[1]=v[1],r[2]=v[2];else if(t<=D)r[0]=a.s[0],r[1]=a.s[1],r[2]=a.s[2];else{var N=i(a.s),O=i(v);b=r,P=function(t,e,r){var i,s,a,n,o,h=[],l=t[0],p=t[1],f=t[2],m=t[3],c=e[0],d=e[1],u=e[2],y=e[3];return(s=l*c+p*d+f*u+m*y)<0&&(s=-s,c=-c,d=-d,u=-u,y=-y),1-s>1e-6?(i=Math.acos(s),a=Math.sin(i),n=Math.sin((1-r)*i)/a,o=Math.sin(r*i)/a):(n=1-r,o=r),h[0]=n*l+o*c,h[1]=n*p+o*d,h[2]=n*f+o*u,h[3]=n*m+o*y,h}(N,O,(t-D)/(k-D)),E=P[0],x=P[1],S=P[2],C=P[3],A=Math.atan2(2*x*C-2*E*S,1-2*x*x-2*S*S),_=Math.asin(2*E*x+2*S*C),T=Math.atan2(2*E*C-2*x*S,1-2*E*E-2*S*S),b[0]=A/degToRads,b[1]=_/degToRads,b[2]=T/degToRads}else for(u=0;u=k?p=1:t=i&&e>=i||this._caching.lastFrame=e&&(this._caching._lastKeyframeIndex=-1,this._caching.lastIndex=0);var s=this.interpolateValue(e,this._caching);this.pv=s}return this._caching.lastFrame=e,this.pv}function a(t){var r;if("unidimensional"===this.propType)r=t*this.mult,e(this.v-r)>1e-5&&(this.v=r,this._mdf=!0);else for(var i=0,s=this.v.length;i1e-5&&(this.v[i]=r,this._mdf=!0),i+=1}function n(){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{var t;this.lock=!0,this._mdf=this._isFirstFrame;var e=this.effectsSequence.length,r=this.kf?this.pv:this.data.k;for(t=0;t=this._maxLength&&this.doubleArrayLength(),r){case"v":a=this.v;break;case"i":a=this.i;break;case"o":a=this.o;break;default:a=[]}(!a[i]||a[i]&&!s)&&(a[i]=pointPool.newElement()),a[i][0]=t,a[i][1]=e},ShapePath.prototype.setTripleAt=function(t,e,r,i,s,a,n,o){this.setXYAt(t,e,"v",n,o),this.setXYAt(r,i,"o",n,o),this.setXYAt(s,a,"i",n,o)},ShapePath.prototype.reverse=function(){var t=new ShapePath;t.setPathData(this.c,this._length);var e=this.v,r=this.o,i=this.i,s=0;this.c&&(t.setTripleAt(e[0][0],e[0][1],i[0][0],i[0][1],r[0][0],r[0][1],0,!1),s=1);var a,n=this._length-1,o=this._length;for(a=s;a=c[c.length-1].t-this.offsetTime)i=c[c.length-1].s?c[c.length-1].s[0]:c[c.length-2].e[0],a=!0;else{for(var d,u,y,g=m,v=c.length-1,b=!0;b&&(d=c[g],!((u=c[g+1]).t-this.offsetTime>t));)g=u.t-this.offsetTime)p=1;else if(ti&&e>i)||(this._caching.lastIndex=s0||t>-1e-6&&t<0?i(1e4*t)/1e4:t}function w(){var t=this.props;return"matrix("+F(t[0])+","+F(t[1])+","+F(t[4])+","+F(t[5])+","+F(t[12])+","+F(t[13])+")"}return function(){this.reset=s,this.rotate=a,this.rotateX=n,this.rotateY=o,this.rotateZ=h,this.skew=p,this.skewFromAxis=f,this.shear=l,this.scale=m,this.setTransform=c,this.translate=d,this.transform=u,this.applyToPoint=P,this.applyToX=E,this.applyToY=x,this.applyToZ=S,this.applyToPointArray=k,this.applyToTriplePoints=T,this.applyToPointStringified=D,this.toCSS=M,this.to2dCSS=w,this.clone=v,this.cloneFromProps=b,this.equals=g,this.inversePoints=_,this.inversePoint=A,this.getInverseMatrix=C,this._t=this.transform,this.isIdentity=y,this._identity=!0,this._identityCalculated=!1,this.props=createTypedArray("float32",16),this.reset()}}();function _typeof$3(t){return _typeof$3="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$3(t)}var lottie={},standalone="__[STANDALONE]__",animationData="__[ANIMATIONDATA]__",renderer="",queryString;function setLocation(t){setLocationHref(t)}function searchAnimations(){!0===standalone?animationManager.searchAnimations(animationData,standalone,renderer):animationManager.searchAnimations()}function setSubframeRendering(t){setSubframeEnabled(t)}function setPrefix(t){setIdPrefix(t)}function loadAnimation(t){return!0===standalone&&(t.animationData=JSON.parse(animationData)),animationManager.loadAnimation(t)}function setQuality(t){if("string"==typeof t)switch(t){case"high":setDefaultCurveSegments(200);break;default:case"medium":setDefaultCurveSegments(50);break;case"low":setDefaultCurveSegments(10)}else!isNaN(t)&&t>1&&setDefaultCurveSegments(t);getDefaultCurveSegments()>=50?roundValues(!1):roundValues(!0)}function inBrowser(){return"undefined"!=typeof navigator}function installPlugin(t,e){"expressions"===t&&setExpressionsPlugin(e)}function getFactory(t){switch(t){case"propertyFactory":return PropertyFactory;case"shapePropertyFactory":return ShapePropertyFactory;case"matrix":return Matrix;default:return null}}function checkReady(){"complete"===document.readyState&&(clearInterval(readyStateCheckInterval),searchAnimations())}function getQueryVariable(t){for(var e=queryString.split("&"),r=0;r=1?a.push({s:t-1,e:e-1}):(a.push({s:t,e:1}),a.push({s:0,e:e-1}));var n,o,h=[],l=a.length;for(n=0;ni+r))p=o.s*s<=i?0:(o.s*s-i)/r,f=o.e*s>=i+r?1:(o.e*s-i)/r,h.push([p,f])}return h.length||h.push([0,0]),h},TrimModifier.prototype.releasePathsData=function(t){var e,r=t.length;for(e=0;e1?1+a:this.s.v<0?0+a:this.s.v+a)>(r=this.e.v>1?1+a:this.e.v<0?0+a:this.e.v+a)){var n=e;e=r,r=n}e=1e-4*Math.round(1e4*e),r=1e-4*Math.round(1e4*r),this.sValue=e,this.eValue=r}else e=this.sValue,r=this.eValue;var o,h,l,p,f,m=this.shapes.length,c=0;if(r===e)for(s=0;s=0;s-=1)if((d=this.shapes[s]).shape._mdf){for((u=d.localShapeCollection).releaseShapes(),2===this.m&&m>1?(g=this.calculateShapeEdges(e,r,d.totalShapeLength,P,c),P+=d.totalShapeLength):g=[[v,b]],h=g.length,o=0;o=1?y.push({s:d.totalShapeLength*(v-1),e:d.totalShapeLength*(b-1)}):(y.push({s:d.totalShapeLength*v,e:d.totalShapeLength}),y.push({s:0,e:d.totalShapeLength*(b-1)}));var E=this.addShapes(d,y[0]);if(y[0].s!==y[0].e){if(y.length>1)if(d.shape.paths.shapes[d.shape.paths._length-1].c){var x=E.pop();this.addPaths(E,u),E=this.addShapes(d,y[1],x)}else this.addPaths(E,u),E=this.addShapes(d,y[1]);this.addPaths(E,u)}}d.shape.paths=u}}},TrimModifier.prototype.addPaths=function(t,e){var r,i=t.length;for(r=0;re.e){r.c=!1;break}e.s<=d&&e.e>=d+n.addedLength?(this.addSegment(m[i].v[s-1],m[i].o[s-1],m[i].i[s],m[i].v[s],r,o,y),y=!1):(l=bez.getNewSegment(m[i].v[s-1],m[i].v[s],m[i].o[s-1],m[i].i[s],(e.s-d)/n.addedLength,(e.e-d)/n.addedLength,h[s-1]),this.addSegmentFromArray(l,r,o,y),y=!1,r.c=!1),d+=n.addedLength,o+=1}if(m[i].c&&h.length){if(n=h[s-1],d<=e.e){var g=h[s-1].addedLength;e.s<=d&&e.e>=d+g?(this.addSegment(m[i].v[s-1],m[i].o[s-1],m[i].i[0],m[i].v[0],r,o,y),y=!1):(l=bez.getNewSegment(m[i].v[s-1],m[i].v[0],m[i].o[s-1],m[i].i[0],(e.s-d)/g,(e.e-d)/g,h[s-1]),this.addSegmentFromArray(l,r,o,y),y=!1,r.c=!1)}else r.c=!1;d+=n.addedLength,o+=1}if(r._length&&(r.setXYAt(r.v[p][0],r.v[p][1],"i",p),r.setXYAt(r.v[r._length-1][0],r.v[r._length-1][1],"o",r._length-1)),d>e.e)break;i=this.p.keyframes[this.p.keyframes.length-1].t?(i=this.p.getValueAtTime(this.p.keyframes[this.p.keyframes.length-1].t/r,0),s=this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length-1].t-.05)/r,0)):(i=this.p.pv,s=this.p.getValueAtTime((this.p._caching.lastFrame+this.p.offsetTime-.01)/r,this.p.offsetTime));else if(this.px&&this.px.keyframes&&this.py.keyframes&&this.px.getValueAtTime&&this.py.getValueAtTime){i=[],s=[];var a=this.px,n=this.py;a._caching.lastFrame+a.offsetTime<=a.keyframes[0].t?(i[0]=a.getValueAtTime((a.keyframes[0].t+.01)/r,0),i[1]=n.getValueAtTime((n.keyframes[0].t+.01)/r,0),s[0]=a.getValueAtTime(a.keyframes[0].t/r,0),s[1]=n.getValueAtTime(n.keyframes[0].t/r,0)):a._caching.lastFrame+a.offsetTime>=a.keyframes[a.keyframes.length-1].t?(i[0]=a.getValueAtTime(a.keyframes[a.keyframes.length-1].t/r,0),i[1]=n.getValueAtTime(n.keyframes[n.keyframes.length-1].t/r,0),s[0]=a.getValueAtTime((a.keyframes[a.keyframes.length-1].t-.01)/r,0),s[1]=n.getValueAtTime((n.keyframes[n.keyframes.length-1].t-.01)/r,0)):(i=[a.pv,n.pv],s[0]=a.getValueAtTime((a._caching.lastFrame+a.offsetTime-.01)/r,a.offsetTime),s[1]=n.getValueAtTime((n._caching.lastFrame+n.offsetTime-.01)/r,n.offsetTime))}else i=s=t;this.v.rotate(-Math.atan2(i[1]-s[1],i[0]-s[0]))}this.data.p&&this.data.p.s?this.data.p.z?this.v.translate(this.px.v,this.py.v,-this.pz.v):this.v.translate(this.px.v,this.py.v,0):this.v.translate(this.p.v[0],this.p.v[1],-this.p.v[2])}this.frameId=this.elem.globalData.frameId}},precalculateMatrix:function(){if(!this.a.k&&(this.pre.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations=1,!this.s.effectsSequence.length)){if(this.pre.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.appliedTransformations=2,this.sk){if(this.sk.effectsSequence.length||this.sa.effectsSequence.length)return;this.pre.skewFromAxis(-this.sk.v,this.sa.v),this.appliedTransformations=3}this.r?this.r.effectsSequence.length||(this.pre.rotate(-this.r.v),this.appliedTransformations=4):this.rz.effectsSequence.length||this.ry.effectsSequence.length||this.rx.effectsSequence.length||this.or.effectsSequence.length||(this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.appliedTransformations=4)}},autoOrient:function(){}},extendPrototype([DynamicPropertyContainer],e),e.prototype.addDynamicProperty=function(t){this._addDynamicProperty(t),this.elem.addDynamicProperty(t),this._isDirty=!0},e.prototype._addDynamicProperty=DynamicPropertyContainer.prototype.addDynamicProperty,{getTransformProperty:function(t,r,i){return new e(t,r,i)}}}();function RepeaterModifier(){}function RoundCornersModifier(){}function getFontProperties(t){for(var e=t.fStyle?t.fStyle.split(" "):[],r="normal",i="normal",s=e.length,a=0;a0;)r-=1,this._elements.unshift(e[r]);this.dynamicProperties.length?this.k=!0:this.getValue(!0)},RepeaterModifier.prototype.resetElements=function(t){var e,r=t.length;for(e=0;e0?Math.floor(m):Math.ceil(m),u=this.pMatrix.props,y=this.rMatrix.props,g=this.sMatrix.props;this.pMatrix.reset(),this.rMatrix.reset(),this.sMatrix.reset(),this.tMatrix.reset(),this.matrix.reset();var v,b,P=0;if(m>0){for(;Pd;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!0),P-=1;c&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,-c,!0),P-=c)}for(i=1===this.data.m?0:this._currentCopies-1,s=1===this.data.m?1:-1,a=this._currentCopies;a;){if(b=(r=(e=this.elemsData[i].it)[e.length-1].transform.mProps.v.props).length,e[e.length-1].transform.mProps._mdf=!0,e[e.length-1].transform.op._mdf=!0,e[e.length-1].transform.op.v=1===this._currentCopies?this.so.v:this.so.v+(this.eo.v-this.so.v)*(i/(this._currentCopies-1)),0!==P){for((0!==i&&1===s||i!==this._currentCopies-1&&-1===s)&&this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),this.matrix.transform(y[0],y[1],y[2],y[3],y[4],y[5],y[6],y[7],y[8],y[9],y[10],y[11],y[12],y[13],y[14],y[15]),this.matrix.transform(g[0],g[1],g[2],g[3],g[4],g[5],g[6],g[7],g[8],g[9],g[10],g[11],g[12],g[13],g[14],g[15]),this.matrix.transform(u[0],u[1],u[2],u[3],u[4],u[5],u[6],u[7],u[8],u[9],u[10],u[11],u[12],u[13],u[14],u[15]),v=0;v0&&(p=!1),p){var f=createTag("style");f.setAttribute("f-forigin",i[r].fOrigin),f.setAttribute("f-origin",i[r].origin),f.setAttribute("f-family",i[r].fFamily),f.type="text/css",f.innerText="@font-face {font-family: "+i[r].fFamily+"; font-style: normal; src: url('"+i[r].fPath+"');}",e.appendChild(f)}}else if("g"===i[r].fOrigin||1===i[r].origin){for(h=document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]'),l=0;lt?!0!==this.isInRange&&(this.globalData._mdf=!0,this._mdf=!0,this.isInRange=!0,this.show()):!1!==this.isInRange&&(this.globalData._mdf=!0,this.isInRange=!1,this.hide())},renderRenderable:function(){var t,e=this.renderableComponents.length;for(t=0;t0&&(this.maskElement.setAttribute("id",y),this.element.maskedElement.setAttribute(v,"url("+getLocationHref()+"#"+y+")"),a.appendChild(this.maskElement)),this.viewData.length&&this.element.addRenderableComponent(this)}FootageElement.prototype.prepareFrame=function(){},extendPrototype([RenderableElement,BaseElement,FrameElement],FootageElement),FootageElement.prototype.getBaseElement=function(){return null},FootageElement.prototype.renderFrame=function(){},FootageElement.prototype.destroy=function(){},FootageElement.prototype.initExpressions=function(){this.layerInterface=FootageInterface(this)},FootageElement.prototype.getFootageData=function(){return this.footageData},AudioElement.prototype.prepareFrame=function(t){if(this.prepareRenderableFrame(t,!0),this.prepareProperties(t,!0),this.tm._placeholder)this._currentTime=t/this.data.sr;else{var e=this.tm.v;this._currentTime=e}},extendPrototype([RenderableElement,BaseElement,FrameElement],AudioElement),AudioElement.prototype.renderFrame=function(){this.isInRange&&this._canPlay&&(this._isPlaying?(!this.audio.playing()||Math.abs(this._currentTime/this.globalData.frameRate-this.audio.seek())>.1)&&this.audio.seek(this._currentTime/this.globalData.frameRate):(this.audio.play(),this.audio.seek(this._currentTime/this.globalData.frameRate),this._isPlaying=!0))},AudioElement.prototype.show=function(){},AudioElement.prototype.hide=function(){this.audio.pause(),this._isPlaying=!1},AudioElement.prototype.pause=function(){this.audio.pause(),this._isPlaying=!1,this._canPlay=!1},AudioElement.prototype.resume=function(){this._canPlay=!0},AudioElement.prototype.setRate=function(t){this.audio.rate(t)},AudioElement.prototype.volume=function(t){this.audio.volume(t)},AudioElement.prototype.getBaseElement=function(){return null},AudioElement.prototype.destroy=function(){},AudioElement.prototype.sourceRectAtTime=function(){},AudioElement.prototype.initExpressions=function(){},BaseRenderer.prototype.checkLayers=function(t){var e,r,i=this.layers.length;for(this.completeLayers=!0,e=i-1;e>=0;e-=1)this.elements[e]||(r=this.layers[e]).ip-r.st<=t-this.layers[e].st&&r.op-r.st>t-this.layers[e].st&&this.buildItem(e),this.completeLayers=!!this.elements[e]&&this.completeLayers;this.checkPendingElements()},BaseRenderer.prototype.createItem=function(t){switch(t.ty){case 2:return this.createImage(t);case 0:return this.createComp(t);case 1:return this.createSolid(t);case 3:default:return this.createNull(t);case 4:return this.createShape(t);case 5:return this.createText(t);case 6:return this.createAudio(t);case 13:return this.createCamera(t);case 15:return this.createFootage(t)}},BaseRenderer.prototype.createCamera=function(){throw new Error("You're using a 3d camera. Try the html renderer.")},BaseRenderer.prototype.createAudio=function(t){return new AudioElement(t,this.globalData,this)},BaseRenderer.prototype.createFootage=function(t){return new FootageElement(t,this.globalData,this)},BaseRenderer.prototype.buildAllItems=function(){var t,e=this.layers.length;for(t=0;t1&&(a+=" C"+e.o[i-1][0]+","+e.o[i-1][1]+" "+e.i[0][0]+","+e.i[0][1]+" "+e.v[0][0]+","+e.v[0][1]),r.lastPath!==a){var n="";r.elem&&(e.c&&(n=t.inv?this.solidPath+a:a),r.elem.setAttribute("d",n)),r.lastPath=a}},MaskElement.prototype.destroy=function(){this.element=null,this.globalData=null,this.maskElement=null,this.data=null,this.masksProperties=null};var filtersFactory=function(){var t={};return t.createFilter=function(t,e){var r=createNS("filter");r.setAttribute("id",t),!0!==e&&(r.setAttribute("filterUnits","objectBoundingBox"),r.setAttribute("x","0%"),r.setAttribute("y","0%"),r.setAttribute("width","100%"),r.setAttribute("height","100%"));return r},t.createAlphaToLuminanceFilter=function(){var t=createNS("feColorMatrix");return t.setAttribute("type","matrix"),t.setAttribute("color-interpolation-filters","sRGB"),t.setAttribute("values","0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 1"),t},t}(),featureSupport=function(){var t={maskType:!0};return(/MSIE 10/i.test(navigator.userAgent)||/MSIE 9/i.test(navigator.userAgent)||/rv:11.0/i.test(navigator.userAgent)||/Edge\/\d./i.test(navigator.userAgent))&&(t.maskType=!1),t}();function SVGTintFilter(t,e){this.filterManager=e;var r=createNS("feColorMatrix");if(r.setAttribute("type","matrix"),r.setAttribute("color-interpolation-filters","linearRGB"),r.setAttribute("values","0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0"),r.setAttribute("result","f1"),t.appendChild(r),(r=createNS("feColorMatrix")).setAttribute("type","matrix"),r.setAttribute("color-interpolation-filters","sRGB"),r.setAttribute("values","1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"),r.setAttribute("result","f2"),t.appendChild(r),this.matrixFilter=r,100!==e.effectElements[2].p.v||e.effectElements[2].p.k){var i,s=createNS("feMerge");t.appendChild(s),(i=createNS("feMergeNode")).setAttribute("in","SourceGraphic"),s.appendChild(i),(i=createNS("feMergeNode")).setAttribute("in","f2"),s.appendChild(i)}}function SVGFillFilter(t,e){this.filterManager=e;var r=createNS("feColorMatrix");r.setAttribute("type","matrix"),r.setAttribute("color-interpolation-filters","sRGB"),r.setAttribute("values","1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"),t.appendChild(r),this.matrixFilter=r}function SVGStrokeEffect(t,e){this.initialized=!1,this.filterManager=e,this.elem=t,this.paths=[]}function SVGTritoneFilter(t,e){this.filterManager=e;var r=createNS("feColorMatrix");r.setAttribute("type","matrix"),r.setAttribute("color-interpolation-filters","linearRGB"),r.setAttribute("values","0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0"),r.setAttribute("result","f1"),t.appendChild(r);var i=createNS("feComponentTransfer");i.setAttribute("color-interpolation-filters","sRGB"),t.appendChild(i),this.matrixFilter=i;var s=createNS("feFuncR");s.setAttribute("type","table"),i.appendChild(s),this.feFuncR=s;var a=createNS("feFuncG");a.setAttribute("type","table"),i.appendChild(a),this.feFuncG=a;var n=createNS("feFuncB");n.setAttribute("type","table"),i.appendChild(n),this.feFuncB=n}function SVGProLevelsFilter(t,e){this.filterManager=e;var r=this.filterManager.effectElements,i=createNS("feComponentTransfer");(r[10].p.k||0!==r[10].p.v||r[11].p.k||1!==r[11].p.v||r[12].p.k||1!==r[12].p.v||r[13].p.k||0!==r[13].p.v||r[14].p.k||1!==r[14].p.v)&&(this.feFuncR=this.createFeFunc("feFuncR",i)),(r[17].p.k||0!==r[17].p.v||r[18].p.k||1!==r[18].p.v||r[19].p.k||1!==r[19].p.v||r[20].p.k||0!==r[20].p.v||r[21].p.k||1!==r[21].p.v)&&(this.feFuncG=this.createFeFunc("feFuncG",i)),(r[24].p.k||0!==r[24].p.v||r[25].p.k||1!==r[25].p.v||r[26].p.k||1!==r[26].p.v||r[27].p.k||0!==r[27].p.v||r[28].p.k||1!==r[28].p.v)&&(this.feFuncB=this.createFeFunc("feFuncB",i)),(r[31].p.k||0!==r[31].p.v||r[32].p.k||1!==r[32].p.v||r[33].p.k||1!==r[33].p.v||r[34].p.k||0!==r[34].p.v||r[35].p.k||1!==r[35].p.v)&&(this.feFuncA=this.createFeFunc("feFuncA",i)),(this.feFuncR||this.feFuncG||this.feFuncB||this.feFuncA)&&(i.setAttribute("color-interpolation-filters","sRGB"),t.appendChild(i),i=createNS("feComponentTransfer")),(r[3].p.k||0!==r[3].p.v||r[4].p.k||1!==r[4].p.v||r[5].p.k||1!==r[5].p.v||r[6].p.k||0!==r[6].p.v||r[7].p.k||1!==r[7].p.v)&&(i.setAttribute("color-interpolation-filters","sRGB"),t.appendChild(i),this.feFuncRComposed=this.createFeFunc("feFuncR",i),this.feFuncGComposed=this.createFeFunc("feFuncG",i),this.feFuncBComposed=this.createFeFunc("feFuncB",i))}function SVGDropShadowEffect(t,e){var r=e.container.globalData.renderConfig.filterSize;t.setAttribute("x",r.x),t.setAttribute("y",r.y),t.setAttribute("width",r.width),t.setAttribute("height",r.height),this.filterManager=e;var i=createNS("feGaussianBlur");i.setAttribute("in","SourceAlpha"),i.setAttribute("result","drop_shadow_1"),i.setAttribute("stdDeviation","0"),this.feGaussianBlur=i,t.appendChild(i);var s=createNS("feOffset");s.setAttribute("dx","25"),s.setAttribute("dy","0"),s.setAttribute("in","drop_shadow_1"),s.setAttribute("result","drop_shadow_2"),this.feOffset=s,t.appendChild(s);var a=createNS("feFlood");a.setAttribute("flood-color","#00ff00"),a.setAttribute("flood-opacity","1"),a.setAttribute("result","drop_shadow_3"),this.feFlood=a,t.appendChild(a);var n=createNS("feComposite");n.setAttribute("in","drop_shadow_3"),n.setAttribute("in2","drop_shadow_2"),n.setAttribute("operator","in"),n.setAttribute("result","drop_shadow_4"),t.appendChild(n);var o,h=createNS("feMerge");t.appendChild(h),o=createNS("feMergeNode"),h.appendChild(o),(o=createNS("feMergeNode")).setAttribute("in","SourceGraphic"),this.feMergeNode=o,this.feMerge=h,this.originalNodeAdded=!1,h.appendChild(o)}SVGTintFilter.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e=this.filterManager.effectElements[0].p.v,r=this.filterManager.effectElements[1].p.v,i=this.filterManager.effectElements[2].p.v/100;this.matrixFilter.setAttribute("values",r[0]-e[0]+" 0 0 0 "+e[0]+" "+(r[1]-e[1])+" 0 0 0 "+e[1]+" "+(r[2]-e[2])+" 0 0 0 "+e[2]+" 0 0 0 "+i+" 0")}},SVGFillFilter.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e=this.filterManager.effectElements[2].p.v,r=this.filterManager.effectElements[6].p.v;this.matrixFilter.setAttribute("values","0 0 0 0 "+e[0]+" 0 0 0 0 "+e[1]+" 0 0 0 0 "+e[2]+" 0 0 0 "+r+" 0")}},SVGStrokeEffect.prototype.initialize=function(){var t,e,r,i,s=this.elem.layerElement.children||this.elem.layerElement.childNodes;for(1===this.filterManager.effectElements[1].p.v?(i=this.elem.maskManager.masksProperties.length,r=0):i=(r=this.filterManager.effectElements[0].p.v-1)+1,(e=createNS("g")).setAttribute("fill","none"),e.setAttribute("stroke-linecap","round"),e.setAttribute("stroke-dashoffset",1);r=l?c<0?i:s:i+m*Math.pow((a-t)/c,1/r),p[f]=n,f+=1,o+=256/255;return p.join(" ")},SVGProLevelsFilter.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e,r=this.filterManager.effectElements;this.feFuncRComposed&&(t||r[3].p._mdf||r[4].p._mdf||r[5].p._mdf||r[6].p._mdf||r[7].p._mdf)&&(e=this.getTableValue(r[3].p.v,r[4].p.v,r[5].p.v,r[6].p.v,r[7].p.v),this.feFuncRComposed.setAttribute("tableValues",e),this.feFuncGComposed.setAttribute("tableValues",e),this.feFuncBComposed.setAttribute("tableValues",e)),this.feFuncR&&(t||r[10].p._mdf||r[11].p._mdf||r[12].p._mdf||r[13].p._mdf||r[14].p._mdf)&&(e=this.getTableValue(r[10].p.v,r[11].p.v,r[12].p.v,r[13].p.v,r[14].p.v),this.feFuncR.setAttribute("tableValues",e)),this.feFuncG&&(t||r[17].p._mdf||r[18].p._mdf||r[19].p._mdf||r[20].p._mdf||r[21].p._mdf)&&(e=this.getTableValue(r[17].p.v,r[18].p.v,r[19].p.v,r[20].p.v,r[21].p.v),this.feFuncG.setAttribute("tableValues",e)),this.feFuncB&&(t||r[24].p._mdf||r[25].p._mdf||r[26].p._mdf||r[27].p._mdf||r[28].p._mdf)&&(e=this.getTableValue(r[24].p.v,r[25].p.v,r[26].p.v,r[27].p.v,r[28].p.v),this.feFuncB.setAttribute("tableValues",e)),this.feFuncA&&(t||r[31].p._mdf||r[32].p._mdf||r[33].p._mdf||r[34].p._mdf||r[35].p._mdf)&&(e=this.getTableValue(r[31].p.v,r[32].p.v,r[33].p.v,r[34].p.v,r[35].p.v),this.feFuncA.setAttribute("tableValues",e))}},SVGDropShadowEffect.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){if((t||this.filterManager.effectElements[4].p._mdf)&&this.feGaussianBlur.setAttribute("stdDeviation",this.filterManager.effectElements[4].p.v/4),t||this.filterManager.effectElements[0].p._mdf){var e=this.filterManager.effectElements[0].p.v;this.feFlood.setAttribute("flood-color",rgbToHex(Math.round(255*e[0]),Math.round(255*e[1]),Math.round(255*e[2])))}if((t||this.filterManager.effectElements[1].p._mdf)&&this.feFlood.setAttribute("flood-opacity",this.filterManager.effectElements[1].p.v/255),t||this.filterManager.effectElements[2].p._mdf||this.filterManager.effectElements[3].p._mdf){var r=this.filterManager.effectElements[3].p.v,i=(this.filterManager.effectElements[2].p.v-90)*degToRads,s=r*Math.cos(i),a=r*Math.sin(i);this.feOffset.setAttribute("dx",s),this.feOffset.setAttribute("dy",a)}}};var _svgMatteSymbols=[];function SVGMatte3Effect(t,e,r){this.initialized=!1,this.filterManager=e,this.filterElem=t,this.elem=r,r.matteElement=createNS("g"),r.matteElement.appendChild(r.layerElement),r.matteElement.appendChild(r.transformedElement),r.baseElement=r.matteElement}function SVGGaussianBlurEffect(t,e){t.setAttribute("x","-100%"),t.setAttribute("y","-100%"),t.setAttribute("width","300%"),t.setAttribute("height","300%"),this.filterManager=e;var r=createNS("feGaussianBlur");t.appendChild(r),this.feGaussianBlur=r}SVGMatte3Effect.prototype.findSymbol=function(t){for(var e=0,r=_svgMatteSymbols.length;e=0&&!this.shapeModifiers[t].processShapes(this._isFirstFrame);t-=1);}},searchProcessedElement:function(t){for(var e=this.processedElements,r=0,i=e.length;r.01)return!1;r+=1}return!0},GradientProperty.prototype.checkCollapsable=function(){if(this.o.length/2!=this.c.length/4)return!1;if(this.data.k.k[0].s)for(var t=0,e=this.data.k.k.length;t0;)h=i.transformers[u].mProps._mdf||h,d-=1,u-=1;if(h)for(d=g-i.styles[p].lvl,u=i.transformers.length-1;d>0;)c=i.transformers[u].mProps.v.props,m.transform(c[0],c[1],c[2],c[3],c[4],c[5],c[6],c[7],c[8],c[9],c[10],c[11],c[12],c[13],c[14],c[15]),d-=1,u-=1}else m=t;if(n=(f=i.sh.paths)._length,h){for(o="",a=0;a=1?v=.99:v<=-1&&(v=-.99);var b=o*v,P=Math.cos(g+e.a.v)*b+p[0],E=Math.sin(g+e.a.v)*b+p[1];h.setAttribute("fx",P),h.setAttribute("fy",E),l&&!e.g._collapsable&&(e.of.setAttribute("fx",P),e.of.setAttribute("fy",E))}}function h(t,e,r){var i=e.style,s=e.d;s&&(s._mdf||r)&&s.dashStr&&(i.pElem.setAttribute("stroke-dasharray",s.dashStr),i.pElem.setAttribute("stroke-dashoffset",s.dashoffset[0])),e.c&&(e.c._mdf||r)&&i.pElem.setAttribute("stroke","rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||r)&&i.pElem.setAttribute("stroke-opacity",e.o.v),(e.w._mdf||r)&&(i.pElem.setAttribute("stroke-width",e.w.v),i.msElem&&i.msElem.setAttribute("stroke-width",e.w.v))}return{createRenderFunction:function(t){switch(t.ty){case"fl":return a;case"gf":return o;case"gs":return n;case"st":return h;case"sh":case"el":case"rc":case"sr":return s;case"tr":return r;case"no":return i;default:return null}}}}();function SVGShapeElement(t,e,r){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.shapeModifiers=[],this.itemsData=[],this.processedElements=[],this.animatedContents=[],this.initElement(t,e,r),this.prevViewData=[]}function LetterProps(t,e,r,i,s,a){this.o=t,this.sw=e,this.sc=r,this.fc=i,this.m=s,this.p=a,this._mdf={o:!0,sw:!!e,sc:!!r,fc:!!i,m:!0,p:!0}}function TextProperty(t,e){this._frameId=initialDefaultFrame,this.pv="",this.v="",this.kf=!1,this._isFirstFrame=!0,this._mdf=!1,this.data=e,this.elem=t,this.comp=this.elem.comp,this.keysIndex=0,this.canResize=!1,this.minimumFontSize=1,this.effectsSequence=[],this.currentData={ascent:0,boxWidth:this.defaultBoxWidth,f:"",fStyle:"",fWeight:"",fc:"",j:"",justifyOffset:"",l:[],lh:0,lineWidths:[],ls:"",of:"",s:"",sc:"",sw:0,t:0,tr:0,sz:0,ps:null,fillColorAnim:!1,strokeColorAnim:!1,strokeWidthAnim:!1,yOffset:0,finalSize:0,finalText:[],finalLineHeight:0,__complete:!1},this.copyData(this.currentData,this.data.d.k[0].s),this.searchProperty()||this.completeTextData(this.currentData)}extendPrototype([BaseElement,TransformElement,SVGBaseElement,IShapeElement,HierarchyElement,FrameElement,RenderableDOMElement],SVGShapeElement),SVGShapeElement.prototype.initSecondaryElement=function(){},SVGShapeElement.prototype.identityMatrix=new Matrix,SVGShapeElement.prototype.buildExpressionInterface=function(){},SVGShapeElement.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes()},SVGShapeElement.prototype.filterUniqueShapes=function(){var t,e,r,i,s=this.shapes.length,a=this.stylesList.length,n=[],o=!1;for(r=0;r1&&o&&this.setShapesAsAnimated(n)}},SVGShapeElement.prototype.setShapesAsAnimated=function(t){var e,r=t.length;for(e=0;e=0;o-=1){if((m=this.searchProcessedElement(t[o]))?e[o]=r[m-1]:t[o]._render=n,"fl"===t[o].ty||"st"===t[o].ty||"gf"===t[o].ty||"gs"===t[o].ty||"no"===t[o].ty)m?e[o].style.closed=!1:e[o]=this.createStyleElement(t[o],s),t[o]._render&&e[o].style.pElem.parentNode!==i&&i.appendChild(e[o].style.pElem),u.push(e[o].style);else if("gr"===t[o].ty){if(m)for(l=e[o].it.length,h=0;h1,this.kf&&this.addEffect(this.getKeyframeValue.bind(this)),this.kf},TextProperty.prototype.addEffect=function(t){this.effectsSequence.push(t),this.elem.addDynamicProperty(this)},TextProperty.prototype.getValue=function(t){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length||t){this.currentData.t=this.data.d.k[this.keysIndex].s.t;var e=this.currentData,r=this.keysIndex;if(this.lock)this.setCurrentData(this.currentData);else{var i;this.lock=!0,this._mdf=!1;var s=this.effectsSequence.length,a=t||this.data.d.k[this.keysIndex].s;for(i=0;ie);)r+=1;return this.keysIndex!==r&&(this.keysIndex=r),this.data.d.k[this.keysIndex].s},TextProperty.prototype.buildFinalText=function(t){for(var e,r,i=[],s=0,a=t.length,n=!1;s=55296&&e<=56319?(r=t.charCodeAt(s+1))>=56320&&r<=57343?(n||FontManager.isModifier(e,r)?(i[i.length-1]+=t.substr(s,2),n=!1):i.push(t.substr(s,2)),s+=1):i.push(t.charAt(s)):e>56319?(r=t.charCodeAt(s+1),FontManager.isZeroWidthJoiner(e,r)?(n=!0,i[i.length-1]+=t.substr(s,2),s+=1):i.push(t.charAt(s))):FontManager.isZeroWidthJoiner(e)?(i[i.length-1]+=t.charAt(s),n=!0):i.push(t.charAt(s)),s+=1;return i},TextProperty.prototype.completeTextData=function(t){t.__complete=!0;var e,r,i,s,a,n,o,h=this.elem.globalData.fontManager,l=this.data,p=[],f=0,m=l.m.g,c=0,d=0,u=0,y=[],g=0,v=0,b=h.getFontByName(t.f),P=0,E=getFontProperties(b);t.fWeight=E.weight,t.fStyle=E.style,t.finalSize=t.s,t.finalText=this.buildFinalText(t.t),r=t.finalText.length,t.finalLineHeight=t.lh;var x,S=t.tr/1e3*t.finalSize;if(t.sz)for(var C,A,_=!0,T=t.sz[0],k=t.sz[1];_;){C=0,g=0,r=(A=this.buildFinalText(t.t)).length,S=t.tr/1e3*t.finalSize;var D=-1;for(e=0;eT&&" "!==A[e]?(-1===D?r+=1:e=D,C+=t.finalLineHeight||1.2*t.finalSize,A.splice(e,D===e?1:0,"\r"),D=-1,g=0):(g+=P,g+=S);C+=b.ascent*t.finalSize/100,this.canResize&&t.finalSize>this.minimumFontSize&&kv?g:v,g=-2*S,s="",i=!0,u+=1):s=M,h.chars?(o=h.getCharData(M,b.fStyle,h.getFontByName(t.f).fFamily),P=i?0:o.w*t.finalSize/100):P=h.measureText(s,t.f,t.finalSize)," "===M?F+=P+S:(g+=P+S+F,F=0),p.push({l:P,an:P,add:c,n:i,anIndexes:[],val:s,line:u,animatorJustifyOffset:0}),2==m){if(c+=P,""===s||" "===s||e===r-1){for(""!==s&&" "!==s||(c-=P);d<=e;)p[d].an=c,p[d].ind=f,p[d].extra=P,d+=1;f+=1,c=0}}else if(3==m){if(c+=P,""===s||e===r-1){for(""===s&&(c-=P);d<=e;)p[d].an=c,p[d].ind=f,p[d].extra=P,d+=1;c=0,f+=1}}else p[f].ind=f,p[f].extra=0,f+=1;if(t.l=p,v=g>v?g:v,y.push(g),t.sz)t.boxWidth=t.sz[0],t.justifyOffset=0;else switch(t.boxWidth=v,t.j){case 1:t.justifyOffset=-t.boxWidth;break;case 2:t.justifyOffset=-t.boxWidth/2;break;default:t.justifyOffset=0}t.lineWidths=y;var w,I,V,B,R=l.a;n=R.length;var L=[];for(a=0;a0?s=this.ne.v/100:a=-this.ne.v/100,this.xe.v>0?n=1-this.xe.v/100:o=1+this.xe.v/100;var h=BezierFactory.getBezierEasing(s,a,n,o).get,l=0,p=this.finalS,f=this.finalE,m=this.data.sh;if(2===m)l=h(l=f===p?i>=f?1:0:t(0,e(.5/(f-p)+(i-p)/(f-p),1)));else if(3===m)l=h(l=f===p?i>=f?0:1:1-t(0,e(.5/(f-p)+(i-p)/(f-p),1)));else if(4===m)f===p?l=0:(l=t(0,e(.5/(f-p)+(i-p)/(f-p),1)))<.5?l*=2:l=1-2*(l-.5),l=h(l);else if(5===m){if(f===p)l=0;else{var c=f-p,d=-c/2+(i=e(t(0,i+.5-p),f-p)),u=c/2;l=Math.sqrt(1-d*d/(u*u))}l=h(l)}else 6===m?(f===p?l=0:(i=e(t(0,i+.5-p),f-p),l=(1+Math.cos(Math.PI+2*Math.PI*i/(f-p)))/2),l=h(l)):(i>=r(p)&&(l=t(0,e(i-p<0?e(f,1)-(p-i):f-i,1))),l=h(l));if(100!==this.sm.v){var y=.01*this.sm.v;0===y&&(y=1e-8);var g=.5-.5*y;l1&&(l=1)}return l*this.a.v},getValue:function(t){this.iterateDynamicProperties(),this._mdf=t||this._mdf,this._currentTextLength=this.elem.textProperty.currentData.l.length||0,t&&2===this.data.r&&(this.e.v=this._currentTextLength);var e=2===this.data.r?1:100/this.data.totalChars,r=this.o.v/e,i=this.s.v/e+r,s=this.e.v/e+r;if(i>s){var a=i;i=s,s=a}this.finalS=i,this.finalE=s}},extendPrototype([DynamicPropertyContainer],i),{getTextSelectorProp:function(t,e,r){return new i(t,e,r)}}}();function TextAnimatorDataProperty(t,e,r){var i={propType:!1},s=PropertyFactory.getProp,a=e.a;this.a={r:a.r?s(t,a.r,0,degToRads,r):i,rx:a.rx?s(t,a.rx,0,degToRads,r):i,ry:a.ry?s(t,a.ry,0,degToRads,r):i,sk:a.sk?s(t,a.sk,0,degToRads,r):i,sa:a.sa?s(t,a.sa,0,degToRads,r):i,s:a.s?s(t,a.s,1,.01,r):i,a:a.a?s(t,a.a,1,0,r):i,o:a.o?s(t,a.o,0,.01,r):i,p:a.p?s(t,a.p,1,0,r):i,sw:a.sw?s(t,a.sw,0,0,r):i,sc:a.sc?s(t,a.sc,1,0,r):i,fc:a.fc?s(t,a.fc,1,0,r):i,fh:a.fh?s(t,a.fh,0,0,r):i,fs:a.fs?s(t,a.fs,0,.01,r):i,fb:a.fb?s(t,a.fb,0,.01,r):i,t:a.t?s(t,a.t,0,0,r):i},this.s=TextSelectorProp.getTextSelectorProp(t,e.s,r),this.s.t=e.s.t}function TextAnimatorProperty(t,e,r){this._isFirstFrame=!0,this._hasMaskedPath=!1,this._frameId=-1,this._textData=t,this._renderType=e,this._elem=r,this._animatorsData=createSizedArray(this._textData.a.length),this._pathData={},this._moreOptions={alignment:{}},this.renderedLetters=[],this.lettersChangedFlag=!1,this.initDynamicPropertyContainer(r)}function ITextElement(){}TextAnimatorProperty.prototype.searchProperties=function(){var t,e,r=this._textData.a.length,i=PropertyFactory.getProp;for(t=0;t=o+ot||!d?(v=(o+ot-l)/h.partialLength,G=c.point[0]+(h.point[0]-c.point[0])*v,z=c.point[1]+(h.point[1]-c.point[1])*v,C.translate(-E[0]*T[s].an*.005,-E[1]*B*.01),p=!1):d&&(l+=h.partialLength,(f+=1)>=d.length&&(f=0,u[m+=1]?d=u[m].points:P.v.c?(f=0,d=u[m=0].points):(l-=h.partialLength,d=null)),d&&(c=h,y=(h=d[f]).partialLength));L=T[s].an/2-T[s].add,C.translate(-L,0,0)}else L=T[s].an/2-T[s].add,C.translate(-L,0,0),C.translate(-E[0]*T[s].an*.005,-E[1]*B*.01,0);for(F=0;Ft?this.textSpans[t].span:createNS(h?"g":"text"),y<=t){if(n.setAttribute("stroke-linecap","butt"),n.setAttribute("stroke-linejoin","round"),n.setAttribute("stroke-miterlimit","4"),this.textSpans[t].span=n,h){var g=createNS("g");n.appendChild(g),this.textSpans[t].childSpan=g}this.textSpans[t].span=n,this.layerElement.appendChild(n)}n.style.display="inherit"}if(l.reset(),l.scale(r.finalSize/100,r.finalSize/100),p&&(o[t].n&&(f=-d,m+=r.yOffset,m+=c?1:0,c=!1),this.applyTextPropertiesToMatrix(r,l,o[t].line,f,m),f+=o[t].l||0,f+=d),h){var v;if(1===(u=this.globalData.fontManager.getCharData(r.finalText[t],i.fStyle,this.globalData.fontManager.getFontByName(r.f).fFamily)).t)v=new SVGCompElement(u.data,this.globalData,this);else{var b=emptyShapeData;u.data&&u.data.shapes&&(b=u.data),v=new SVGShapeElement(b,this.globalData,this)}if(this.textSpans[t].glyph){var P=this.textSpans[t].glyph;this.textSpans[t].childSpan.removeChild(P.layerElement),P.destroy()}this.textSpans[t].glyph=v,v._debug=!0,v.prepareFrame(0),v.renderFrame(),this.textSpans[t].childSpan.appendChild(v.layerElement),this.textSpans[t].childSpan.setAttribute("transform","scale("+r.finalSize/100+","+r.finalSize/100+")")}else p&&n.setAttribute("transform","translate("+l.props[12]+","+l.props[13]+")"),n.textContent=o[t].val,n.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve")}p&&n&&n.setAttribute("d","")}else{var E=this.textContainer,x="start";switch(r.j){case 1:x="end";break;case 2:x="middle";break;default:x="start"}E.setAttribute("text-anchor",x),E.setAttribute("letter-spacing",d);var S=this.buildTextContents(r.finalText);for(e=S.length,m=r.ps?r.ps[1]+r.ascent:0,t=0;t=0;e-=1)(this.completeLayers||this.elements[e])&&this.elements[e].prepareFrame(t-this.layers[e].st);if(this.globalData._mdf)for(e=0;e=0;r-=1)(this.completeLayers||this.elements[r])&&(this.elements[r].prepareFrame(this.renderedFrame-this.layers[r].st),this.elements[r]._mdf&&(this._mdf=!0))}},ICompElement.prototype.renderInnerContent=function(){var t,e=this.layers.length;for(t=0;t=0;i-=1)r=t.transforms[i].transform.mProps.v.props,t.finalTransform.transform(r[0],r[1],r[2],r[3],r[4],r[5],r[6],r[7],r[8],r[9],r[10],r[11],r[12],r[13],r[14],r[15]);t._mdf=a},processSequences:function(t){var e,r=this.sequenceList.length;for(e=0;e=0;a-=1){if((h=this.searchProcessedElement(t[a]))?e[a]=r[h-1]:t[a]._shouldRender=i,"fl"===t[a].ty||"st"===t[a].ty||"gf"===t[a].ty||"gs"===t[a].ty)h?e[a].style.closed=!1:e[a]=this.createStyleElement(t[a],d),m.push(e[a].style);else if("gr"===t[a].ty){if(h)for(o=e[a].it.length,n=0;n=0;s-=1)"tr"===e[s].ty?(a=r[s].transform,this.renderShapeTransform(t,a)):"sh"===e[s].ty||"el"===e[s].ty||"rc"===e[s].ty||"sr"===e[s].ty?this.renderPath(e[s],r[s]):"fl"===e[s].ty?this.renderFill(e[s],r[s],a):"st"===e[s].ty?this.renderStroke(e[s],r[s],a):"gf"===e[s].ty||"gs"===e[s].ty?this.renderGradientFill(e[s],r[s],a):"gr"===e[s].ty?this.renderShape(a,e[s].it,r[s].it):e[s].ty;i&&this.drawLayer()},CVShapeElement.prototype.renderStyledShape=function(t,e){if(this._isFirstFrame||e._mdf||t.transforms._mdf){var r,i,s,a=t.trNodes,n=e.paths,o=n._length;a.length=0;var h=t.transforms.finalTransform;for(s=0;s=1?f=.99:f<=-1&&(f=-.99);var m=l*f,c=Math.cos(p+e.a.v)*m+o[0],d=Math.sin(p+e.a.v)*m+o[1];i=n.createRadialGradient(c,d,0,o[0],o[1],l)}var u=t.g.p,y=e.g.c,g=1;for(a=0;ao&&"xMidYMid slice"===h||nr&&"meet"===a||ir&&"slice"===a)?(t-this.transformCanvas.w*(e/this.transformCanvas.h))/2*this.renderConfig.dpr:"xMax"===o&&(ir&&"slice"===a)?(t-this.transformCanvas.w*(e/this.transformCanvas.h))*this.renderConfig.dpr:0,this.transformCanvas.ty="YMid"===h&&(i>r&&"meet"===a||ir&&"meet"===a||i=0;t-=1)this.elements[t]&&this.elements[t].destroy();this.elements.length=0,this.globalData.canvasContext=null,this.animationItem.container=null,this.destroyed=!0},CanvasRendererBase.prototype.renderFrame=function(t,e){if((this.renderedFrame!==t||!0!==this.renderConfig.clearCanvas||e)&&!this.destroyed&&-1!==t){var r;this.renderedFrame=t,this.globalData.frameNum=t-this.animationItem._isFirstFrame,this.globalData.frameId+=1,this.globalData._mdf=!this.renderConfig.clearCanvas||e,this.globalData.projectInterface.currentFrame=t;var i=this.layers.length;for(this.completeLayers||this.checkLayers(t),r=0;r=0;r-=1)(this.completeLayers||this.elements[r])&&this.elements[r].renderFrame();!0!==this.renderConfig.clearCanvas&&this.restore()}}},CanvasRendererBase.prototype.buildItem=function(t){var e=this.elements;if(!e[t]&&99!==this.layers[t].ty){var r=this.createItem(this.layers[t],this,this.globalData);e[t]=r,r.initExpressions()}},CanvasRendererBase.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){this.pendingElements.pop().checkParenting()}},CanvasRendererBase.prototype.hide=function(){this.animationItem.container.style.display="none"},CanvasRendererBase.prototype.show=function(){this.animationItem.container.style.display="block"},extendPrototype([CanvasRendererBase,ICompElement,CVBaseElement],CVCompElement),CVCompElement.prototype.renderInnerContent=function(){var t,e=this.canvasContext;for(e.beginPath(),e.moveTo(0,0),e.lineTo(this.data.w,0),e.lineTo(this.data.w,this.data.h),e.lineTo(0,this.data.h),e.lineTo(0,0),e.clip(),t=this.layers.length-1;t>=0;t-=1)(this.completeLayers||this.elements[t])&&this.elements[t].renderFrame()},CVCompElement.prototype.destroy=function(){var t;for(t=this.layers.length-1;t>=0;t-=1)this.elements[t]&&this.elements[t].destroy();this.layers=null,this.elements=null},CVCompElement.prototype.createComp=function(t){return new CVCompElement(t,this.globalData,this)},extendPrototype([CanvasRendererBase],CanvasRenderer),CanvasRenderer.prototype.createComp=function(t){return new CVCompElement(t,this.globalData,this)},HBaseElement.prototype={checkBlendMode:function(){},initRendererElement:function(){this.baseElement=createTag(this.data.tg||"div"),this.data.hasMask?(this.svgElement=createNS("svg"),this.layerElement=createNS("g"),this.maskedElement=this.layerElement,this.svgElement.appendChild(this.layerElement),this.baseElement.appendChild(this.svgElement)):this.layerElement=this.baseElement,styleDiv(this.baseElement)},createContainerElements:function(){this.renderableEffectsManager=new CVEffects(this),this.transformedElement=this.baseElement,this.maskedElement=this.layerElement,this.data.ln&&this.layerElement.setAttribute("id",this.data.ln),this.data.cl&&this.layerElement.setAttribute("class",this.data.cl),0!==this.data.bm&&this.setBlendMode()},renderElement:function(){var t=this.transformedElement?this.transformedElement.style:{};if(this.finalTransform._matMdf){var e=this.finalTransform.mat.toCSS();t.transform=e,t.webkitTransform=e}this.finalTransform._opMdf&&(t.opacity=this.finalTransform.mProp.o.v)},renderFrame:function(){this.data.hd||this.hidden||(this.renderTransform(),this.renderRenderable(),this.renderElement(),this.renderInnerContent(),this._isFirstFrame&&(this._isFirstFrame=!1))},destroy:function(){this.layerElement=null,this.transformedElement=null,this.matteElement&&(this.matteElement=null),this.maskManager&&(this.maskManager.destroy(),this.maskManager=null)},createRenderableComponents:function(){this.maskManager=new MaskElement(this.data,this,this.globalData)},addEffects:function(){},setMatte:function(){}},HBaseElement.prototype.getBaseElement=SVGBaseElement.prototype.getBaseElement,HBaseElement.prototype.destroyBaseElement=HBaseElement.prototype.destroy,HBaseElement.prototype.buildElementParenting=BaseRenderer.prototype.buildElementParenting,extendPrototype([BaseElement,TransformElement,HBaseElement,HierarchyElement,FrameElement,RenderableDOMElement],HSolidElement),HSolidElement.prototype.createContent=function(){var t;this.data.hasMask?((t=createNS("rect")).setAttribute("width",this.data.sw),t.setAttribute("height",this.data.sh),t.setAttribute("fill",this.data.sc),this.svgElement.setAttribute("width",this.data.sw),this.svgElement.setAttribute("height",this.data.sh)):((t=createTag("div")).style.width=this.data.sw+"px",t.style.height=this.data.sh+"px",t.style.backgroundColor=this.data.sc),this.layerElement.appendChild(t)},extendPrototype([BaseElement,TransformElement,HSolidElement,SVGShapeElement,HBaseElement,HierarchyElement,FrameElement,RenderableElement],HShapeElement),HShapeElement.prototype._renderShapeFrame=HShapeElement.prototype.renderInnerContent,HShapeElement.prototype.createContent=function(){var t;if(this.baseElement.style.fontSize=0,this.data.hasMask)this.layerElement.appendChild(this.shapesContainer),t=this.svgElement;else{t=createNS("svg");var e=this.comp.data?this.comp.data:this.globalData.compSize;t.setAttribute("width",e.w),t.setAttribute("height",e.h),t.appendChild(this.shapesContainer),this.layerElement.appendChild(t)}this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.shapesContainer,0,[],!0),this.filterUniqueShapes(),this.shapeCont=t},HShapeElement.prototype.getTransformedPoint=function(t,e){var r,i=t.length;for(r=0;r0&&o<1&&f[m].push(this.calculateF(o,t,e,r,i,m)):(h=a*a-4*n*s)>=0&&((l=(-a+bmSqrt(h))/(2*s))>0&&l<1&&f[m].push(this.calculateF(l,t,e,r,i,m)),(p=(-a-bmSqrt(h))/(2*s))>0&&p<1&&f[m].push(this.calculateF(p,t,e,r,i,m))));this.shapeBoundingBox.left=bmMin.apply(null,f[0]),this.shapeBoundingBox.top=bmMin.apply(null,f[1]),this.shapeBoundingBox.right=bmMax.apply(null,f[0]),this.shapeBoundingBox.bottom=bmMax.apply(null,f[1])},HShapeElement.prototype.calculateF=function(t,e,r,i,s,a){return bmPow(1-t,3)*e[a]+3*bmPow(1-t,2)*t*r[a]+3*(1-t)*bmPow(t,2)*i[a]+bmPow(t,3)*s[a]},HShapeElement.prototype.calculateBoundingBox=function(t,e){var r,i=t.length;for(r=0;r=t.x+t.width&&this.currentBBox.height+this.currentBBox.y>=t.y+t.height},HShapeElement.prototype.renderInnerContent=function(){if(this._renderShapeFrame(),!this.hidden&&(this._isFirstFrame||this._mdf)){var t=this.tempBoundingBox,e=999999;if(t.x=e,t.xMax=-e,t.y=e,t.yMax=-e,this.calculateBoundingBox(this.itemsData,t),t.width=t.xMax=0;t-=1){var i=this.hierarchy[t].finalTransform.mProp;this.mat.translate(-i.p.v[0],-i.p.v[1],i.p.v[2]),this.mat.rotateX(-i.or.v[0]).rotateY(-i.or.v[1]).rotateZ(i.or.v[2]),this.mat.rotateX(-i.rx.v).rotateY(-i.ry.v).rotateZ(i.rz.v),this.mat.scale(1/i.s.v[0],1/i.s.v[1],1/i.s.v[2]),this.mat.translate(i.a.v[0],i.a.v[1],i.a.v[2])}if(this.p?this.mat.translate(-this.p.v[0],-this.p.v[1],this.p.v[2]):this.mat.translate(-this.px.v,-this.py.v,this.pz.v),this.a){var s;s=this.p?[this.p.v[0]-this.a.v[0],this.p.v[1]-this.a.v[1],this.p.v[2]-this.a.v[2]]:[this.px.v-this.a.v[0],this.py.v-this.a.v[1],this.pz.v-this.a.v[2]];var a=Math.sqrt(Math.pow(s[0],2)+Math.pow(s[1],2)+Math.pow(s[2],2)),n=[s[0]/a,s[1]/a,s[2]/a],o=Math.sqrt(n[2]*n[2]+n[0]*n[0]),h=Math.atan2(n[1],o),l=Math.atan2(n[0],-n[2]);this.mat.rotateY(l).rotateX(-h)}this.mat.rotateX(-this.rx.v).rotateY(-this.ry.v).rotateZ(this.rz.v),this.mat.rotateX(-this.or.v[0]).rotateY(-this.or.v[1]).rotateZ(this.or.v[2]),this.mat.translate(this.globalData.compSize.w/2,this.globalData.compSize.h/2,0),this.mat.translate(0,0,this.pe.v);var p=!this._prevMat.equals(this.mat);if((p||this.pe._mdf)&&this.comp.threeDElements){var f,m,c;for(e=this.comp.threeDElements.length,t=0;t=t)return this.threeDElements[e].perspectiveElem;e+=1}return null},HybridRendererBase.prototype.createThreeDContainer=function(t,e){var r,i,s=createTag("div");styleDiv(s);var a=createTag("div");if(styleDiv(a),"3d"===e){(r=s.style).width=this.globalData.compSize.w+"px",r.height=this.globalData.compSize.h+"px";var n="50% 50%";r.webkitTransformOrigin=n,r.mozTransformOrigin=n,r.transformOrigin=n;var o="matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)";(i=a.style).transform=o,i.webkitTransform=o}s.appendChild(a);var h={container:a,perspectiveElem:s,startPos:t,endPos:t,type:e};return this.threeDElements.push(h),h},HybridRendererBase.prototype.build3dContainers=function(){var t,e,r=this.layers.length,i="";for(t=0;t=0;t-=1)this.resizerElem.appendChild(this.threeDElements[t].perspectiveElem)},HybridRendererBase.prototype.addTo3dContainer=function(t,e){for(var r=0,i=this.threeDElements.length;rn?(t=s/this.globalData.compSize.w,e=s/this.globalData.compSize.w,r=0,i=(a-this.globalData.compSize.h*(s/this.globalData.compSize.w))/2):(t=a/this.globalData.compSize.h,e=a/this.globalData.compSize.h,r=(s-this.globalData.compSize.w*(a/this.globalData.compSize.h))/2,i=0);var o=this.resizerElem.style;o.webkitTransform="matrix3d("+t+",0,0,0,0,"+e+",0,0,0,0,1,0,"+r+","+i+",0,1)",o.transform=o.webkitTransform},HybridRendererBase.prototype.renderFrame=SVGRenderer.prototype.renderFrame,HybridRendererBase.prototype.hide=function(){this.resizerElem.style.display="none"},HybridRendererBase.prototype.show=function(){this.resizerElem.style.display="block"},HybridRendererBase.prototype.initItems=function(){if(this.buildAllItems(),this.camera)this.camera.setup();else{var t,e=this.globalData.compSize.w,r=this.globalData.compSize.h,i=this.threeDElements.length;for(t=0;t=o;)t/=2,e/=2,r>>>=1;return(t+r)/e};return b.int32=function(){return 0|v.g(4)},b.quick=function(){return v.g(4)/4294967296},b.double=b,m(c(v.S),t),(d.pass||u||function(t,r,i,s){return s&&(s.S&&p(s,v),t.state=function(){return p(v,{})}),i?(e.random=t,r):t})(b,g,"global"in d?d.global:this==e,d.state)},m(e.random(),t)}function initialize$2(t){seedRandom([],t)}var propTypes={SHAPE:"shape"};function _typeof(t){return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof(t)}var ExpressionManager=function(){var ob={},Math=BMMath,window=null,document=null,XMLHttpRequest=null,fetch=null,frames=null;function $bm_isInstanceOfArray(t){return t.constructor===Array||t.constructor===Float32Array}function isNumerable(t,e){return"number"===t||"boolean"===t||"string"===t||e instanceof Number}function $bm_neg(t){var e=_typeof(t);if("number"===e||"boolean"===e||t instanceof Number)return-t;if($bm_isInstanceOfArray(t)){var r,i=t.length,s=[];for(r=0;rr){var i=r;r=e,e=i}return Math.min(Math.max(t,e),r)}function radiansToDegrees(t){return t/degToRads}var radians_to_degrees=radiansToDegrees;function degreesToRadians(t){return t*degToRads}var degrees_to_radians=radiansToDegrees,helperLengthArray=[0,0,0,0,0,0];function length(t,e){if("number"==typeof t||t instanceof Number)return e=e||0,Math.abs(t-e);var r;e||(e=helperLengthArray);var i=Math.min(t.length,e.length),s=0;for(r=0;r.5?l/(2-n-o):l/(n+o),n){case i:e=(s-a)/l+(s1&&(r-=1),r<1/6?t+6*(e-t)*r:r<.5?e:r<2/3?t+(e-t)*(2/3-r)*6:t}function hslToRgb(t){var e,r,i,s=t[0],a=t[1],n=t[2];if(0===a)e=n,i=n,r=n;else{var o=n<.5?n*(1+a):n+a-n*a,h=2*n-o;e=hue2rgb(h,o,s+1/3),r=hue2rgb(h,o,s),i=hue2rgb(h,o,s-1/3)}return[e,r,i,t[3]]}function linear(t,e,r,i,s){if(void 0!==i&&void 0!==s||(i=e,s=r,e=0,r=1),r=r)return s;var n,o=r===e?0:(t-e)/(r-e);if(!i.length)return i+(s-i)*o;var h=i.length,l=createTypedArray("float32",h);for(n=0;n1){for(i=0;i1?e=1:e<0&&(e=0);var n=t(e);if($bm_isInstanceOfArray(s)){var o,h=s.length,l=createTypedArray("float32",h);for(o=0;odata.k[e].t&&tdata.k[e+1].t-t?(r=e+2,i=data.k[e+1].t):(r=e+1,i=data.k[e].t);break}}-1===r&&(r=e+1,i=data.k[e].t)}else r=0,i=0;var a={};return a.index=r,a.time=i/elem.comp.globalData.frameRate,a}function key(t){var e,r,i;if(!data.k.length||"number"==typeof data.k[0])throw new Error("The property has no keyframe at index "+t);t-=1,e={time:data.k[t].t/elem.comp.globalData.frameRate,value:[]};var s=Object.prototype.hasOwnProperty.call(data.k[t],"s")?data.k[t].s:data.k[t-1].e;for(i=s.length,r=0;rl.length-1)&&(e=l.length-1),i=p-(s=l[l.length-1-e].t)),"pingpong"===t){if(Math.floor((h-s)/i)%2!=0)return this.getValueAtTime((i-(h-s)%i+s)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var f=this.getValueAtTime(s/this.comp.globalData.frameRate,0),m=this.getValueAtTime(p/this.comp.globalData.frameRate,0),c=this.getValueAtTime(((h-s)%i+s)/this.comp.globalData.frameRate,0),d=Math.floor((h-s)/i);if(this.pv.length){for(n=(o=new Array(f.length)).length,a=0;a=p)return this.pv;if(r?s=p+(i=e?Math.abs(this.elem.comp.globalData.frameRate*e):Math.max(0,this.elem.data.op-p)):((!e||e>l.length-1)&&(e=l.length-1),i=(s=l[e].t)-p),"pingpong"===t){if(Math.floor((p-h)/i)%2==0)return this.getValueAtTime(((p-h)%i+p)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var f=this.getValueAtTime(p/this.comp.globalData.frameRate,0),m=this.getValueAtTime(s/this.comp.globalData.frameRate,0),c=this.getValueAtTime((i-(p-h)%i+p)/this.comp.globalData.frameRate,0),d=Math.floor((p-h)/i)+1;if(this.pv.length){for(n=(o=new Array(f.length)).length,a=0;a1?(s+t-a)/(e-1):1,o=0,h=0;for(r=this.pv.length?createTypedArray("float32",this.pv.length):0;on){var p=o,f=r.c&&o===h-1?0:o+1,m=(n-l)/a[o].addedLength;i=bez.getPointInSegment(r.v[p],r.v[f],r.o[p],r.i[f],m,a[o]);break}l+=a[o].addedLength,o+=1}return i||(i=r.c?[r.v[0][0],r.v[0][1]]:[r.v[r._length-1][0],r.v[r._length-1][1]]),i},vectorOnPath:function(t,e,r){1==t?t=this.v.c:0==t&&(t=.999);var i=this.pointOnPath(t,e),s=this.pointOnPath(t+.001,e),a=s[0]-i[0],n=s[1]-i[1],o=Math.sqrt(Math.pow(a,2)+Math.pow(n,2));return 0===o?[0,0]:"tangent"===r?[a/o,n/o]:[-n/o,a/o]},tangentOnPath:function(t,e){return this.vectorOnPath(t,e,"tangent")},normalOnPath:function(t,e){return this.vectorOnPath(t,e,"normal")},setGroupProperty:expressionHelpers.setGroupProperty,getValueAtTime:expressionHelpers.getStaticValueAtTime},extendPrototype([l],o),extendPrototype([l],h),h.prototype.getValueAtTime=function(t){return this._cachingAtTime||(this._cachingAtTime={shapeValue:shapePool.clone(this.pv),lastIndex:0,lastTime:initialDefaultFrame}),t*=this.elem.globalData.frameRate,(t-=this.offsetTime)!==this._cachingAtTime.lastTime&&(this._cachingAtTime.lastIndex=this._cachingAtTime.lastTime { + let chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''); + let uuid = []; + radix = radix || chars.length; + if (len) { + // 如果指定uuid长度,只是取随机的字符,0|x为位运算,能去掉x的小数位,返回整数位 + for (let i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix]; + } else { + let r; + // rfc4122标准要求返回的uuid中,某些位为固定的字符 + uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'; + uuid[14] = '4'; + + for (let i = 0; i < 36; i++) { + if (!uuid[i]) { + r = 0 | Math.random() * 16; + uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r]; + } + } + } + return uuid.join(''); +} diff --git a/uni_modules/hx-lottie/package.json b/uni_modules/hx-lottie/package.json new file mode 100644 index 0000000..3ee7dcc --- /dev/null +++ b/uni_modules/hx-lottie/package.json @@ -0,0 +1,83 @@ +{ + "id": "hx-lottie", + "displayName": "hx-lottie", + "version": "1.0.0", + "description": "uniapp lottie动画插件, 适配H5, App, 微信小程序, 其他小程序暂未测试", + "keywords": [ + "hx-lottie", + "lottie", + "lottie动画", + "微信lottie" +], + "repository": "", + "engines": { + "HBuilderX": "^3.3.0" + }, + "dcloudext": { + "category": [ + "前端组件", + "通用组件" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://gitee.com/Xiaohuixiong_123/hx-lottie.git" + }, + "uni_modules": { + "dependencies": [], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "n" + }, + "App": { + "app-vue": "y", + "app-nvue": "u" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "u" + }, + "小程序": { + "微信": "y", + "阿里": "u", + "百度": "u", + "字节跳动": "u", + "QQ": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/hx-lottie/readme.md b/uni_modules/hx-lottie/readme.md new file mode 100644 index 0000000..fed1e36 --- /dev/null +++ b/uni_modules/hx-lottie/readme.md @@ -0,0 +1,47 @@ +

hx-lottie 使用说明

+ +## 预览 +[![L8dXn0.gif](https://s1.ax1x.com/2022/04/15/L8dXn0.gif)](https://imgtu.com/i/L8dXn0) + +[![L8wmND.gif](https://s1.ax1x.com/2022/04/15/L8wmND.gif)](https://imgtu.com/i/L8wmND) + +## 使用说明 + +* 引入使用 + + ``` html + + + + ``` + +* 参数说明 + + + | 属性值 | 参数说明 | + |----------|---------------------------| + | loop | 是否循环播放动画(Boolean 默认 true) | + | autoplay | 是否自动播放(Boolean 默认 true) | + | data | 动画数据(Object) | + | path | 动画网络路径 (String) | + +* 方法说名 `组件内方法统一使用 call(funName, args) 调用 +` + 1. 使用示例 + + ```js + // 播放动画 + this.$refs.lottie.call('play') + // 暂停动画 + this.$refs.lottie.call('pause') + ``` + + 1. 说明 `方法与lottie-web 方法保持一致` [详情可参考](http://airbnb.io/lottie/#/web?id=usage) + + | 方法名 | 说明 | + |----------|---------------------| + | play | 播放动画 | + | pause | 暂停动画 | + | stop | 停止动画 | + | setSpeed | 设置动画速度,args = speed | + | … | ... | diff --git a/uni_modules/liu-swipe-action/changelog.md b/uni_modules/liu-swipe-action/changelog.md new file mode 100644 index 0000000..d6addb8 --- /dev/null +++ b/uni_modules/liu-swipe-action/changelog.md @@ -0,0 +1,18 @@ +## 1.0.8(2023-06-26) +优化 +## 1.0.7(2023-06-08) +增加预览二维码 +## 1.0.6(2023-06-08) +增加禁用左滑参数 +## 1.0.5(2023-06-08) +增加禁用参数 +## 1.0.4(2023-05-31) +增加license +## 1.0.3(2023-05-19) +优化代码 +## 1.0.2(2023-05-19) +增加示例代码 +## 1.0.1(2023-05-19) +增加示例 +## 1.0.0(2023-05-19) +初始化发布 diff --git a/uni_modules/liu-swipe-action/components/liu-swipe-action/liu-swipe-action.vue b/uni_modules/liu-swipe-action/components/liu-swipe-action/liu-swipe-action.vue new file mode 100644 index 0000000..117d90b --- /dev/null +++ b/uni_modules/liu-swipe-action/components/liu-swipe-action/liu-swipe-action.vue @@ -0,0 +1,166 @@ + + + + + \ No newline at end of file diff --git a/uni_modules/liu-swipe-action/license.md b/uni_modules/liu-swipe-action/license.md new file mode 100644 index 0000000..029bf39 --- /dev/null +++ b/uni_modules/liu-swipe-action/license.md @@ -0,0 +1,6 @@ +### 1、本插件可免费下载使用; +### 2、未经许可,严禁复制本插件派生同类插件上传插件市场; +### 3、未经许可,严禁在插件市场恶意复制抄袭本插件进行违规获利; +### 4、对本软件的任何使用都必须遵守这些条款,违反这些条款的个人或组织将面临法律追究。 + + diff --git a/uni_modules/liu-swipe-action/package.json b/uni_modules/liu-swipe-action/package.json new file mode 100644 index 0000000..a279182 --- /dev/null +++ b/uni_modules/liu-swipe-action/package.json @@ -0,0 +1,85 @@ +{ + "id": "liu-swipe-action", + "displayName": "滑动操作、左滑删除、滑动删除", + "version": "1.0.8", + "description": "简单好用的滑动操作、左滑删除、滑动删除组件,可自定义样式,源码简单易修改", + "keywords": [ + "滑动操作", + "左滑删除", + "滑动删除", + "滑动", + "列表" + ], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "u" + }, + "App": { + "app-vue": "u", + "app-nvue": "u" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "u", + "IE": "u", + "Edge": "u", + "Firefox": "u", + "Safari": "u" + }, + "小程序": { + "微信": "y", + "阿里": "u", + "百度": "u", + "字节跳动": "u", + "QQ": "u", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/liu-swipe-action/readme.md b/uni_modules/liu-swipe-action/readme.md new file mode 100644 index 0000000..9938916 --- /dev/null +++ b/uni_modules/liu-swipe-action/readme.md @@ -0,0 +1,86 @@ +# liu-watermark适用于uni-app项目的滑动操作、左滑删除、滑动删除组件 +### 本组件目前兼容微信小程序、H5 +### 本组件是简单好用的滑动操作、左滑删除、滑动删除组件,可自定义样式,源码简单易修改 +# --- 扫码预览、关注我们 --- + +## 扫码关注公众号,查看更多插件信息,预览插件效果! + +![](https://uni.ckapi.pro/uniapp/publicize.png) + +### 使用示例 +``` + + + + + +``` +### 如需图文水印可自行修改组件内容 + +### 属性说明 +| 名称 | 类型 | 默认值 | 描述 | +| ----------------------------|--------------- | -------------------- | ---------------| +| index | Number | 0 | 当前列索引 +| disable | Boolean | false | 是否禁用左滑 +| btnList | Array | 默认显示编辑、删除 | 操作按钮数组信息,默认显示编辑、删除,可自定义传入 +| @clickItem | Function | | 点击操作回调事件(返回当前列id和操作按钮id) + diff --git a/uni_modules/lsj-upload/changelog.md b/uni_modules/lsj-upload/changelog.md new file mode 100644 index 0000000..0b19561 --- /dev/null +++ b/uni_modules/lsj-upload/changelog.md @@ -0,0 +1,114 @@ +## 2.2.9(2023-06-01) +优化:将是否多选与count字段解绑(原逻辑是count>1为允许多选),改为新增multiple属性控制是否多选。 +## 2.2.8(2023-06-01) +修复上版本提交时accept测试值未删除导致h5端只能选择图片的问题。 +## 2.2.7(2023-05-06) +应群友建议,当instantly为true时,触发change事件后延迟1000毫秒再自动上传,方便动态修改参数,其实个人还是建议想在change事件动态设置参数的伙伴将instantly设置为false,修改参数后手动调用upload() +## 2.2.6(2023-02-09) +修复多个文件同时选择时返回多次change回调的问题 +## 2.2.5(2022-12-27) +1.修复多选文件时未能正常校验数量的问题; +2.app端与H5端支持单选或多选文件,通过count数量控制,超过1开启多选。 +## 2.2.4(2022-12-27) +1.修复多选文件时未能正常校验数量的问题; +2.app端修复多选只取到第一个文件的问题。 +## 2.2.3(2022-12-06) +修复手动调用show()导致count失效的问题 +## 2.2.2(2022-12-01) +Vue3自行修改兼容 +## 2.2.1(2022-10-19) +修复childId警告提示 +## 2.2.0(2022-10-10) +更新app端webview窗口参数clidId,默认值添加时间戳保证唯一性 +## 2.1.9(2022-07-13) +[修复] app端选择文件后初始化设置的文件列表被清空问题 +## 2.1.8(2022-07-13) +[新增] ref方法初始化文件列表,用于已提交后再次编辑时需带入已上传文件:setFiles(files),可传入数组或Map对象,传入格式请与组件选择返回格式保持一致,且name为必须属性。 +## 2.1.7(2022-07-12) +修复ios端偶现创建webview初始化参数未生效的问题 +## 2.1.6(2022-07-11) +[修复]:修复上个版本更新导致nvue窗口组件不能选择文件的问题; +[新增]: +1.应群友建议(填写禁止格式太多)格式限制formats由原来填写禁止选择的格式改为填写允许被选择的格式; +2.应群友建议(增加上传结束回调事件),上传结束回调事件@uploadEnd +3.如能帮到你请留下你的免费好评,组件使用过程中有问题可以加QQ群交流,至于Map对象怎么使用这类前端基础问题请自行百度 +## 2.1.5(2022-07-01) +app端组件销毁时添加自动销毁webview功能,避免v-if销毁组件的情况控件还能被点击的问题 +## 2.1.4(2022-07-01) +修复小程序端回显问题 +## 2.1.3(2022-06-30) +回调事件返回参数新增path字段(文件临时地址),用于回显 +## 2.1.2(2022-06-16) +修复APP端Tabbar窗口无法选择文件的问题 +## 2.1.1(2022-06-16) +优化: +1.组件优化为允许在v-if中使用; +2.允许option直接在data赋值,不再强制在onRead中初始化; +## 2.1.0(2022-06-13) +h5 pc端更改为单次可多选 +## 2.0.9(2022-06-10) +更新演示内容,部分同学不知道怎么获取服务端返回的数据 +## 2.0.8(2022-06-09) +优化动态更新上传参数函数,具体查看下方说明:动态更新参数演示 +## 2.0.7(2022-06-07) +新增wxFileType属性,用于小程序端选择附件时可选文件类型 +## 2.0.6(2022-06-07) +修复小程序端真机选择文件提示失败的问题 +## 2.0.5(2022-06-02) +优化小程序端调用hide()后未阻止触发文件选择问题 +## 2.0.4(2022-06-01) +优化APP端选择器初始定位 +## 2.0.3(2022-05-31) +修复nvue窗口选择文件报错问题 +## 2.0.2(2022-05-20) +修复ios端opiton设置过早未传入webview导致不自动上传问题 +## 2.0.1(2022-05-19) +修复APP端子窗口点击选择文件不响应问题 +## 2.0.0(2022-05-18) +此次组件更新至2.0版本,与1.0版本使用上略有差异,已使用1.0的同学请自行斟酌是否需要升级! +部分差异: +一、 2.0新增异步触发上传功能; +二、2.0新增文件批量上传功能; +三、2.0优化option,剔除属性,只保留上传接口所需字段,且允许异步更改option的值; +四、组件增加size(文件大小限制)、count(文件个数限制)、formats(文件后缀限制)、accept(文件类型限制)、instantly(是否立即自动上传)、debug(日志打印)等属性; +五、回调事件取消input事件、callback事件,新增change事件和progress事件; +六、ref事件新增upload事件、clear事件; +七、优化组件代码,show和hide函数改为显示隐藏,不再重复开关webview; + +## 1.2.3(2022-03-22) +修复Demo里传入待完善功能[手动上传属性manual=true]导致不自动上传的问题,手动提交上传待下个版本更新 +## 1.2.2(2022-02-21) +修复上版本APP优化导致H5和小程序端不自动初始化的问题,此次更新仅修复此问题。异步提交功能下个版本更新~ +## 1.2.1(2022-01-25) +QQ1群已满,已开放2群:469580165 +## 1.2.0(2021-12-09) +优化APP端页面中DOM重排后每次需要重新定位的问题 +## 1.1.1(2021-12-09) +优化,与上版本使用方式有改变,请检查后确认是否需要更新,create更名为show, close更名为hide,取消初始化时手动create, 传参方式改为props=>option +## 1.1.0(2021-12-09) +新增refresh方法,用于DOM发生重排时重新定位控件(APP端) +## 1.0.9(2021-07-15) +修复上传进度未同步渲染,直接返回100%的BUG +## 1.0.8(2021-07-12) +修复H5端传入height和width未生效的bug +## 1.0.7(2021-07-07) +修复h5和小程序端上传完成callback未返回fileName字段问题 +## 1.0.6(2021-07-07) +修复h5端提示信息debug +## 1.0.5(2021-06-29) +感谢小伙伴找出bug,上传成功回调success未置为true,已修复 +## 1.0.4(2021-06-28) +新增兼容APP,H5,小程序手动关闭控件,关闭后不再弹出文件选择框,需要重新create再次开启 +## 1.0.3(2021-06-28) +close增加条件编译,除app端外不需要close +## 1.0.2(2021-06-28) +1.修复页面滚动位置后再create控件导致控件位置不正确的问题; +2.修复nvue无法create控件; +3.示例项目新增nvue使用案例; +## 1.0.1(2021-06-28) +因为有的朋友不清楚app端切换tab时应该怎么处理webview,现重新上传一版示例项目,需要做tab切换的朋友可以导入示例项目查看 +## 1.0.0(2021-06-25) +此插件为l-file插件中上传功能改版,更新内容为: +1. 按钮内嵌入页面,不再强制固定底部,可跟随页面滚动 +2.无需再单独弹框点击上传,减去中间层 +3.通过slot自定义按钮样式 diff --git a/uni_modules/lsj-upload/components/lsj-upload/LsjFile.js b/uni_modules/lsj-upload/components/lsj-upload/LsjFile.js new file mode 100644 index 0000000..177b53a --- /dev/null +++ b/uni_modules/lsj-upload/components/lsj-upload/LsjFile.js @@ -0,0 +1,400 @@ +export class LsjFile { + constructor(data) { + this.dom = null; + // files.type = waiting(等待上传)|| loading(上传中)|| success(成功) || fail(失败) + this.files = new Map(); + this.debug = data.debug || false; + this.id = data.id; + this.width = data.width; + this.height = data.height; + this.option = data.option; + this.instantly = data.instantly; + this.prohibited = data.prohibited; + this.onchange = data.onchange; + this.onprogress = data.onprogress; + this.uploadHandle = this._uploadHandle; + // #ifdef MP-WEIXIN + this.uploadHandle = this._uploadHandleWX; + // #endif + } + + + /** + * 创建File节点 + * @param {string}path webview地址 + */ + create(path) { + if (!this.dom) { + // #ifdef H5 + let dom = document.createElement('input'); + dom.type = 'file' + dom.value = '' + dom.style.height = this.height + dom.style.width = this.width + dom.style.position = 'absolute' + dom.style.top = 0 + dom.style.left = 0 + dom.style.right = 0 + dom.style.bottom = 0 + dom.style.opacity = 0 + dom.style.zIndex = 999 + dom.accept = this.prohibited.accept; + if (this.prohibited.multiple) { + dom.multiple = 'multiple'; + } + dom.onchange = event => { + for (let file of event.target.files) { + if (this.files.size >= this.prohibited.count) { + this.toast(`只允许上传${this.prohibited.count}个文件`); + this.dom.value = ''; + break; + } + this.addFile(file); + } + + this._uploadAfter(); + + this.dom.value = ''; + }; + this.dom = dom; + // #endif + + // #ifdef APP-PLUS + let styles = { + top: '-200px', + left: 0, + width: '1px', + height: '200px', + background: 'transparent' + }; + let extras = { + debug: this.debug, + instantly: this.instantly, + prohibited: this.prohibited, + } + this.dom = plus.webview.create(path, this.id, styles,extras); + this.setData(this.option); + this._overrideUrlLoading(); + // #endif + return this.dom; + } + } + + + /** + * 设置上传参数 + * @param {object|string}name 上传参数,支持a.b 和 a[b] + */ + setData() { + let [name,value = ''] = arguments; + if (typeof name === 'object') { + Object.assign(this.option,name); + } + else { + this._setValue(this.option,name,value); + } + + this.debug&&console.log(JSON.stringify(this.option)); + + // #ifdef APP-PLUS + this.dom.evalJS(`vm.setData('${JSON.stringify(this.option)}')`); + // #endif + } + + /** + * 上传 + * @param {string}name 文件名称 + */ + async upload(name='') { + if (!this.option.url) { + throw Error('未设置上传地址'); + } + + // #ifndef APP-PLUS + if (name && this.files.has(name)) { + await this.uploadHandle(this.files.get(name)); + } + else { + for (let item of this.files.values()) { + if (item.type === 'waiting' || item.type === 'fail') { + await this.uploadHandle(item); + } + } + } + // #endif + + // #ifdef APP-PLUS + this.dom&&this.dom.evalJS(`vm.upload('${name}')`); + // #endif + } + + // 选择文件change + addFile(file,isCallChange) { + + let name = file.name; + this.debug&&console.log('文件名称',name,'大小',file.size); + + if (file) { + // 限制文件格式 + let path = ''; + let suffix = name.substring(name.lastIndexOf(".")+1).toLowerCase(); + let formats = this.prohibited.formats.toLowerCase(); + + + // #ifndef MP-WEIXIN + path = URL.createObjectURL(file); + // #endif + // #ifdef MP-WEIXIN + path = file.path; + // #endif + if (formats&&!formats.includes(suffix)) { + this.toast(`不支持上传${suffix.toUpperCase()}格式文件`); + return false; + } + // 限制文件大小 + if (file.size > 1024 * 1024 * Math.abs(this.prohibited.size)) { + this.toast(`附件大小请勿超过${this.prohibited.size}M`) + return false; + } + this.files.set(file.name,{file,path,name: file.name,size: file.size,progress: 0,type: 'waiting'}); + return true; + } + } + + /** + * 移除文件 + * @param {string}name 不传name默认移除所有文件,传入name移除指定name的文件 + */ + clear(name='') { + // #ifdef APP-PLUS + this.dom&&this.dom.evalJS(`vm.clear('${name}')`); + // #endif + + if (!name) { + this.files.clear(); + } + else { + this.files.delete(name); + } + return this.onchange(this.files); + } + + /** + * 提示框 + * @param {string}msg 轻提示内容 + */ + toast(msg) { + uni.showToast({ + title: msg, + icon: 'none' + }); + } + + /** + * 微信小程序选择文件 + * @param {number}count 可选择文件数量 + */ + chooseMessageFile(type,count) { + wx.chooseMessageFile({ + count: count, + type: type, + success: ({ tempFiles }) => { + for (let file of tempFiles) { + this.addFile(file); + } + this._uploadAfter(); + }, + fail: () => { + this.toast(`打开失败`); + } + }) + } + + _copyObject(obj) { + if (typeof obj !== "undefined") { + return JSON.parse(JSON.stringify(obj)); + } else { + return obj; + } + } + + /** + * 自动根据字符串路径设置对象中的值 支持.和[] + * @param {Object} dataObj 数据源 + * @param {String} name 支持a.b 和 a[b] + * @param {String} value 值 + * setValue(dataObj, name, value); + */ + _setValue(dataObj, name, value) { + // 通过正则表达式 查找路径数据 + let dataValue; + if (typeof value === "object") { + dataValue = this._copyObject(value); + } else { + dataValue = value; + } + let regExp = new RegExp("([\\w$]+)|\\[(:\\d)\\]", "g"); + const patten = name.match(regExp); + // 遍历路径 逐级查找 最后一级用于直接赋值 + for (let i = 0; i < patten.length - 1; i++) { + let keyName = patten[i]; + if (typeof dataObj[keyName] !== "object") dataObj[keyName] = {}; + dataObj = dataObj[keyName]; + } + // 最后一级 + dataObj[patten[patten.length - 1]] = dataValue; + this.debug&&console.log('参数更新后',JSON.stringify(this.option)); + } + + _uploadAfter() { + this.onchange(this.files); + setTimeout(()=>{ + this.instantly&&this.upload(); + },1000) + } + + _overrideUrlLoading() { + this.dom.overrideUrlLoading({ mode: 'reject' }, e => { + let {retype,item,files,end} = this._getRequest( + e.url + ); + let _this = this; + switch (retype) { + case 'updateOption': + this.dom.evalJS(`vm.setData('${JSON.stringify(_this.option)}')`); + break + case 'change': + try { + _this.files = new Map([..._this.files,...JSON.parse(unescape(files))]); + } catch (e) { + return console.error('出错了,请检查代码') + } + _this.onchange(_this.files); + break + case 'progress': + try { + item = JSON.parse(unescape(item)); + } catch (e) { + return console.error('出错了,请检查代码') + } + _this._changeFilesItem(item,end); + break + default: + break + } + }) + } + + _getRequest(url) { + let theRequest = new Object() + let index = url.indexOf('?') + if (index != -1) { + let str = url.substring(index + 1) + let strs = str.split('&') + for (let i = 0; i < strs.length; i++) { + theRequest[strs[i].split('=')[0]] = unescape(strs[i].split('=')[1]) + } + } + return theRequest + } + + _changeFilesItem(item,end=false) { + this.debug&&console.log('onprogress',JSON.stringify(item)); + this.onprogress(item,end); + this.files.set(item.name,item); + } + + _uploadHandle(item) { + item.type = 'loading'; + delete item.responseText; + return new Promise((resolve,reject)=>{ + this.debug&&console.log('option',JSON.stringify(this.option)); + let {url,name,method='POST',header,formData} = this.option; + let form = new FormData(); + for (let keys in formData) { + form.append(keys, formData[keys]) + } + form.append(name, item.file); + let xmlRequest = new XMLHttpRequest(); + xmlRequest.open(method, url, true); + for (let keys in header) { + xmlRequest.setRequestHeader(keys, header[keys]) + } + + xmlRequest.upload.addEventListener( + 'progress', + event => { + if (event.lengthComputable) { + let progress = Math.ceil((event.loaded * 100) / event.total) + if (progress <= 100) { + item.progress = progress; + this._changeFilesItem(item); + } + } + }, + false + ); + + xmlRequest.ontimeout = () => { + console.error('请求超时') + item.type = 'fail'; + this._changeFilesItem(item,true); + return resolve(false); + } + + xmlRequest.onreadystatechange = ev => { + if (xmlRequest.readyState == 4) { + if (xmlRequest.status == 200) { + this.debug&&console.log('上传完成:' + xmlRequest.responseText) + item['responseText'] = xmlRequest.responseText; + item.type = 'success'; + this._changeFilesItem(item,true); + return resolve(true); + } else if (xmlRequest.status == 0) { + console.error('status = 0 :请检查请求头Content-Type与服务端是否匹配,服务端已正确开启跨域,并且nginx未拦截阻止请求') + } + console.error('--ERROR--:status = ' + xmlRequest.status) + item.type = 'fail'; + this._changeFilesItem(item,true); + return resolve(false); + } + } + xmlRequest.send(form) + }); + } + + _uploadHandleWX(item) { + item.type = 'loading'; + delete item.responseText; + return new Promise((resolve,reject)=>{ + this.debug&&console.log('option',JSON.stringify(this.option)); + let form = {filePath: item.file.path,...this.option }; + form['fail'] = ({ errMsg = '' }) => { + console.error('--ERROR--:' + errMsg) + item.type = 'fail'; + this._changeFilesItem(item,true); + return resolve(false); + } + form['success'] = res => { + if (res.statusCode == 200) { + this.debug&&console.log('上传完成,微信端返回不一定是字符串,根据接口返回格式判断是否需要JSON.parse:' + res.data) + item['responseText'] = res.data; + item.type = 'success'; + this._changeFilesItem(item,true); + return resolve(true); + } + item.type = 'fail'; + this._changeFilesItem(item,true); + return resolve(false); + } + + let xmlRequest = uni.uploadFile(form); + xmlRequest.onProgressUpdate(({ progress = 0 }) => { + if (progress <= 100) { + item.progress = progress; + this._changeFilesItem(item); + } + }) + }); + } +} \ No newline at end of file diff --git a/uni_modules/lsj-upload/components/lsj-upload/lsj-upload.vue b/uni_modules/lsj-upload/components/lsj-upload/lsj-upload.vue new file mode 100644 index 0000000..74897f5 --- /dev/null +++ b/uni_modules/lsj-upload/components/lsj-upload/lsj-upload.vue @@ -0,0 +1,321 @@ + + + + + diff --git a/uni_modules/lsj-upload/hybrid/html/js/vue.min.js b/uni_modules/lsj-upload/hybrid/html/js/vue.min.js new file mode 100644 index 0000000..97ac4cf --- /dev/null +++ b/uni_modules/lsj-upload/hybrid/html/js/vue.min.js @@ -0,0 +1,8 @@ +/*! + * Vue.js v2.3.0 + * (c) 2014-2017 Evan You + * Released under the MIT License. + */ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Vue=t()}(this,function(){"use strict";function e(e){return void 0===e||null===e}function t(e){return void 0!==e&&null!==e}function n(e){return!0===e}function r(e){return"string"==typeof e||"number"==typeof e}function i(e){return null!==e&&"object"==typeof e}function o(e){return"[object Object]"===Ai.call(e)}function a(e){return"[object RegExp]"===Ai.call(e)}function s(e){return null==e?"":"object"==typeof e?JSON.stringify(e,null,2):String(e)}function c(e){var t=parseFloat(e);return isNaN(t)?e:t}function u(e,t){for(var n=Object.create(null),r=e.split(","),i=0;i-1)return e.splice(n,1)}}function f(e,t){return Si.call(e,t)}function p(e){var t=Object.create(null);return function(n){return t[n]||(t[n]=e(n))}}function d(e,t){function n(n){var r=arguments.length;return r?r>1?e.apply(t,arguments):e.call(t,n):e.call(t)}return n._length=e.length,n}function v(e,t){t=t||0;for(var n=e.length-t,r=new Array(n);n--;)r[n]=e[n+t];return r}function h(e,t){for(var n in t)e[n]=t[n];return e}function m(e){for(var t={},n=0;n=0&&$o[n].id>e.id;)n--;$o.splice(Math.max(n,Ao)+1,0,e)}else $o.push(e);Co||(Co=!0,ro($e))}}function Ae(e){To.clear(),Oe(e,To)}function Oe(e,t){var n,r,o=Array.isArray(e);if((o||i(e))&&Object.isExtensible(e)){if(e.__ob__){var a=e.__ob__.dep.id;if(t.has(a))return;t.add(a)}if(o)for(n=e.length;n--;)Oe(e[n],t);else for(r=Object.keys(e),n=r.length;n--;)Oe(e[r[n]],t)}}function Se(e,t,n){Eo.get=function(){return this[t][n]},Eo.set=function(e){this[t][n]=e},Object.defineProperty(e,n,Eo)}function Te(e){e._watchers=[];var t=e.$options;t.props&&Ee(e,t.props),t.methods&&Me(e,t.methods),t.data?je(e):E(e._data={},!0),t.computed&&Le(e,t.computed),t.watch&&Pe(e,t.watch)}function Ee(e,t){var n=e.$options.propsData||{},r=e._props={},i=e.$options._propKeys=[],o=!e.$parent;lo.shouldConvert=o;for(var a in t)!function(o){i.push(o);var a=U(o,t,n,e);j(r,o,a),o in e||Se(e,"_props",o)}(a);lo.shouldConvert=!0}function je(e){var t=e.$options.data;t=e._data="function"==typeof t?Ne(t,e):t||{},o(t)||(t={});for(var n=Object.keys(t),r=e.$options.props,i=n.length;i--;)r&&f(r,n[i])||$(n[i])||Se(e,"_data",n[i]);E(t,!0)}function Ne(e,t){try{return e.call(t)}catch(e){return C(e,t,"data()"),{}}}function Le(e,t){var n=e._computedWatchers=Object.create(null);for(var r in t){var i=t[r],o="function"==typeof i?i:i.get;n[r]=new So(e,o,g,jo),r in e||Ie(e,r,i)}}function Ie(e,t,n){"function"==typeof n?(Eo.get=De(t),Eo.set=g):(Eo.get=n.get?!1!==n.cache?De(t):n.get:g,Eo.set=n.set?n.set:g),Object.defineProperty(e,t,Eo)}function De(e){return function(){var t=this._computedWatchers&&this._computedWatchers[e];if(t)return t.dirty&&t.evaluate(),oo.target&&t.depend(),t.value}}function Me(e,t){e.$options.props;for(var n in t)e[n]=null==t[n]?g:d(t[n],e)}function Pe(e,t){for(var n in t){var r=t[n];if(Array.isArray(r))for(var i=0;i=0||n.indexOf(e[i])<0)&&r.push(e[i]);return r}return e}function pt(e){this._init(e)}function dt(e){e.use=function(e){if(!e.installed){var t=v(arguments,1);return t.unshift(this),"function"==typeof e.install?e.install.apply(e,t):"function"==typeof e&&e.apply(null,t),e.installed=!0,this}}}function vt(e){e.mixin=function(e){this.options=B(this.options,e)}}function ht(e){e.cid=0;var t=1;e.extend=function(e){e=e||{};var n=this,r=n.cid,i=e._Ctor||(e._Ctor={});if(i[r])return i[r];var o=e.name||n.options.name,a=function(e){this._init(e)};return a.prototype=Object.create(n.prototype),a.prototype.constructor=a,a.cid=t++,a.options=B(n.options,e),a.super=n,a.options.props&&mt(a),a.options.computed&>(a),a.extend=n.extend,a.mixin=n.mixin,a.use=n.use,Di.forEach(function(e){a[e]=n[e]}),o&&(a.options.components[o]=a),a.superOptions=n.options,a.extendOptions=e,a.sealedOptions=h({},a.options),i[r]=a,a}}function mt(e){var t=e.options.props;for(var n in t)Se(e.prototype,"_props",n)}function gt(e){var t=e.options.computed;for(var n in t)Ie(e.prototype,n,t[n])}function yt(e){Di.forEach(function(t){e[t]=function(e,n){return n?("component"===t&&o(n)&&(n.name=n.name||e,n=this.options._base.extend(n)),"directive"===t&&"function"==typeof n&&(n={bind:n,update:n}),this.options[t+"s"][e]=n,n):this.options[t+"s"][e]}})}function _t(e){return e&&(e.Ctor.options.name||e.tag)}function bt(e,t){return"string"==typeof e?e.split(",").indexOf(t)>-1:!!a(e)&&e.test(t)}function $t(e,t,n){for(var r in e){var i=e[r];if(i){var o=_t(i.componentOptions);o&&!n(o)&&(i!==t&&xt(i),e[r]=null)}}}function xt(e){e&&e.componentInstance.$destroy()}function wt(e){for(var n=e.data,r=e,i=e;t(i.componentInstance);)i=i.componentInstance._vnode,i.data&&(n=Ct(i.data,n));for(;t(r=r.parent);)r.data&&(n=Ct(n,r.data));return kt(n)}function Ct(e,n){return{staticClass:At(e.staticClass,n.staticClass),class:t(e.class)?[e.class,n.class]:n.class}}function kt(e){var n=e.class,r=e.staticClass;return t(r)||t(n)?At(r,Ot(n)):""}function At(e,t){return e?t?e+" "+t:e:t||""}function Ot(n){if(e(n))return"";if("string"==typeof n)return n;var r="";if(Array.isArray(n)){for(var o,a=0,s=n.length;a-1?ua[e]=t.constructor===window.HTMLUnknownElement||t.constructor===window.HTMLElement:ua[e]=/HTMLUnknownElement/.test(t.toString())}function Et(e){if("string"==typeof e){var t=document.querySelector(e);return t||document.createElement("div")}return e}function jt(e,t){var n=document.createElement(e);return"select"!==e?n:(t.data&&t.data.attrs&&void 0!==t.data.attrs.multiple&&n.setAttribute("multiple","multiple"),n)}function Nt(e,t){return document.createElementNS(ia[e],t)}function Lt(e){return document.createTextNode(e)}function It(e){return document.createComment(e)}function Dt(e,t,n){e.insertBefore(t,n)}function Mt(e,t){e.removeChild(t)}function Pt(e,t){e.appendChild(t)}function Rt(e){return e.parentNode}function Ft(e){return e.nextSibling}function Bt(e){return e.tagName}function Ht(e,t){e.textContent=t}function Ut(e,t,n){e.setAttribute(t,n)}function Vt(e,t){var n=e.data.ref;if(n){var r=e.context,i=e.componentInstance||e.elm,o=r.$refs;t?Array.isArray(o[n])?l(o[n],i):o[n]===i&&(o[n]=void 0):e.data.refInFor?Array.isArray(o[n])&&o[n].indexOf(i)<0?o[n].push(i):o[n]=[i]:o[n]=i}}function zt(e,n){return e.key===n.key&&e.tag===n.tag&&e.isComment===n.isComment&&t(e.data)===t(n.data)&&Jt(e,n)}function Jt(e,n){if("input"!==e.tag)return!0;var r;return(t(r=e.data)&&t(r=r.attrs)&&r.type)===(t(r=n.data)&&t(r=r.attrs)&&r.type)}function Kt(e,n,r){var i,o,a={};for(i=n;i<=r;++i)o=e[i].key,t(o)&&(a[o]=i);return a}function qt(e,t){(e.data.directives||t.data.directives)&&Wt(e,t)}function Wt(e,t){var n,r,i,o=e===pa,a=t===pa,s=Zt(e.data.directives,e.context),c=Zt(t.data.directives,t.context),u=[],l=[];for(n in c)r=s[n],i=c[n],r?(i.oldValue=r.value,Yt(i,"update",t,e),i.def&&i.def.componentUpdated&&l.push(i)):(Yt(i,"bind",t,e),i.def&&i.def.inserted&&u.push(i));if(u.length){var f=function(){for(var n=0;n=0&&" "===(m=e.charAt(h));h--);m&&_a.test(m)||(l=!0)}}else void 0===o?(v=i+1,o=e.slice(0,i).trim()):t();if(void 0===o?o=e.slice(0,i).trim():0!==v&&t(),a)for(i=0;i=Bo}function gn(e){return 34===e||39===e}function yn(e){var t=1;for(zo=Vo;!mn();)if(e=hn(),gn(e))_n(e);else if(91===e&&t++,93===e&&t--,0===t){Jo=Vo;break}}function _n(e){for(var t=e;!mn()&&(e=hn())!==t;);}function bn(e,t,n){Ko=n;var r=t.value,i=t.modifiers,o=e.tag,a=e.attrsMap.type;if("select"===o)wn(e,r,i);else if("input"===o&&"checkbox"===a)$n(e,r,i);else if("input"===o&&"radio"===a)xn(e,r,i);else if("input"===o||"textarea"===o)Cn(e,r,i);else if(!Pi.isReservedTag(o))return pn(e,r,i),!1;return!0}function $n(e,t,n){var r=n&&n.number,i=ln(e,"value")||"null",o=ln(e,"true-value")||"true",a=ln(e,"false-value")||"false";an(e,"checked","Array.isArray("+t+")?_i("+t+","+i+")>-1"+("true"===o?":("+t+")":":_q("+t+","+o+")")),un(e,$a,"var $$a="+t+",$$el=$event.target,$$c=$$el.checked?("+o+"):("+a+");if(Array.isArray($$a)){var $$v="+(r?"_n("+i+")":i)+",$$i=_i($$a,$$v);if($$c){$$i<0&&("+t+"=$$a.concat($$v))}else{$$i>-1&&("+t+"=$$a.slice(0,$$i).concat($$a.slice($$i+1)))}}else{"+dn(t,"$$c")+"}",null,!0)}function xn(e,t,n){var r=n&&n.number,i=ln(e,"value")||"null";i=r?"_n("+i+")":i,an(e,"checked","_q("+t+","+i+")"),un(e,$a,dn(t,i),null,!0)}function wn(e,t,n){var r=n&&n.number,i='Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = "_value" in o ? o._value : o.value;return '+(r?"_n(val)":"val")+"})",o="var $$selectedVal = "+i+";";o=o+" "+dn(t,"$event.target.multiple ? $$selectedVal : $$selectedVal[0]"),un(e,"change",o,null,!0)}function Cn(e,t,n){var r=e.attrsMap.type,i=n||{},o=i.lazy,a=i.number,s=i.trim,c=!o&&"range"!==r,u=o?"change":"range"===r?ba:"input",l="$event.target.value";s&&(l="$event.target.value.trim()"),a&&(l="_n("+l+")");var f=dn(t,l);c&&(f="if($event.target.composing)return;"+f),an(e,"value","("+t+")"),un(e,u,f,null,!0),(s||a||"number"===r)&&un(e,"blur","$forceUpdate()")}function kn(e){var n;t(e[ba])&&(n=zi?"change":"input",e[n]=[].concat(e[ba],e[n]||[]),delete e[ba]),t(e[$a])&&(n=Zi?"click":"change",e[n]=[].concat(e[$a],e[n]||[]),delete e[$a])}function An(e,t,n,r,i){if(n){var o=t,a=qo;t=function(n){null!==(1===arguments.length?o(n):o.apply(null,arguments))&&On(e,t,r,a)}}qo.addEventListener(e,t,Gi?{capture:r,passive:i}:r)}function On(e,t,n,r){(r||qo).removeEventListener(e,t,n)}function Sn(t,n){if(!e(t.data.on)||!e(n.data.on)){var r=n.data.on||{},i=t.data.on||{};qo=n.elm,kn(r),G(r,i,An,On,n.context)}}function Tn(n,r){if(!e(n.data.domProps)||!e(r.data.domProps)){var i,o,a=r.elm,s=n.data.domProps||{},c=r.data.domProps||{};t(c.__ob__)&&(c=r.data.domProps=h({},c));for(i in s)e(c[i])&&(a[i]="");for(i in c)if(o=c[i],"textContent"!==i&&"innerHTML"!==i||(r.children&&(r.children.length=0),o!==s[i]))if("value"===i){a._value=o;var u=null==o?"":String(o);En(a,r,u)&&(a.value=u)}else a[i]=o}}function En(e,t,n){return!e.composing&&("option"===t.tag||jn(e,n)||Nn(e,n))}function jn(e,t){return document.activeElement!==e&&e.value!==t}function Nn(e,n){var r=e.value,i=e._vModifiers;return t(i)&&i.number||"number"===e.type?c(r)!==c(n):t(i)&&i.trim?r.trim()!==n.trim():r!==n}function Ln(e){var t=In(e.style);return e.staticStyle?h(e.staticStyle,t):t}function In(e){return Array.isArray(e)?m(e):"string"==typeof e?Ca(e):e}function Dn(e,t){var n,r={};if(t)for(var i=e;i.componentInstance;)i=i.componentInstance._vnode,i.data&&(n=Ln(i.data))&&h(r,n);(n=Ln(e.data))&&h(r,n);for(var o=e;o=o.parent;)o.data&&(n=Ln(o.data))&&h(r,n);return r}function Mn(n,r){var i=r.data,o=n.data;if(!(e(i.staticStyle)&&e(i.style)&&e(o.staticStyle)&&e(o.style))){var a,s,c=r.elm,u=o.staticStyle,l=o.normalizedStyle||o.style||{},f=u||l,p=In(r.data.style)||{};r.data.normalizedStyle=t(p.__ob__)?h({},p):p;var d=Dn(r,!0);for(s in f)e(d[s])&&Oa(c,s,"");for(s in d)(a=d[s])!==f[s]&&Oa(c,s,null==a?"":a)}}function Pn(e,t){if(t&&(t=t.trim()))if(e.classList)t.indexOf(" ")>-1?t.split(/\s+/).forEach(function(t){return e.classList.add(t)}):e.classList.add(t);else{var n=" "+(e.getAttribute("class")||"")+" ";n.indexOf(" "+t+" ")<0&&e.setAttribute("class",(n+t).trim())}}function Rn(e,t){if(t&&(t=t.trim()))if(e.classList)t.indexOf(" ")>-1?t.split(/\s+/).forEach(function(t){return e.classList.remove(t)}):e.classList.remove(t);else{for(var n=" "+(e.getAttribute("class")||"")+" ",r=" "+t+" ";n.indexOf(r)>=0;)n=n.replace(r," ");e.setAttribute("class",n.trim())}}function Fn(e){if(e){if("object"==typeof e){var t={};return!1!==e.css&&h(t,ja(e.name||"v")),h(t,e),t}return"string"==typeof e?ja(e):void 0}}function Bn(e){Fa(function(){Fa(e)})}function Hn(e,t){(e._transitionClasses||(e._transitionClasses=[])).push(t),Pn(e,t)}function Un(e,t){e._transitionClasses&&l(e._transitionClasses,t),Rn(e,t)}function Vn(e,t,n){var r=zn(e,t),i=r.type,o=r.timeout,a=r.propCount;if(!i)return n();var s=i===La?Ma:Ra,c=0,u=function(){e.removeEventListener(s,l),n()},l=function(t){t.target===e&&++c>=a&&u()};setTimeout(function(){c0&&(n=La,l=a,f=o.length):t===Ia?u>0&&(n=Ia,l=u,f=c.length):(l=Math.max(a,u),n=l>0?a>u?La:Ia:null,f=n?n===La?o.length:c.length:0),{type:n,timeout:l,propCount:f,hasTransform:n===La&&Ba.test(r[Da+"Property"])}}function Jn(e,t){for(;e.length1}function Yn(e,t){!0!==t.data.show&&qn(t)}function Qn(e,t,n){var r=t.value,i=e.multiple;if(!i||Array.isArray(r)){for(var o,a,s=0,c=e.options.length;s-1,a.selected!==o&&(a.selected=o);else if(y(er(a),r))return void(e.selectedIndex!==s&&(e.selectedIndex=s));i||(e.selectedIndex=-1)}}function Xn(e,t){for(var n=0,r=t.length;n=0&&a[i].lowerCasedTag!==s;i--);else i=0;if(i>=0){for(var c=a.length-1;c>=i;c--)t.end&&t.end(a[c].tag,n,r);a.length=i,o=i&&a[i-1].tag}else"br"===s?t.start&&t.start(e,[],!0,n,r):"p"===s&&(t.start&&t.start(e,[],!1,n,r),t.end&&t.end(e,n,r))}for(var i,o,a=[],s=t.expectHTML,c=t.isUnaryTag||Ni,u=t.canBeLeftOpenTag||Ni,l=0;e;){if(i=e,o&&Ns(o)){var f=o.toLowerCase(),p=Ls[f]||(Ls[f]=new RegExp("([\\s\\S]*?)(]*>)","i")),d=0,v=e.replace(p,function(e,n,r){return d=r.length,Ns(f)||"noscript"===f||(n=n.replace(//g,"$1").replace(//g,"$1")),t.chars&&t.chars(n),""});l+=e.length-v.length,e=v,r(f,l-d,l)}else{var h=e.indexOf("<");if(0===h){if(fs.test(e)){var m=e.indexOf("--\x3e");if(m>=0){n(m+3);continue}}if(ps.test(e)){var g=e.indexOf("]>");if(g>=0){n(g+2);continue}}var y=e.match(ls);if(y){n(y[0].length);continue}var _=e.match(us);if(_){var b=l;n(_[0].length),r(_[1],b,l);continue}var $=function(){var t=e.match(ss);if(t){var r={tagName:t[1],attrs:[],start:l};n(t[0].length);for(var i,o;!(i=e.match(cs))&&(o=e.match(os));)n(o[0].length),r.attrs.push(o);if(i)return r.unarySlash=i[1],n(i[0].length),r.end=l,r}}();if($){!function(e){var n=e.tagName,i=e.unarySlash;s&&("p"===o&&rs(n)&&r(o),u(n)&&o===n&&r(n));for(var l=c(n)||"html"===n&&"head"===o||!!i,f=e.attrs.length,p=new Array(f),d=0;d=0){for(w=e.slice(h);!(us.test(w)||ss.test(w)||fs.test(w)||ps.test(w)||(C=w.indexOf("<",1))<0);)h+=C,w=e.slice(h);x=e.substring(0,h),n(h)}h<0&&(x=e,e=""),t.chars&&x&&t.chars(x)}if(e===i){t.chars&&t.chars(e);break}}r()}function mr(e,t){var n=t?Rs(t):Ps;if(n.test(e)){for(var r,i,o=[],a=n.lastIndex=0;r=n.exec(e);){i=r.index,i>a&&o.push(JSON.stringify(e.slice(a,i)));var s=tn(r[1].trim());o.push("_s("+s+")"),a=i+r[0].length}return a0,Ki=Vi&&Vi.indexOf("edge/")>0,qi=Vi&&Vi.indexOf("android")>0,Wi=Vi&&/iphone|ipad|ipod|ios/.test(Vi),Zi=Vi&&/chrome\/\d+/.test(Vi)&&!Ki,Gi=!1;if(Ui)try{var Yi={};Object.defineProperty(Yi,"passive",{get:function(){Gi=!0}}),window.addEventListener("test-passive",null,Yi)}catch(e){}var Qi,Xi,eo=function(){return void 0===Qi&&(Qi=!Ui&&"undefined"!=typeof global&&"server"===global.process.env.VUE_ENV),Qi},to=Ui&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__,no="undefined"!=typeof Symbol&&k(Symbol)&&"undefined"!=typeof Reflect&&k(Reflect.ownKeys),ro=function(){function e(){r=!1;var e=n.slice(0);n.length=0;for(var t=0;t1?v(n):n;for(var r=v(arguments,1),i=0,o=n.length;i1&&(t[n[0].trim()]=n[1].trim())}}),t}),ka=/^--/,Aa=/\s*!important$/,Oa=function(e,t,n){if(ka.test(t))e.style.setProperty(t,n);else if(Aa.test(n))e.style.setProperty(t,n.replace(Aa,""),"important");else{var r=Ta(t);if(Array.isArray(n))for(var i=0,o=n.length;iv?(f=e(i[g+1])?null:i[g+1].elm,y(n,f,i,d,g,o)):d>g&&b(n,r,p,v)}function w(r,i,o,a){if(r!==i){if(n(i.isStatic)&&n(r.isStatic)&&i.key===r.key&&(n(i.isCloned)||n(i.isOnce)))return i.elm=r.elm,void(i.componentInstance=r.componentInstance);var s,c=i.data;t(c)&&t(s=c.hook)&&t(s=s.prepatch)&&s(r,i);var u=i.elm=r.elm,l=r.children,f=i.children;if(t(c)&&h(i)){for(s=0;s',n.innerHTML.indexOf(t)>0}("\n"," "),ts=u("area,base,br,col,embed,frame,hr,img,input,isindex,keygen,link,meta,param,source,track,wbr"),ns=u("colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr,source"),rs=u("address,article,aside,base,blockquote,body,caption,col,colgroup,dd,details,dialog,div,dl,dt,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,head,header,hgroup,hr,html,legend,li,menuitem,meta,optgroup,option,param,rp,rt,source,style,summary,tbody,td,tfoot,th,thead,title,tr,track"),is=[/"([^"]*)"+/.source,/'([^']*)'+/.source,/([^\s"'=<>`]+)/.source],os=new RegExp("^\\s*"+/([^\s"'<>\/=]+)/.source+"(?:\\s*("+/(?:=)/.source+")\\s*(?:"+is.join("|")+"))?"),as="[a-zA-Z_][\\w\\-\\.]*",ss=new RegExp("^<((?:"+as+"\\:)?"+as+")"),cs=/^\s*(\/?)>/,us=new RegExp("^<\\/((?:"+as+"\\:)?"+as+")[^>]*>"),ls=/^]+>/i,fs=/^ + + + 提示:【path主要用于图片视频类文件回显,他用自行处理】:{{item.path}} + {{item.name}} + 大小:{{item.size}} + 状态:{{item.type}} + 进度:{{item.progress}} + 服务端返回演示:{{item.responseText}} + 重新上传 + 删除 + + + + + + {{item.name}} + 大小:{{item.size}} + 状态:{{item.type}} + 进度:{{item.progress}} + + + + + + + + + + +``` + +--- +* 函数说明 + + +``` javascript +export default { + data() { + return { + // 上传接口参数 + option: { + // 上传服务器地址,需要替换为你的接口地址 + url: 'http://hl.j56.com/dropbox/document/upload', // 该地址非真实路径,需替换为你项目自己的接口地址 + // 上传附件的key + name: 'file', + // 根据你接口需求自定义请求头,默认不要写content-type,让浏览器自适配 + header: { + // 示例参数可删除 + 'Authorization': 'bearer eyJhbGciOiJSUzI1NiIsI', + 'uid': '99', + 'client': 'app', + 'accountid': 'DP', + }, + // 根据你接口需求自定义body参数 + formData: { + // 'orderId': 1000 + } + }, + // 选择文件后是否立即自动上传,true=选择后立即上传 + instantly: true, + // 必传宽高且宽高应与slot宽高保持一致 + width: '180rpx', + height: '180rpx', + // 限制允许上传的格式,空串=不限制,默认为空 + formats: '', + // 文件上传大小限制 + size: 30, + // 文件数量限制 + count: 2, + // 文件回显列表 + files: new Map(), + // 微信小程序Map对象for循环不显示,所以转成普通数组,不要问为什么,我也不知道 + wxFiles: [], + // 是否打印日志 + debug: true, + + + // 演示用 + tabIndex: 0, + list:[], + } + }, + onReady() { + setTimeout(()=>{ + console.log('----演示动态更新参数-----'); + this.$refs['lsjUpload'+this.tabIndex].setData('formData.orderId','动态设置的参数'); + + console.log('以下注释内容为-动态更新参数更多演示,放开后可查看演示效果'); + // 修改option对象的name属性 + // this.$refs.lsjUpload.setData('name','myFile'); + + // 修改option对象的formData内的属性 + // this.$refs.lsjUpload.setData('formData.appid','1111'); + + // 替换option对象的formData + // this.$refs.lsjUpload.setData('formData',{appid:'222'}); + + // option对象的formData新增属性 + // this.$refs.lsjUpload.setData('formData.newkey','新插入到formData的属性'); + + + // ---------演示初始化值,用于已提交后再次编辑时需带入已上传文件------- + // 方式1=传入数组 + // let files1 = [{name: '1.png'},{name: '2.png',}]; + + // 方式2=传入Map对象 + // let files2 = new Map(); + // files2.set('1.png',{name: '1.png'}) + + // 此处调用setFiles设置初始files + // this.$refs.lsjUpload.setFiles(files1); + + // 初始化tab + this.onTab(0); + },2000) + }, + methods: { + // 某文件上传结束回调(成功失败都回调) + onuploadEnd(item) { + console.log(`${item.name}已上传结束,上传状态=${item.type}`); + + // 更新当前窗口状态变化的文件 + this.files.set(item.name,item); + + // ---可删除--演示上传完成后取服务端数据 + if (item['responseText']) { + console.log('演示服务器返回的字符串JSON转Object对象'); + this.files.get(item.name).responseText = JSON.parse(item.responseText); + } + + // 微信小程序Map对象for循环不显示,所以转成普通数组, + // 如果你用不惯Map对象,也可以像这样转普通数组,组件使用Map主要是避免反复文件去重操作 + // #ifdef MP-WEIXIN + this.wxFiles = [...this.files.values()]; + // #endif + + // 强制更新视图 + this.$forceUpdate(); + + + // ---可删除--演示判断是否所有文件均已上传成功 + let isAll = [...this.files.values()].find(item=>item.type!=='success'); + if (!isAll) { + console.log('已全部上传完毕'); + } + else { + console.log(isAll.name+'待上传'); + } + + }, + // 上传进度回调,如果网页上md文档没有渲染出事件名称onprogre,请复制代码的小伙伴自行添加上哈,没有哪个事件是只(item)的 + onprogre(item) { + // 更新当前状态变化的文件 + this.files.set(item.name,item); + + console.log('打印对象',JSON.stringify(this.files.get(item.name))); + // 微信小程序Map对象for循环不显示,所以转成普通数组,不要问为什么,我也不知道 + // #ifdef MP-WEIXIN + this.wxFiles = [...this.files.values()]; + // #endif + + // 强制更新视图 + this.$forceUpdate(); + + }, + // 文件选择回调 + onChange(files) { + console.log('当前选择的文件列表:',JSON.stringify([...files.values()])); + // 更新选择的文件 + this.files = files; + // 强制更新视图 + this.$forceUpdate(); + + // 微信小程序Map对象for循环不显示,所以转成普通数组,不要问为什么,我也不知道 + // #ifdef MP-WEIXIN + this.wxFiles = [...this.files.values()]; + // #endif + + // ---可删除--演示重新定位覆盖层控件 + this.$nextTick(()=>{ + console.log('演示重新定位'); + this.$refs.lsjUpload0.show(); + this.$refs.lsjUpload1.show(); + this.$refs.lsjUpload2.show(); + }); + + }, + // 手动上传 + upload() { + // name=指定文件名,不指定则上传所有type等于waiting和fail的文件 + this.$refs['lsjUpload'+this.tabIndex].upload(); + }, + // 指定上传某个文件 + resetUpload(name) { + this.$refs['lsjUpload'+this.tabIndex].upload(name); + }, + // 移除某个文件 + clear(name) { + // name=指定文件名,不传name默认移除所有文件 + this.$refs['lsjUpload'+this.tabIndex].clear(name); + }, + /** + * ---可删除--演示在组件上方添加新内容DOM变化 + * DOM重排演示,重排后组件内部updated默认会触发show方法,若特殊情况未能触发updated也可以手动调用一次show() + * 什么是DOM重排?自行百度去 + */ + add() { + this.list.push('DOM重排测试'); + }, + /** + * ---可删除--演示Tab切换时覆盖层是否能被点击 + * APP端因为是webview,层级比view高,此时若不希望点击触发选择文件,需要手动调用hide() + * 手动调用hide后,需要调用show()才能恢复覆盖层的点击 + */ + onTab(tabIndex) { + this.$refs.lsjUpload0.hide(); + this.$refs.lsjUpload1.hide(); + + this.tabIndex = tabIndex; + + this.$nextTick(()=>{ + this.$refs['lsjUpload'+this.tabIndex].show(); + }) + + }, + /** + * 打开nvue窗口查看非跟随窗口滚动效果 + */ + open() { + uni.navigateTo({ + url: '/pages/nvue-demo/nvue-demo' + }); + } + } +} + +``` + +## 温馨提示 + +* 文件上传 +0. 如说明表达还不够清楚,不清楚怎么使用可导入完整示例项目运行体验和查看 +1. APP端请优先联调Android,上传成功后再运行iOS端,如iOS返回status=0则需要后端开启允许跨域; +2. header的Content-Type类型需要与服务端要求一致,否则收不到附件(服务端若没有明文规定则可不写,使用默认匹配) +3. 服务端不清楚怎么配置跨域可加群咨询,具体百度~ +4. 欢迎加入QQ讨论群:701468256(已满) +5. 欢迎加入QQ讨论群:469580165(已满) +6. 欢迎加入QQ讨论群:667530868 +7. 若能帮到你还请点亮5颗小星星以作鼓励哈~ +8. 若能帮到你还请点亮5颗小星星以作鼓励哈~ +9. 若能帮到你还请点亮5颗小星星以作鼓励哈~ \ No newline at end of file diff --git a/uni_modules/uni-transition/changelog.md b/uni_modules/uni-transition/changelog.md new file mode 100644 index 0000000..dca8178 --- /dev/null +++ b/uni_modules/uni-transition/changelog.md @@ -0,0 +1,13 @@ +## 1.2.0(2021-07-30) +- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) +## 1.1.1(2021-05-12) +- 新增 示例地址 +- 修复 示例项目缺少组件的Bug +## 1.1.0(2021-04-22) +- 新增 通过方法自定义动画 +- 新增 custom-class 非 NVUE 平台支持自定义 class 定制样式 +- 优化 动画触发逻辑,使动画更流畅 +- 优化 支持单独的动画类型 +- 优化 文档示例 +## 1.0.2(2021-02-05) +- 调整为uni_modules目录规范 diff --git a/uni_modules/uni-transition/components/uni-transition/createAnimation.js b/uni_modules/uni-transition/components/uni-transition/createAnimation.js new file mode 100644 index 0000000..5f54365 --- /dev/null +++ b/uni_modules/uni-transition/components/uni-transition/createAnimation.js @@ -0,0 +1,128 @@ +// const defaultOption = { +// duration: 300, +// timingFunction: 'linear', +// delay: 0, +// transformOrigin: '50% 50% 0' +// } +// #ifdef APP-NVUE +const nvueAnimation = uni.requireNativePlugin('animation') +// #endif +class MPAnimation { + constructor(options, _this) { + this.options = options + this.animation = uni.createAnimation(options) + this.currentStepAnimates = {} + this.next = 0 + this.$ = _this + + } + + _nvuePushAnimates(type, args) { + let aniObj = this.currentStepAnimates[this.next] + let styles = {} + if (!aniObj) { + styles = { + styles: {}, + config: {} + } + } else { + styles = aniObj + } + if (animateTypes1.includes(type)) { + if (!styles.styles.transform) { + styles.styles.transform = '' + } + let unit = '' + if(type === 'rotate'){ + unit = 'deg' + } + styles.styles.transform += `${type}(${args+unit}) ` + } else { + styles.styles[type] = `${args}` + } + this.currentStepAnimates[this.next] = styles + } + _animateRun(styles = {}, config = {}) { + let ref = this.$.$refs['ani'].ref + if (!ref) return + return new Promise((resolve, reject) => { + nvueAnimation.transition(ref, { + styles, + ...config + }, res => { + resolve() + }) + }) + } + + _nvueNextAnimate(animates, step = 0, fn) { + let obj = animates[step] + if (obj) { + let { + styles, + config + } = obj + this._animateRun(styles, config).then(() => { + step += 1 + this._nvueNextAnimate(animates, step, fn) + }) + } else { + this.currentStepAnimates = {} + typeof fn === 'function' && fn() + this.isEnd = true + } + } + + step(config = {}) { + // #ifndef APP-NVUE + this.animation.step(config) + // #endif + // #ifdef APP-NVUE + this.currentStepAnimates[this.next].config = Object.assign({}, this.options, config) + this.currentStepAnimates[this.next].styles.transformOrigin = this.currentStepAnimates[this.next].config.transformOrigin + this.next++ + // #endif + return this + } + + run(fn) { + // #ifndef APP-NVUE + this.$.animationData = this.animation.export() + this.$.timer = setTimeout(() => { + typeof fn === 'function' && fn() + }, this.$.durationTime) + // #endif + // #ifdef APP-NVUE + this.isEnd = false + let ref = this.$.$refs['ani'] && this.$.$refs['ani'].ref + if(!ref) return + this._nvueNextAnimate(this.currentStepAnimates, 0, fn) + this.next = 0 + // #endif + } +} + + +const animateTypes1 = ['matrix', 'matrix3d', 'rotate', 'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'scale', 'scale3d', + 'scaleX', 'scaleY', 'scaleZ', 'skew', 'skewX', 'skewY', 'translate', 'translate3d', 'translateX', 'translateY', + 'translateZ' +] +const animateTypes2 = ['opacity', 'backgroundColor'] +const animateTypes3 = ['width', 'height', 'left', 'right', 'top', 'bottom'] +animateTypes1.concat(animateTypes2, animateTypes3).forEach(type => { + MPAnimation.prototype[type] = function(...args) { + // #ifndef APP-NVUE + this.animation[type](...args) + // #endif + // #ifdef APP-NVUE + this._nvuePushAnimates(type, args) + // #endif + return this + } +}) + +export function createAnimation(option, _this) { + if(!_this) return + clearTimeout(_this.timer) + return new MPAnimation(option, _this) +} diff --git a/uni_modules/uni-transition/components/uni-transition/uni-transition.vue b/uni_modules/uni-transition/components/uni-transition/uni-transition.vue new file mode 100644 index 0000000..69ff9d9 --- /dev/null +++ b/uni_modules/uni-transition/components/uni-transition/uni-transition.vue @@ -0,0 +1,277 @@ + + + + + diff --git a/uni_modules/uni-transition/package.json b/uni_modules/uni-transition/package.json new file mode 100644 index 0000000..0a709c9 --- /dev/null +++ b/uni_modules/uni-transition/package.json @@ -0,0 +1,83 @@ +{ + "id": "uni-transition", + "displayName": "uni-transition 过渡动画", + "version": "1.2.0", + "description": "元素的简单过渡动画", + "keywords": [ + "uni-ui", + "uniui", + "动画", + "过渡", + "过渡动画" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, + "dcloudext": { + "category": [ + "前端组件", + "通用组件" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui" + }, + "uni_modules": { + "dependencies": [], + "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" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uni-transition/readme.md b/uni_modules/uni-transition/readme.md new file mode 100644 index 0000000..1a790cb --- /dev/null +++ b/uni_modules/uni-transition/readme.md @@ -0,0 +1,397 @@ + + +## Transition 过渡动画 +> **组件名:uni-transition** +> 代码块: `uTransition` + + +元素过渡动画 + +> **注意事项** +> 为了避免错误使用,给大家带来不好的开发体验,请在使用组件前仔细阅读下面的注意事项,可以帮你避免一些错误。 +> - 组件需要依赖 `sass` 插件 ,请自行手动安装 +> - rotate 旋转动画不需要填写 deg 单位,在小程序上填写单位动画不会执行 +> - NVUE 下修改宽高动画,不能定位到中心点 +> - 百度小程序下修改宽高 ,可能会影响其他动画,需注意 +> - nvue 不支持 costom-class , 请使用 styles +> - 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 + + +### 安装方式 + +本组件符合[easycom](https://uniapp.dcloud.io/collocation/pages?id=easycom)规范,`HBuilderX 2.5.5`起,只需将本组件导入项目,在页面`template`中即可直接使用,无需在页面中`import`和注册`components`。 + +如需通过`npm`方式使用`uni-ui`组件,另见文档:[https://ext.dcloud.net.cn/plugin?id=55](https://ext.dcloud.net.cn/plugin?id=55) + +### 基本用法 + +在 ``template`` 中使用组件 + +```html + + + +``` + +### 样式覆盖 + +**注意:`nvue` 不支持 `custom-class` 属性 ,需要使用 `styles` 属性进行兼容** + +使用 `custom-class` 属性绑定样式,可以自定义 `uni-transition` 的样式 + +```html + + + + +``` + + +如果使用 `styles` 注意带’-‘连接符的属性需要使用小驼峰写法如:`backgroundColor:red` + +```html + + +``` + +### 自定义动画 +当内置动画类型不能满足需求的时候 ,可以使用 `step()` 和 `run()` 自定义动画,入参以及具体用法参考下方属性说明 + +`init()` 方法可以覆盖默认配置 + + +```html + + + +``` + + +## API + +### Transition Props + +|属性名 |类型 |默认值 |说明 | +|:-: |:-: |:-: |:-:| +|show |Boolean|false |控制组件显示或隐藏 | +|mode-class |Array/String |- |内置过渡动画类型 | +|custom-class |String |- |自定义类名 | +|duration |Number |300 |过渡动画持续时间 | +|styles |Object |- |组件样式,同 css 样式,注意带’-‘连接符的属性需要使用小驼峰写法如:`backgroundColor:red` | + +#### mode-class 内置过渡动画类型说明 +**格式为** :`'fade'` 或者 `['fade','slide-top']` + +|属性名 |说明 | +|:-: |:-: | +|fade |渐隐渐出过渡 | +|slide-top |由上至下过渡 | +|slide-right |由右至左过渡 | +|slide-bottom |由下至上过渡 | +|slide-left |由左至右过渡 | +|zoom-in |由小到大过渡 | +|zoom-out |由大到小过渡 | + +**注意** + +组合使用时,同一种类型相反的过渡动画如(slide-top、slide-bottom)同时使用时,只有最后一个生效 + +### Transition Events + +|事件名 |说明 |返回值 | +|:-: |:-: |:-: | +|click |点击组件触发 |- | +|change |过渡动画结束时触发 | e = {detail:true} | + +### Transition Methons + +|方法名|说明|参数| +|:-:|:-:|:-:| +|init()|手动初始化配置|Function(OBJECT:config)| +|step()|动画队列|Function(OBJECT:type,OBJECT:config)| +|run()|执行动画|Function(FUNCTION:callback) | + +### init(OBJECT:config) +**通过 ref 调用方法** + +手动设置动画配置,需要在页面渲染完毕后调用 + +```javascript +this.$refs.ani.init({ + duration: 1000, + timingFunction:'ease', + delay:500, + transformOrigin:'left center' +}) +``` + +### step(OBJECT:type,OBJECT:config) 动画队列 +**通过 ref 调用方法** + +调用 `step()` 来表示一组动画完成,`step` 第一个参数可以传入任意多个动画方法,一组动画中的所有动画会同时开始,一组动画完成后才会进行下一组动画。`step` 第二个参数可以传入一个跟 `uni.createAnimation()` 一样的配置参数用于指定当前组动画的配置。 + +Tips +- 第一个参数支持的动画参考下面的 `支持的动画` +- 第二个参数参考下面的 `动画配置`,可省略,如果省略继承`init`的配置 + + +```javascript +this.$refs.ani.step({ + translateX: '100px' +},{ + duration: 1000, + timingFunction:'ease', + delay:500, + transformOrigin:'left center' +}) +``` + +### run(FUNCTION:callback) 执行动画 +**通过 ref 调用方法** + +在执行 `step()` 后,需要调用 `run()` 来运行动画 ,否则动画会一直等待 + +`run()` 方法可以传入一个 `callback` 函数 ,会在所有动画执行完毕后回调 + +```javascript +this.$refs.ani.step({ + translateX: '100px' +}) +this.$refs.ani.run(()=>{ + // console.log('动画执行完毕') +}) + +``` + +### 动画配置 +动画配置 , `init()` 与 `step()` 第二个参数配置相同 ,如果配置`step() `第二个参数,将会覆盖 `init()` 的配置 + +|属性名|值|必填|默认值|说明|平台差异| +|:-:|:-:|:-:|:-:|:-:|:-:| +|duration|Number|否|400|动画持续时间,单位ms|-| +|timingFunction|String|否|"linear"|定义动画的效果|-| +|delay|Number|否|0|动画延迟时间,单位 ms|-| +|needLayout|Boolean|否|false |动画执行是否影响布局|仅 nvue 支持| +|transformOrigin|String |否|"center center"|设置 [transform-origin](https://developer.mozilla.org/en-US/docs/Web/CSS/transform-origin)|-| + + +### timingFunction 属性说明 + +|值|说明|平台差异| +|:-:|:-:|:-:| +|linear|动画从头到尾的速度是相同的|-| +|ease|动画以低速开始,然后加快,在结束前变慢|-| +|ease-in| 动画以低速开始|-| +|ease-in-out| 动画以低速开始和结束|-| +|ease-out|动画以低速结束|-| +|step-start|动画第一帧就跳至结束状态直到结束|nvue不支持| +|step-end|动画一直保持开始状态,最后一帧跳到结束状态|nvue不支持| + +```javascript +// init 配置 +this.$refs.ani.init({ + duration: 1000, + timingFunction:'ease', + delay:500, + transformOrigin:'left center' +}) +// step 配置 +this.$refs.ani.step({ + translateX: '100px' +},{ + duration: 1000, + timingFunction:'ease', + delay:500, + transformOrigin:'left center' +}) +``` + +### 支持的动画 +动画方法 + +如果同一个动画方法有多个值,多个值使用数组分隔 + +```javascript +this.$refs.ani.step({ + width:'100px', + scale: [1.2,0.8], +}) +``` + +**样式:** + +|属性名|值|说明|平台差异| +|:-:|:-:|:-:|:-:| +|opacity|value|透明度,参数范围 0~1|-| +|backgroundColor|color|颜色值|-| +|width|length|长度值,如果传入 Number 则默认使用 px,可传入其他自定义单位的长度值|-| +|height|length|长度值,如果传入 Number 则默认使用 px,可传入其他自定义单位的长度值|-| +|top|length|长度值,如果传入 Number 则默认使用 px,可传入其他自定义单位的长度值|nvue 不支持| +|left|length|长度值,如果传入 Number 则默认使用 px,可传入其他自定义单位的长度值|nvue 不支持| +|bottom|length|长度值,如果传入 Number 则默认使用 px,可传入其他自定义单位的长度值|nvue 不支持| +|right|length|长度值,如果传入 Number 则默认使用 px,可传入其他自定义单位的长度值|nvue 不支持| + +```javascript +this.$refs.ani.step({ + opacity: 1, + backgroundColor: '#ff5a5f', + widht:'100px', + height:'50rpx', +}) +``` + +**旋转:** + +旋转属性的值不需要填写单位 + +|属性名|值|说明|平台差异 | +|:-:|:-:|:-:|:-:| +|rotate|deg|deg的范围-180~180,从原点顺时针旋转一个deg角度 |-| +|rotateX|deg|deg的范围-180~180,在X轴旋转一个deg角度 |-| +|rotateY|deg|deg的范围-180~180,在Y轴旋转一个deg角度 |-| +|rotateZ|deg|deg的范围-180~180,在Z轴旋转一个deg角度 |nvue不支持| +|rotate3d|x,y,z,deg| 同 [transform-function rotate3d](https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/rotate3d()) |nvue不支持| + +```javascript +this.$refs.ani.step({ + rotateX: 45, + rotateY: 45 +}) +``` + +**缩放:** + +|属性名|值|说明|平台差异| +|:-:|:-:|:-: |:-:| +|scale|sx,[sy]|一个参数时,表示在X轴、Y轴同时缩放sx倍数;两个参数时表示在X轴缩放sx倍数,在Y轴缩放sy倍数|-| +|scaleX|sx|在X轴缩放sx倍数|-| +|scaleY|sy|在Y轴缩放sy倍数|-| +|scaleZ|sz|在Z轴缩放sy倍数|nvue不支持| +|scale3d|sx,sy,sz|在X轴缩放sx倍数,在Y轴缩放sy倍数,在Z轴缩放sz倍数|nvue不支持| + +```javascript +this.$refs.ani.step({ + scale: [1.2,0.8] +}) +``` + +**偏移:** + +|属性名|值|说明|平台差异| +|:-:|:-:|:-:|:-:| +|translate|tx,[ty]|一个参数时,表示在X轴偏移tx,单位px;两个参数时,表示在X轴偏移tx,在Y轴偏移ty,单位px。|-| +|translateX|tx| 在X轴偏移tx,单位px|-| +|translateY|ty| 在Y轴偏移tx,单位px|-| +|translateZ|tz| 在Z轴偏移tx,单位px|nvue不支持| +|translate3d|tx,ty,tz| 在X轴偏移tx,在Y轴偏移ty,在Z轴偏移tz,单位px|nvue不支持| + +```javascript +this.$refs.ani.step({ + translateX: '100px' +}) +``` + + + +## 组件示例 + +点击查看:[https://hellouniapp.dcloud.net.cn/pages/extUI/transition/transition](https://hellouniapp.dcloud.net.cn/pages/extUI/transition/transition) \ No newline at end of file diff --git a/uni_modules/uv-icon/changelog.md b/uni_modules/uv-icon/changelog.md new file mode 100644 index 0000000..f641801 --- /dev/null +++ b/uni_modules/uv-icon/changelog.md @@ -0,0 +1,27 @@ +## 1.0.11(2023-10-29) +1. imgMode默认值改成aspectFit +## 1.0.10(2023-08-13) +1. 优化nvue,方便自定义图标 +## 1.0.9(2023-07-28) +1. 修改几个对应错误图标的BUG +## 1.0.8(2023-07-24) +1. 优化 支持base64图片 +## 1.0.7(2023-07-17) +1. 修复 uv-icon 恢复uv-empty相关的图标 +## 1.0.6(2023-07-13) +1. 修复icon设置name属性对应图标错误的BUG +## 1.0.5(2023-07-04) +1. 更新图标,删除一些不常用的图标 +2. 删除base64,修改成ttf文件引入读取图标 +3. 自定义图标文档说明:https://www.uvui.cn/guide/customIcon.html +## 1.0.4(2023-07-03) +1. 修复主题颜色在APP不生效的BUG +## 1.0.3(2023-05-24) +1. 将线上ttf字体包替换成base64,避免加载时或者网络差时候显示白色方块 +## 1.0.2(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.1(2023-05-10) +1. 修复小程序中异常显示 +## 1.0.0(2023-05-04) +新发版 diff --git a/uni_modules/uv-icon/components/uv-icon/icons.js b/uni_modules/uv-icon/components/uv-icon/icons.js new file mode 100644 index 0000000..8469a2d --- /dev/null +++ b/uni_modules/uv-icon/components/uv-icon/icons.js @@ -0,0 +1,160 @@ +export default { + 'uvicon-level': 'e68f', + 'uvicon-checkbox-mark': 'e659', + 'uvicon-folder': 'e694', + 'uvicon-movie': 'e67c', + 'uvicon-star-fill': 'e61e', + 'uvicon-star': 'e618', + 'uvicon-phone-fill': 'e6ac', + 'uvicon-phone': 'e6ba', + 'uvicon-apple-fill': 'e635', + 'uvicon-backspace': 'e64d', + 'uvicon-attach': 'e640', + 'uvicon-empty-data': 'e671', + 'uvicon-empty-address': 'e68a', + 'uvicon-empty-favor': 'e662', + 'uvicon-empty-car': 'e657', + 'uvicon-empty-order': 'e66b', + 'uvicon-empty-list': 'e672', + 'uvicon-empty-search': 'e677', + 'uvicon-empty-permission': 'e67d', + 'uvicon-empty-news': 'e67e', + 'uvicon-empty-history': 'e685', + 'uvicon-empty-coupon': 'e69b', + 'uvicon-empty-page': 'e60e', + 'uvicon-empty-wifi-off': 'e6cc', + 'uvicon-reload': 'e627', + 'uvicon-order': 'e695', + 'uvicon-server-man': 'e601', + 'uvicon-search': 'e632', + 'uvicon-more-dot-fill': 'e66f', + 'uvicon-scan': 'e631', + 'uvicon-map': 'e665', + 'uvicon-map-fill': 'e6a8', + 'uvicon-tags': 'e621', + 'uvicon-tags-fill': 'e613', + 'uvicon-eye': 'e664', + 'uvicon-eye-fill': 'e697', + 'uvicon-eye-off': 'e69c', + 'uvicon-eye-off-outline': 'e688', + 'uvicon-mic': 'e66d', + 'uvicon-mic-off': 'e691', + 'uvicon-calendar': 'e65c', + 'uvicon-trash': 'e623', + 'uvicon-trash-fill': 'e6ce', + 'uvicon-play-left': 'e6bf', + 'uvicon-play-right': 'e6b3', + 'uvicon-minus': 'e614', + 'uvicon-plus': 'e625', + 'uvicon-info-circle': 'e69f', + 'uvicon-info-circle-fill': 'e6a7', + 'uvicon-question-circle': 'e622', + 'uvicon-question-circle-fill': 'e6bc', + 'uvicon-close': 'e65a', + 'uvicon-checkmark': 'e64a', + 'uvicon-checkmark-circle': 'e643', + 'uvicon-checkmark-circle-fill': 'e668', + 'uvicon-setting': 'e602', + 'uvicon-setting-fill': 'e6d0', + 'uvicon-heart': 'e6a2', + 'uvicon-heart-fill': 'e68b', + 'uvicon-camera': 'e642', + 'uvicon-camera-fill': 'e650', + 'uvicon-more-circle': 'e69e', + 'uvicon-more-circle-fill': 'e684', + 'uvicon-chat': 'e656', + 'uvicon-chat-fill': 'e63f', + 'uvicon-bag': 'e647', + 'uvicon-error-circle': 'e66e', + 'uvicon-error-circle-fill': 'e655', + 'uvicon-close-circle': 'e64e', + 'uvicon-close-circle-fill': 'e666', + 'uvicon-share': 'e629', + 'uvicon-share-fill': 'e6bb', + 'uvicon-share-square': 'e6c4', + 'uvicon-shopping-cart': 'e6cb', + 'uvicon-shopping-cart-fill': 'e630', + 'uvicon-bell': 'e651', + 'uvicon-bell-fill': 'e604', + 'uvicon-list': 'e690', + 'uvicon-list-dot': 'e6a9', + 'uvicon-zhifubao-circle-fill': 'e617', + 'uvicon-weixin-circle-fill': 'e6cd', + 'uvicon-weixin-fill': 'e620', + 'uvicon-qq-fill': 'e608', + 'uvicon-qq-circle-fill': 'e6b9', + 'uvicon-moments-circel-fill': 'e6c2', + 'uvicon-moments': 'e6a0', + 'uvicon-car': 'e64f', + 'uvicon-car-fill': 'e648', + 'uvicon-warning-fill': 'e6c7', + 'uvicon-warning': 'e6c1', + 'uvicon-clock-fill': 'e64b', + 'uvicon-clock': 'e66c', + 'uvicon-edit-pen': 'e65d', + 'uvicon-edit-pen-fill': 'e679', + 'uvicon-email': 'e673', + 'uvicon-email-fill': 'e683', + 'uvicon-minus-circle': 'e6a5', + 'uvicon-plus-circle': 'e603', + 'uvicon-plus-circle-fill': 'e611', + 'uvicon-file-text': 'e687', + 'uvicon-file-text-fill': 'e67f', + 'uvicon-pushpin': 'e6d1', + 'uvicon-pushpin-fill': 'e6b6', + 'uvicon-grid': 'e68c', + 'uvicon-grid-fill': 'e698', + 'uvicon-play-circle': 'e6af', + 'uvicon-play-circle-fill': 'e62a', + 'uvicon-pause-circle-fill': 'e60c', + 'uvicon-pause': 'e61c', + 'uvicon-pause-circle': 'e696', + 'uvicon-gift-fill': 'e6b0', + 'uvicon-gift': 'e680', + 'uvicon-kefu-ermai': 'e660', + 'uvicon-server-fill': 'e610', + 'uvicon-coupon-fill': 'e64c', + 'uvicon-coupon': 'e65f', + 'uvicon-integral': 'e693', + 'uvicon-integral-fill': 'e6b1', + 'uvicon-home-fill': 'e68e', + 'uvicon-home': 'e67b', + 'uvicon-account': 'e63a', + 'uvicon-account-fill': 'e653', + 'uvicon-thumb-down-fill': 'e628', + 'uvicon-thumb-down': 'e60a', + 'uvicon-thumb-up': 'e612', + 'uvicon-thumb-up-fill': 'e62c', + 'uvicon-lock-fill': 'e6a6', + 'uvicon-lock-open': 'e68d', + 'uvicon-lock-opened-fill': 'e6a1', + 'uvicon-lock': 'e69d', + 'uvicon-red-packet': 'e6c3', + 'uvicon-photo-fill': 'e6b4', + 'uvicon-photo': 'e60d', + 'uvicon-volume-off-fill': 'e6c8', + 'uvicon-volume-off': 'e6bd', + 'uvicon-volume-fill': 'e624', + 'uvicon-volume': 'e605', + 'uvicon-download': 'e670', + 'uvicon-arrow-up-fill': 'e636', + 'uvicon-arrow-down-fill': 'e638', + 'uvicon-play-left-fill': 'e6ae', + 'uvicon-play-right-fill': 'e6ad', + 'uvicon-arrow-downward': 'e634', + 'uvicon-arrow-leftward': 'e63b', + 'uvicon-arrow-rightward': 'e644', + 'uvicon-arrow-upward': 'e641', + 'uvicon-arrow-down': 'e63e', + 'uvicon-arrow-right': 'e63c', + 'uvicon-arrow-left': 'e646', + 'uvicon-arrow-up': 'e633', + 'uvicon-skip-back-left': 'e6c5', + 'uvicon-skip-forward-right': 'e61f', + 'uvicon-arrow-left-double': 'e637', + 'uvicon-man': 'e675', + 'uvicon-woman': 'e626', + 'uvicon-en': 'e6b8', + 'uvicon-twitte': 'e607', + 'uvicon-twitter-circle-fill': 'e6cf' +} \ No newline at end of file diff --git a/uni_modules/uv-icon/components/uv-icon/props.js b/uni_modules/uv-icon/components/uv-icon/props.js new file mode 100644 index 0000000..7668cf9 --- /dev/null +++ b/uni_modules/uv-icon/components/uv-icon/props.js @@ -0,0 +1,90 @@ +export default { + props: { + // 图标类名 + name: { + type: String, + default: '' + }, + // 图标颜色,可接受主题色 + color: { + type: String, + default: '#606266' + }, + // 字体大小,单位px + size: { + type: [String, Number], + default: '16px' + }, + // 是否显示粗体 + bold: { + type: Boolean, + default: false + }, + // 点击图标的时候传递事件出去的index(用于区分点击了哪一个) + index: { + type: [String, Number], + default: null + }, + // 触摸图标时的类名 + hoverClass: { + type: String, + default: '' + }, + // 自定义扩展前缀,方便用户扩展自己的图标库 + customPrefix: { + type: String, + default: 'uvicon' + }, + // 图标右边或者下面的文字 + label: { + type: [String, Number], + default: '' + }, + // label的位置,只能右边或者下边 + labelPos: { + type: String, + default: 'right' + }, + // label的大小 + labelSize: { + type: [String, Number], + default: '15px' + }, + // label的颜色 + labelColor: { + type: String, + default: '#606266' + }, + // label与图标的距离 + space: { + type: [String, Number], + default: '3px' + }, + // 图片的mode + imgMode: { + type: String, + default: 'aspectFit' + }, + // 用于显示图片小图标时,图片的宽度 + width: { + type: [String, Number], + default: '' + }, + // 用于显示图片小图标时,图片的高度 + height: { + type: [String, Number], + default: '' + }, + // 用于解决某些情况下,让图标垂直居中的用途 + top: { + type: [String, Number], + default: 0 + }, + // 是否阻止事件传播 + stop: { + type: Boolean, + default: false + }, + ...uni.$uv?.props?.icon + } +} \ No newline at end of file diff --git a/uni_modules/uv-icon/components/uv-icon/uv-icon.vue b/uni_modules/uv-icon/components/uv-icon/uv-icon.vue new file mode 100644 index 0000000..d61c9e5 --- /dev/null +++ b/uni_modules/uv-icon/components/uv-icon/uv-icon.vue @@ -0,0 +1,226 @@ + + + + + \ No newline at end of file diff --git a/uni_modules/uv-icon/components/uv-icon/uvicons.ttf b/uni_modules/uv-icon/components/uv-icon/uvicons.ttf new file mode 100644 index 0000000..9aedef8 Binary files /dev/null and b/uni_modules/uv-icon/components/uv-icon/uvicons.ttf differ diff --git a/uni_modules/uv-icon/package.json b/uni_modules/uv-icon/package.json new file mode 100644 index 0000000..6bf40e9 --- /dev/null +++ b/uni_modules/uv-icon/package.json @@ -0,0 +1,83 @@ +{ + "id": "uv-icon", + "displayName": "uv-icon 图标 全面兼容vue3+2、app、h5、小程序等多端", + "version": "1.0.11", + "description": "基于字体的图标集,包含了大多数常见场景的图标,支持自定义,支持自定义图片图标等。可自定义颜色、大小。", + "keywords": [ + "uv-ui,uvui,uv-icon,icon,图标,字体图标" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-icon/readme.md b/uni_modules/uv-icon/readme.md new file mode 100644 index 0000000..d526e1a --- /dev/null +++ b/uni_modules/uv-icon/readme.md @@ -0,0 +1,15 @@ +## uv-icon 图标库 + +> **组件名:uv-icon** + +基于字体的图标集,包含了大多数常见场景的图标,支持自定义,支持自定义图片图标等。 + +# 查看文档 + +## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +![image](https://mp-a667b617-c5f1-4a2d-9a54-683a67cff588.cdn.bspapp.com/uv-ui/banner.png) + +#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:官方QQ群 diff --git a/uni_modules/uv-swipe-action/changelog.md b/uni_modules/uv-swipe-action/changelog.md new file mode 100644 index 0000000..508543c --- /dev/null +++ b/uni_modules/uv-swipe-action/changelog.md @@ -0,0 +1,11 @@ +## 1.0.4(2023-10-13) +1. 优化 +## 1.0.3(2023-10-13) +1. unmounted兼容vue3 +## 1.0.2(2023-05-27) +1. 不支持抖音小程序说明 +## 1.0.1(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.0(2023-05-10) +uv-swipe-action 滑动单元格 diff --git a/uni_modules/uv-swipe-action/components/uv-swipe-action-item/index - backup.wxs b/uni_modules/uv-swipe-action/components/uv-swipe-action-item/index - backup.wxs new file mode 100644 index 0000000..3d62784 --- /dev/null +++ b/uni_modules/uv-swipe-action/components/uv-swipe-action-item/index - backup.wxs @@ -0,0 +1,256 @@ +/** + * 此为wxs模块,只支持APP-VUE,微信和QQ小程序以及H5平台 + * wxs内部不支持es6语法,变量只能使用var定义,无法使用解构,箭头函数等特性 + */ + +// 开始触摸 +function touchstart(event, ownerInstance) { + // 触发事件的组件的ComponentDescriptor实例 + var instance = event.instance + // wxs内的局部变量快照,此快照是属于整个组件的,在touchstart和touchmove事件中都能获取到相同的结果 + var state = instance.getState() + if (state.disable) return + var touches = event.touches + // 如果进行的是多指触控,不允许进行操作 + if (touches && touches.length > 1) return + // 标识当前为滑动中状态 + state.moving = true + // 记录触摸开始点的坐标值 + state.startX = touches[0].pageX + state.startY = touches[0].pageY +} + +// 触摸滑动 +function touchmove(event, ownerInstance) { + // 触发事件的组件的ComponentDescriptor实例 + var instance = event.instance + // wxs内的局部变量快照 + var state = instance.getState() + if (state.disabled || !state.moving) return + + var touches = event.touches + var pageX = touches[0].pageX + var pageY = touches[0].pageY + var moveX = pageX - state.startX + var moveY = pageY - state.startY + var buttonsWidth = state.buttonsWidth + + // 移动的X轴距离大于Y轴距离,也即终点与起点位置连线,与X轴夹角小于45度时,禁止页面滚动 + if (Math.abs(moveX) > Math.abs(moveY) || Math.abs(moveX) > state.threshold) { + event.preventDefault() + event.stopPropagation() + } + // 如果移动的X轴距离小于Y轴距离,也即终点位置与起点位置连线,与Y轴夹角小于45度时,认为是页面上下滑动,而不是左右滑动单元格 + if (Math.abs(moveX) < Math.abs(moveY)) return + + // 限制右滑的距离,不允许内容部分往右偏移,右滑会导致X轴偏移值大于0,以此做判断 + // 此处不能直接return,因为滑动过程中会缺失某些关键点坐标,会导致错乱,最好的办法就是 + // 在超出后,设置为0 + if (state.status === 'open') { + // 在开启状态下,向左滑动,需忽略 + if (moveX < 0) moveX = 0 + // 想要收起菜单,最大能移动的距离为按钮的总宽度 + if (moveX > buttonsWidth) moveX = buttonsWidth + // 如果是已经打开了的状态,向左滑动时,移动收起菜单 + moveSwipeAction(-buttonsWidth + moveX, instance, ownerInstance) + } else { + // 关闭状态下,右滑动需忽略 + if (moveX > 0) moveX = 0 + // 滑动的距离不允许超过所有按钮的总宽度,此时只能是左滑,最终设置按钮的总宽度,同时为负数 + if (Math.abs(moveX) > buttonsWidth) moveX = -buttonsWidth + // 只要是在滑过程中,就不断移动菜单的内容部分,从而使隐藏的菜单显示出来 + moveSwipeAction(moveX, instance, ownerInstance) + } +} + +// 触摸结束 +function touchend(event, ownerInstance) { + // 触发事件的组件的ComponentDescriptor实例 + var instance = event.instance + // wxs内的局部变量快照 + var state = instance.getState() + if (!state.moving || state.disabled) return + var touches = event.changedTouches ? event.changedTouches[0] : {} + var pageX = touches.pageX + var pageY = touches.pageY + var moveX = pageX - state.startX + if (state.status === 'open') { + // 在展开的状态下,继续左滑,无需操作 + if (moveX < 0) return + // 在开启状态下,点击一下内容区域,moveX为0,也即没有进行移动,这时执行收起菜单逻辑 + if (moveX === 0) { + return closeSwipeAction(instance, ownerInstance) + } + // 在开启状态下,滑动距离小于阈值,则默认为不关闭,同时恢复原来的打开状态 + if (Math.abs(moveX) < state.threshold) { + openSwipeAction(instance, ownerInstance) + } else { + // 如果滑动距离大于阈值,则执行收起逻辑 + closeSwipeAction(instance, ownerInstance) + } + } else { + // 在关闭的状态下,右滑,无需操作 + if (moveX > 0) return + // 理由同上 + if (Math.abs(moveX) < state.threshold) { + closeSwipeAction(instance, ownerInstance) + } else { + openSwipeAction(instance, ownerInstance) + } + } +} + +// 获取过渡时间 +function getDuration(value) { + if (value.toString().indexOf('s') >= 0) return value + return value > 30 ? value + 'ms' : value + 's' +} + +// 滑动结束时判断滑动的方向 +function getMoveDirection(instance, ownerInstance) { + var state = instance.getState() +} + +// 移动滑动选择器内容区域,同时显示出其隐藏的菜单 +function moveSwipeAction(moveX, instance, ownerInstance) { + var state = instance.getState() + // 获取所有按钮的实例,需要通过它去设置按钮的位移 + var buttons = ownerInstance.selectAllComponents('.uv-swipe-action-item__right__button') + var len = buttons.length + var previewButtonsMoveX = 0 + + // 设置菜单内容部分的偏移 + instance.requestAnimationFrame(function() { + instance.setStyle({ + // 设置translateX的值 + 'transition': 'none', + transform: 'translateX(' + moveX + 'px)', + '-webkit-transform': 'translateX(' + moveX + 'px)' + }) + // 折叠按钮动画 + for (var i = len - 1; i >= 0; i--) { + // 通过比例,得出元素自身该移动的距离 + var translateX = state.buttons[i].width / state.buttonsWidth * moveX + // 最终移动的距离,是通过自身比例算出的距离,再加上在它之前所有按钮移动的距离之和 + var realTranslateX = translateX + previewButtonsMoveX + buttons[i].setStyle({ + // 在移动期间,不能使用过渡效果,否则会造成卡顿,本质原因是每次移动一点,就要花一定时间去过渡这个过程 + 'transition': 'none', + 'transform': 'translateX(' + realTranslateX + 'px)', + '-webkit-transform': 'translateX(' + realTranslateX + 'px)' + }) + // 记录本按钮之前的所有按钮的移动距离之和 + previewButtonsMoveX += translateX + } + }) +} + +// 一次性展开滑动菜单 +function openSwipeAction(instance, ownerInstance) { + var state = instance.getState() + // 获取所有按钮的实例,需要通过它去设置按钮的位移 + var buttons = ownerInstance.selectAllComponents('.uv-swipe-action-item__right__button') + var len = buttons.length + // 处理duration单位问题 + const duration = getDuration(state.duration) + // 展开过程中,是向左移动,所以X的偏移应该为负值 + var buttonsWidth = -state.buttonsWidth + var previewButtonsMoveX = 0 + instance.requestAnimationFrame(function() { + // 设置菜单主体内容 + instance.setStyle({ + 'transition': 'transform ' + duration, + 'transform': 'translateX(' + buttonsWidth + 'px)', + '-webkit-transform': 'translateX(' + buttonsWidth + 'px)', + }) + // 设置各个隐藏的按钮为展开的状态 + for (var i = len - 1; i >= 0; i--) { + // 通过比例,得出元素自身该移动的距离 + var translateX = state.buttons[i].width / state.buttonsWidth * buttonsWidth + // 最终移动的距离,是通过自身比例算出的距离,再加上在它之前所有按钮移动的距离之和 + var realTranslateX = translateX + previewButtonsMoveX + buttons[i].setStyle({ + // 在移动期间,需要加上动画效果 + 'transition': 'transform ' + duration, + 'transform': 'translateX(' + realTranslateX + 'px)', + '-webkit-transform': 'translateX(' + realTranslateX + 'px)' + }) + // 记录本按钮之前的所有按钮的移动距离之和 + previewButtonsMoveX += translateX + } + }) + setStatus('open', instance) +} + +// 标记菜单的当前状态,open-已经打开,close-已经关闭 +function setStatus(status, instance) { + var state = instance.getState() + state.status = status +} + +// 一次性收起滑动菜单 +function closeSwipeAction(instance, ownerInstance) { + var state = instance.getState() + // 获取所有按钮的实例,需要通过它去设置按钮的位移 + var buttons = ownerInstance.selectAllComponents('.uv-swipe-action-item__right__button') + var len = buttons.length + // 处理duration单位问题 + const duration = getDuration(state.duration) + instance.requestAnimationFrame(function() { + // 设置菜单主体内容 + instance.setStyle({ + 'transition': 'transform ' + duration, + 'transform': 'translateX(0px)', + '-webkit-transform': 'translateX(0px)' + }) + // 设置各个隐藏的按钮为收起的状态 + for (var i = len - 1; i >= 0; i--) { + buttons[i].setStyle({ + 'transition': 'transform ' + duration, + 'transform': 'translateX(0px)', + '-webkit-transform': 'translateX(0px)' + }) + } + }) + setStatus('close', instance) +} + +// show的状态发生变化 +function showChange(newValue, oldValue, ownerInstance, instance) { + var state = instance.getState() + if (state.disabled) return + // 打开或关闭单元格 + if (newValue) { + openSwipeAction(instance, ownerInstance) + } else { + closeSwipeAction(instance, ownerInstance) + } +} + +// 菜单尺寸发生变化 +function sizeChange(newValue, oldValue, ownerInstance, instance) { + // wxs内的局部变量快照 + var state = instance.getState() + state.disabled = newValue.disabled + state.duration = newValue.duration + state.show = newValue.show + state.threshold = newValue.threshold + state.buttons = newValue.buttons + + var len = state.buttons.length + if (len) { + var buttonsWidth = 0 + var buttons = newValue.buttons + for (var i = 0; i < len; i++) { + buttonsWidth += buttons[i].width + } + } + state.buttonsWidth = buttonsWidth +} + +module.exports = { + touchstart: touchstart, + touchmove: touchmove, + touchend: touchend, + sizeChange: sizeChange +} diff --git a/uni_modules/uv-swipe-action/components/uv-swipe-action-item/index.wxs b/uni_modules/uv-swipe-action/components/uv-swipe-action-item/index.wxs new file mode 100644 index 0000000..16add56 --- /dev/null +++ b/uni_modules/uv-swipe-action/components/uv-swipe-action-item/index.wxs @@ -0,0 +1,225 @@ +/** + * 此为wxs模块,只支持APP-VUE,微信和QQ小程序以及H5平台 + * wxs内部不支持es6语法,变量只能使用var定义,无法使用解构,箭头函数等特性 + */ + +// 开始触摸 +function touchstart(event, ownerInstance) { + // 触发事件的组件的ComponentDescriptor实例 + var instance = event.instance + // wxs内的局部变量快照,此快照是属于整个组件的,在touchstart和touchmove事件中都能获取到相同的结果 + var state = instance.getState() + if (state.disabled) return + var touches = event.touches + // 如果进行的是多指触控,不允许进行操作 + if (touches && touches.length > 1) return + // 标识当前为滑动中状态 + state.moving = true + // 记录触摸开始点的坐标值 + state.startX = touches[0].pageX + state.startY = touches[0].pageY + + ownerInstance.callMethod('closeOther') +} + +// 触摸滑动 +function touchmove(event, ownerInstance) { + // 触发事件的组件的ComponentDescriptor实例 + var instance = event.instance + // wxs内的局部变量快照 + var state = instance.getState() + if (state.disabled || !state.moving) return + var touches = event.touches + var pageX = touches[0].pageX + var pageY = touches[0].pageY + var moveX = pageX - state.startX + var moveY = pageY - state.startY + var buttonsWidth = state.buttonsWidth + + // 移动的X轴距离大于Y轴距离,也即终点与起点位置连线,与X轴夹角小于45度时,禁止页面滚动 + if (Math.abs(moveX) > Math.abs(moveY) || Math.abs(moveX) > state.threshold) { + event.preventDefault && event.preventDefault() + event.stopPropagation && event.stopPropagation() + } + // 如果移动的X轴距离小于Y轴距离,也即终点位置与起点位置连线,与Y轴夹角小于45度时,认为是页面上下滑动,而不是左右滑动单元格 + if (Math.abs(moveX) < Math.abs(moveY)) return + + // 限制右滑的距离,不允许内容部分往右偏移,右滑会导致X轴偏移值大于0,以此做判断 + // 此处不能直接return,因为滑动过程中会缺失某些关键点坐标,会导致错乱,最好的办法就是 + // 在超出后,设置为0 + if (state.status === 'open') { + // 在开启状态下,向左滑动,需忽略 + if (moveX < 0) moveX = 0 + // 想要收起菜单,最大能移动的距离为按钮的总宽度 + if (moveX > buttonsWidth) moveX = buttonsWidth + // 如果是已经打开了的状态,向左滑动时,移动收起菜单 + moveSwipeAction(-buttonsWidth + moveX, instance, ownerInstance) + } else { + // 关闭状态下,右滑动需忽略 + if (moveX > 0) moveX = 0 + // 滑动的距离不允许超过所有按钮的总宽度,此时只能是左滑,最终设置按钮的总宽度,同时为负数 + if (Math.abs(moveX) > buttonsWidth) moveX = -buttonsWidth + // 只要是在滑过程中,就不断移动单元格内容部分,从而使隐藏的菜单显示出来 + moveSwipeAction(moveX, instance, ownerInstance) + } +} + +// 触摸结束 +function touchend(event, ownerInstance) { + // 触发事件的组件的ComponentDescriptor实例 + var instance = event.instance + // wxs内的局部变量快照 + var state = instance.getState() + if (!state.moving || state.disabled) return + var touches = event.changedTouches ? event.changedTouches[0] : {} + var pageX = touches.pageX + var pageY = touches.pageY + var moveX = pageX - state.startX + if (state.status === 'open') { + // 在展开的状态下,继续左滑,无需操作 + if (moveX < 0) return + // 在开启状态下,点击一下内容区域,moveX为0,也即没有进行移动,这时执行收起菜单逻辑 + if (moveX === 0) { + return closeSwipeAction(instance, ownerInstance) + } + // 在开启状态下,滑动距离小于阈值,则默认为不关闭,同时恢复原来的打开状态 + if (Math.abs(moveX) < state.threshold) { + openSwipeAction(instance, ownerInstance) + } else { + // 如果滑动距离大于阈值,则执行收起逻辑 + closeSwipeAction(instance, ownerInstance) + } + } else { + // 在关闭的状态下,右滑,无需操作 + if (moveX > 0) return + // 理由同上 + if (Math.abs(moveX) < state.threshold) { + closeSwipeAction(instance, ownerInstance) + } else { + openSwipeAction(instance, ownerInstance) + } + } +} + +// 获取过渡时间 +function getDuration(value) { + if (value.toString().indexOf('s') >= 0) return value + return value > 30 ? value + 'ms' : value + 's' +} + +// 滑动结束时判断滑动的方向 +function getMoveDirection(instance, ownerInstance) { + var state = instance.getState() +} + +// 移动滑动选择器内容区域,同时显示出其隐藏的菜单 +function moveSwipeAction(moveX, instance, ownerInstance) { + var state = instance.getState() + // 获取所有按钮的实例,需要通过它去设置按钮的位移 + var buttons = ownerInstance.selectAllComponents('.uv-swipe-action-item__right__button') + + // 设置菜单内容部分的偏移 + instance.requestAnimationFrame(function() { + instance.setStyle({ + // 设置translateX的值 + 'transition': 'none', + transform: 'translateX(' + moveX + 'px)', + '-webkit-transform': 'translateX(' + moveX + 'px)' + }) + }) +} + +// 一次性展开滑动菜单 +function openSwipeAction(instance, ownerInstance) { + var state = instance.getState() + // 获取所有按钮的实例,需要通过它去设置按钮的位移 + var buttons = ownerInstance.selectAllComponents('.uv-swipe-action-item__right__button') + // 处理duration单位问题 + var duration = getDuration(state.duration) + // 展开过程中,是向左移动,所以X的偏移应该为负值 + var buttonsWidth = -state.buttonsWidth + instance.requestAnimationFrame(function() { + // 设置菜单主体内容 + instance.setStyle({ + 'transition': 'transform ' + duration, + 'transform': 'translateX(' + buttonsWidth + 'px)', + '-webkit-transform': 'translateX(' + buttonsWidth + 'px)', + }) + }) + setStatus('open', instance, ownerInstance) +} + +// 标记菜单的当前状态,open-已经打开,close-已经关闭 +function setStatus(status, instance, ownerInstance) { + var state = instance.getState() + state.status = status + ownerInstance.callMethod('setState', status) +} + +// 一次性收起滑动菜单 +function closeSwipeAction(instance, ownerInstance) { + var state = instance.getState() + // 获取所有按钮的实例,需要通过它去设置按钮的位移 + var buttons = ownerInstance.selectAllComponents('.uv-swipe-action-item__right__button') + var len = buttons.length + // 处理duration单位问题 + var duration = getDuration(state.duration) + instance.requestAnimationFrame(function() { + // 设置菜单主体内容 + instance.setStyle({ + 'transition': 'transform ' + duration, + 'transform': 'translateX(0px)', + '-webkit-transform': 'translateX(0px)' + }) + // 设置各个隐藏的按钮为收起的状态 + for (var i = len - 1; i >= 0; i--) { + buttons[i].setStyle({ + 'transition': 'transform ' + duration, + 'transform': 'translateX(0px)', + '-webkit-transform': 'translateX(0px)' + }) + } + }) + setStatus('close', instance, ownerInstance) +} + +// status的状态发生变化 +function statusChange(newValue, oldValue, ownerInstance, instance) { + var state = instance.getState() + if (state.disabled) return + // 打开或关闭单元格 + if (newValue === 'close' && state.status === 'open') { + closeSwipeAction(instance, ownerInstance) + } else if(newValue === 'open' && state.status === 'close') { + openSwipeAction(instance, ownerInstance) + } +} + +// 菜单尺寸发生变化 +function sizeChange(newValue, oldValue, ownerInstance, instance) { + // wxs内的局部变量快照 + var state = instance.getState() + state.disabled = newValue.disabled + state.duration = newValue.duration + state.show = newValue.show + state.threshold = newValue.threshold + state.buttons = newValue.buttons + + if (state.buttons) { + var len = state.buttons.length + var buttonsWidth = 0 + var buttons = newValue.buttons + for (var i = 0; i < len; i++) { + buttonsWidth += buttons[i].width + } + } + state.buttonsWidth = buttonsWidth +} + +module.exports = { + touchstart: touchstart, + touchmove: touchmove, + touchend: touchend, + sizeChange: sizeChange, + statusChange: statusChange +} diff --git a/uni_modules/uv-swipe-action/components/uv-swipe-action-item/nvue - backup.js b/uni_modules/uv-swipe-action/components/uv-swipe-action-item/nvue - backup.js new file mode 100644 index 0000000..da259e8 --- /dev/null +++ b/uni_modules/uv-swipe-action/components/uv-swipe-action-item/nvue - backup.js @@ -0,0 +1,264 @@ +// nvue操作dom的库,用于获取dom的尺寸信息 +const dom = uni.requireNativePlugin('dom') +// nvue中用于操作元素动画的库,类似于uni.animation,只不过uni.animation不能用于nvue +const animation = uni.requireNativePlugin('animation') +import { sleep } from '@/uni_modules/uv-ui-tools/libs/function/index.js' +export default { + data() { + return { + // 是否滑动中 + moving: false, + // 状态,open-打开状态,close-关闭状态 + status: 'close', + // 开始触摸点的X和Y轴坐标 + startX: 0, + startY: 0, + // 所有隐藏按钮的尺寸信息数组 + buttons: [], + // 所有按钮的总宽度 + buttonsWidth: 0, + // 记录上一次移动的位置值 + moveX: 0, + // 记录上一次滑动的位置,用于前后两次做对比,如果移动的距离小于某一阈值,则认为前后之间没有移动,为了解决可能存在的通信阻塞问题 + lastX: 0 + } + }, + computed: { + // 获取过渡时间 + getDuratin() { + let duration = String(this.duration) + // 如果ms为单位,返回ms的数值部分 + if (duration.indexOf('ms') >= 0) return parseInt(duration) + // 如果s为单位,为了得到ms的数值,需要乘以1000 + if (duration.indexOf('s') >= 0) return parseInt(duration) * 1000 + // 如果值传了数值,且小于30,认为是s单位 + duration = Number(duration) + return duration < 30 ? duration * 1000 : duration + } + }, + watch: { + show: { + immediate: true, + handler(n) { + + } + } + }, + mounted() { + sleep(20).then(() => { + this.queryRect() + }) + }, + methods: { + close() { + this.closeSwipeAction() + }, + // 触摸单元格 + touchstart(event) { + if (this.disabled) return + this.closeOther() + const { touches } = event + // 记录触摸开始点的坐标值 + this.startX = touches[0].pageX + this.startY = touches[0].pageY + }, + // // 触摸滑动 + touchmove(event) { + if (this.disabled) return + const { touches } = event + const { pageX } = touches[0] + const { pageY } = touches[0] + let moveX = pageX - this.startX + const moveY = pageY - this.startY + const { buttonsWidth } = this + const len = this.buttons.length + + // 判断前后两次的移动距离,如果小于一定值,则不进行移动处理 + if (Math.abs(pageX - this.lastX) < 0.3) return + this.lastX = pageX + + // 移动的X轴距离大于Y轴距离,也即终点与起点位置连线,与X轴夹角小于45度时,禁止页面滚动 + if (Math.abs(moveX) > Math.abs(moveY) || Math.abs(moveX) > this.threshold) { + event.stopPropagation() + } + // 如果移动的X轴距离小于Y轴距离,也即终点位置与起点位置连线,与Y轴夹角小于45度时,认为是页面上下滑动,而不是左右滑动单元格 + if (Math.abs(moveX) < Math.abs(moveY)) return + + // 限制右滑的距离,不允许内容部分往右偏移,右滑会导致X轴偏移值大于0,以此做判断 + // 此处不能直接return,因为滑动过程中会缺失某些关键点坐标,会导致错乱,最好的办法就是 + // 在超出后,设置为0 + if (this.status === 'open') { + // 在开启状态下,向左滑动,需忽略 + if (moveX < 0) moveX = 0 + // 想要收起菜单,最大能移动的距离为按钮的总宽度 + if (moveX > buttonsWidth) moveX = buttonsWidth + // 如果是已经打开了的状态,向左滑动时,移动收起菜单 + this.moveSwipeAction(-buttonsWidth + moveX) + } else { + // 关闭状态下,右滑动需忽略 + if (moveX > 0) moveX = 0 + // 滑动的距离不允许超过所有按钮的总宽度,此时只能是左滑,最终设置按钮的总宽度,同时为负数 + if (Math.abs(moveX) > buttonsWidth) moveX = -buttonsWidth + // 只要是在滑过程中,就不断移动菜单的内容部分,从而使隐藏的菜单显示出来 + this.moveSwipeAction(moveX) + } + }, + // 单元格结束触摸 + touchend(event) { + if (this.disabled) return + const touches = event.changedTouches ? event.changedTouches[0] : {} + const { pageX } = touches + const { pageY } = touches + const { buttonsWidth } = this + this.moveX = pageX - this.startX + if (this.status === 'open') { + // 在展开的状态下,继续左滑,无需操作 + if (this.moveX < 0) this.moveX = 0 + if (this.moveX > buttonsWidth) this.moveX = buttonsWidth + // 在开启状态下,点击一下内容区域,moveX为0,也即没有进行移动,这时执行收起菜单逻辑 + if (this.moveX === 0) { + return this.closeSwipeAction() + } + // 在开启状态下,滑动距离小于阈值,则默认为不关闭,同时恢复原来的打开状态 + if (Math.abs(this.moveX) < this.threshold) { + this.openSwipeAction() + } else { + // 如果滑动距离大于阈值,则执行收起逻辑 + this.closeSwipeAction() + } + } else { + // 在关闭的状态下,右滑,无需操作 + if (this.moveX >= 0) this.moveX = 0 + if (this.moveX <= -buttonsWidth) this.moveX = -buttonsWidth + // 理由同上 + if (Math.abs(this.moveX) < this.threshold) { + this.closeSwipeAction() + } else { + this.openSwipeAction() + } + } + }, + // 移动滑动选择器内容区域,同时显示出其隐藏的菜单 + moveSwipeAction(moveX) { + if (this.moving) return + this.moving = true + + let previewButtonsMoveX = 0 + const len = this.buttons.length + animation.transition(this.$refs['uv-swipe-action-item__content'].ref, { + styles: { + transform: `translateX(${moveX}px)` + }, + timingFunction: 'linear' + }, () => { + this.moving = false + }) + // 按钮的组的长度 + for (let i = len - 1; i >= 0; i--) { + const buttonRef = this.$refs[`uv-swipe-action-item__right__button-${i}`][0].ref + // 通过比例,得出元素自身该移动的距离 + const translateX = this.buttons[i].width / this.buttonsWidth * moveX + // 最终移动的距离,是通过自身比例算出的距离,再加上在它之前所有按钮移动的距离之和 + const realTranslateX = translateX + previewButtonsMoveX + animation.transition(buttonRef, { + styles: { + transform: `translateX(${realTranslateX}px)` + }, + duration: 0, + delay: 0, + timingFunction: 'linear' + }, () => {}) + // 记录本按钮之前的所有按钮的移动距离之和 + previewButtonsMoveX += translateX + } + }, + // 关闭菜单 + closeSwipeAction() { + if (this.status === 'close') return + this.moving = true + const { buttonsWidth } = this + animation.transition(this.$refs['uv-swipe-action-item__content'].ref, { + styles: { + transform: 'translateX(0px)' + }, + duration: this.getDuratin, + timingFunction: 'ease-in-out' + }, () => { + this.status = 'close' + this.moving = false + this.closeHandler() + }) + // 按钮的组的长度 + const len = this.buttons.length + for (let i = len - 1; i >= 0; i--) { + const buttonRef = this.$refs[`uv-swipe-action-item__right__button-${i}`][0].ref + // 如果不满足边界条件,返回 + if (this.buttons.length === 0 || !this.buttons[i] || !this.buttons[i].width) return + + animation.transition(buttonRef, { + styles: { + transform: 'translateX(0px)' + }, + duration: this.getDuratin, + timingFunction: 'ease-in-out' + }, () => {}) + } + }, + // 打开菜单 + openSwipeAction() { + if (this.status === 'open') return + this.moving = true + const buttonsWidth = -this.buttonsWidth + let previewButtonsMoveX = 0 + animation.transition(this.$refs['uv-swipe-action-item__content'].ref, { + styles: { + transform: `translateX(${buttonsWidth}px)` + }, + duration: this.getDuratin, + timingFunction: 'ease-in-out' + }, () => { + this.status = 'open' + this.moving = false + this.openHandler() + }) + // 按钮的组的长度 + const len = this.buttons.length + for (let i = len - 1; i >= 0; i--) { + const buttonRef = this.$refs[`uv-swipe-action-item__right__button-${i}`][0].ref + // 如果不满足边界条件,返回 + if (this.buttons.length === 0 || !this.buttons[i] || !this.buttons[i].width) return + // 通过比例,得出元素自身该移动的距离 + const translateX = this.buttons[i].width / this.buttonsWidth * buttonsWidth + // 最终移动的距离,是通过自身比例算出的距离,再加上在它之前所有按钮移动的距离之和 + const realTranslateX = translateX + previewButtonsMoveX + animation.transition(buttonRef, { + styles: { + transform: `translateX(${realTranslateX}px)` + }, + duration: this.getDuratin, + timingFunction: 'ease-in-out' + }, () => {}) + previewButtonsMoveX += translateX + } + }, + // 查询按钮节点信息 + queryRect() { + // 历遍所有按钮数组,通过getRectByDom返回一个promise + const promiseAll = this.rightOptions.map((item, index) => this.getRectByDom(this.$refs[`uv-swipe-action-item__right__button-${index}`][0])) + // 通过promise.all方法,让所有按钮的查询结果返回一个数组的形式 + Promise.all(promiseAll).then((sizes) => { + this.buttons = sizes + // 计算所有按钮总宽度 + this.buttonsWidth = sizes.reduce((sum, cur) => sum + cur.width, 0) + }) + }, + // 通过nvue的dom模块,查询节点信息 + getRectByDom(ref) { + return new Promise((resolve) => { + dom.getComponentRect(ref, (res) => { + resolve(res.size) + }) + }) + } + } +} diff --git a/uni_modules/uv-swipe-action/components/uv-swipe-action-item/nvue.js b/uni_modules/uv-swipe-action/components/uv-swipe-action-item/nvue.js new file mode 100644 index 0000000..6eaf491 --- /dev/null +++ b/uni_modules/uv-swipe-action/components/uv-swipe-action-item/nvue.js @@ -0,0 +1,182 @@ +// nvue操作dom的库,用于获取dom的尺寸信息 +const dom = uni.requireNativePlugin('dom'); +const bindingX = uni.requireNativePlugin('bindingx'); +const animation = uni.requireNativePlugin('animation'); +import { getDuration, getPx } from '@/uni_modules/uv-ui-tools/libs/function/index.js' +export default { + data() { + return { + // 所有按钮的总宽度 + buttonsWidth: 0, + // 是否正在移动中 + moving: false + } + }, + computed: { + // 获取过渡时间 + getDuratin() { + let duration = String(this.duration) + // 如果ms为单位,返回ms的数值部分 + if (duration.indexOf('ms') >= 0) return parseInt(duration) + // 如果s为单位,为了得到ms的数值,需要乘以1000 + if (duration.indexOf('s') >= 0) return parseInt(duration) * 1000 + // 如果值传了数值,且小于30,认为是s单位 + duration = Number(duration) + return duration < 30 ? duration * 1000 : duration + } + }, + watch: { + show(n) { + if(n) { + this.moveCellByAnimation('open') + } else { + this.moveCellByAnimation('close') + } + } + }, + mounted() { + setTimeout(()=>{ + this.initialize() + },20) + }, + methods: { + initialize() { + this.queryRect() + }, + // 关闭单元格,用于打开一个,自动关闭其他单元格的场景 + closeHandler() { + if(this.status === 'open') { + // 如果在打开状态下,进行点击的话,直接关闭单元格 + return this.moveCellByAnimation('close') && this.unbindBindingX() + } + }, + // 点击单元格 + clickHandler() { + // 如果在移动中被点击,进行忽略 + if(this.moving) return + // 尝试关闭其他打开的单元格 + this.parent && this.parent.closeOther(this) + if(this.status === 'open') { + // 如果在打开状态下,进行点击的话,直接关闭单元格 + return this.moveCellByAnimation('close') && this.unbindBindingX() + } + }, + // 滑动单元格 + onTouchstart(e) { + // 如果当前正在移动中,或者disabled状态,则返回 + if(this.moving || this.disabled) { + return this.unbindBindingX() + } + if(this.status === 'open') { + // 如果在打开状态下,进行点击的话,直接关闭单元格 + return this.moveCellByAnimation('close') && this.unbindBindingX() + } + // 特殊情况下,e可能不为一个对象 + e?.stopPropagation && e.stopPropagation() + e?.preventDefault && e.preventDefault() + this.moving = true + // 获取元素ref + const content = this.getContentRef() + let expression = `min(max(${-this.buttonsWidth}, x), 0)` + // 尝试关闭其他打开的单元格 + this.parent && this.parent.closeOther(this) + // 阿里为了KPI而开源的BindingX + this.panEvent = bindingX.bind({ + anchor: content, + eventType: 'pan', + props: [{ + element: content, + // 绑定width属性,设置其宽度值 + property: 'transform.translateX', + expression + }] + }, (res) => { + this.moving = false + if (res.state === 'end' || res.state === 'exit') { + const deltaX = res.deltaX + if(deltaX <= -this.buttonsWidth || deltaX >= 0) { + // 如果触摸滑动的过程中,大于单元格的总宽度,或者大于0,意味着已经动过滑动达到了打开或者关闭的状态 + // 这里直接进行状态的标记 + this.$nextTick(() => { + this.status = deltaX <= -this.buttonsWidth ? 'open' : 'close' + }) + } else if(Math.abs(deltaX) > getPx(this.threshold)) { + // 在移动大于阈值、并且小于总按钮宽度时,进行自动打开或者关闭 + // 移动距离大于0时,意味着需要关闭状态 + if(Math.abs(deltaX) < this.buttonsWidth) { + this.moveCellByAnimation(deltaX > 0 ? 'close' : 'open') + } + } else { + // 在小于阈值时,进行关闭操作(如果在打开状态下,将不会执行bindingX) + this.moveCellByAnimation('close') + } + } + }) + }, + // 释放bindingX + unbindBindingX() { + // 释放上一次的资源 + if (this?.panEvent?.token != 0) { + bindingX.unbind({ + token: this.panEvent?.token, + // pan为手势事件 + eventType: 'pan' + }) + } + }, + // 查询按钮节点信息 + queryRect() { + // 历遍所有按钮数组,通过getRectByDom返回一个promise + const promiseAll = this.options.map(async(item, index) => { + return await this.getRectByDom(this.$refs[`uv-swipe-action-item__right__button-${index}`][0]) + }) + // 通过promise.all方法,让所有按钮的查询结果返回一个数组的形式 + Promise.all(promiseAll).then(sizes => { + this.buttons = sizes + // 计算所有按钮总宽度 + this.buttonsWidth = sizes.reduce((sum, cur) => sum + cur.width, 0) + }) + }, + // 通过nvue的dom模块,查询节点信息 + getRectByDom(ref) { + return new Promise(resolve => { + dom.getComponentRect(ref, res => { + resolve(res.size) + }) + }) + }, + // 移动单元格到左边或者右边尽头 + moveCellByAnimation(status = 'open') { + if(this.moving) return + // 标识当前状态 + this.moveing = true + const content = this.getContentRef() + const x = status === 'open' ? -this.buttonsWidth : 0 + animation.transition(content, { + styles: { + transform: `translateX(${x}px)`, + }, + duration: getDuration(this.duration, false), + timingFunction: 'ease-in-out' + }, () => { + this.moving = false + this.status = status + this.unbindBindingX() + }) + }, + // 获取元素ref + getContentRef() { + return this.$refs['uv-swipe-action-item__content'].ref + } + }, + // #ifdef VUE2 + beforeDestroy() { + this.unbindBindingX() + }, + // #endif + // #ifdef VUE3 + unmounted() { + this.unbindBindingX() + } + // #endif +} diff --git a/uni_modules/uv-swipe-action/components/uv-swipe-action-item/props.js b/uni_modules/uv-swipe-action/components/uv-swipe-action-item/props.js new file mode 100644 index 0000000..5b321e2 --- /dev/null +++ b/uni_modules/uv-swipe-action/components/uv-swipe-action-item/props.js @@ -0,0 +1,40 @@ +export default { + props: { + // 控制打开或者关闭 + show: { + type: Boolean, + default: false + }, + // 标识符,如果是v-for,可用index索引值 + name: { + type: [String, Number], + default: '' + }, + // 是否禁用 + disabled: { + type: Boolean, + default: false + }, + // 是否自动关闭其他swipe按钮组 + autoClose: { + type: Boolean, + default: true + }, + // 滑动距离阈值,只有大于此值,才被认为是要打开菜单 + threshold: { + type: Number, + default: 20 + }, + // 右侧按钮内容 + options: { + type: Array, + default: () => [] + }, + // 动画过渡时间,单位ms + duration: { + type: [String, Number], + default: 300 + }, + ...uni.$uv?.props?.swipeActionItem + } +} \ No newline at end of file diff --git a/uni_modules/uv-swipe-action/components/uv-swipe-action-item/uv-swipe-action-item.vue b/uni_modules/uv-swipe-action/components/uv-swipe-action-item/uv-swipe-action-item.vue new file mode 100644 index 0000000..8fd503a --- /dev/null +++ b/uni_modules/uv-swipe-action/components/uv-swipe-action-item/uv-swipe-action-item.vue @@ -0,0 +1,200 @@ + + + + + + + diff --git a/uni_modules/uv-swipe-action/components/uv-swipe-action-item/wxs.js b/uni_modules/uv-swipe-action/components/uv-swipe-action-item/wxs.js new file mode 100644 index 0000000..ee49c10 --- /dev/null +++ b/uni_modules/uv-swipe-action/components/uv-swipe-action-item/wxs.js @@ -0,0 +1,15 @@ +export default { + methods: { + // 关闭时执行 + closeHandler() { + this.status = 'close' + }, + setState(status) { + this.status = status + }, + closeOther() { + // 尝试关闭其他打开的单元格 + this.parent && this.parent.closeOther(this) + } + } +} diff --git a/uni_modules/uv-swipe-action/components/uv-swipe-action/props.js b/uni_modules/uv-swipe-action/components/uv-swipe-action/props.js new file mode 100644 index 0000000..7d06765 --- /dev/null +++ b/uni_modules/uv-swipe-action/components/uv-swipe-action/props.js @@ -0,0 +1,10 @@ +export default { + props: { + // 是否自动关闭其他swipe按钮组 + autoClose: { + type: Boolean, + default: true + }, + ...uni.$uv?.props?.swipeAction + } +} \ No newline at end of file diff --git a/uni_modules/uv-swipe-action/components/uv-swipe-action/uv-swipe-action.vue b/uni_modules/uv-swipe-action/components/uv-swipe-action/uv-swipe-action.vue new file mode 100644 index 0000000..ed3e9f9 --- /dev/null +++ b/uni_modules/uv-swipe-action/components/uv-swipe-action/uv-swipe-action.vue @@ -0,0 +1,65 @@ + + + diff --git a/uni_modules/uv-swipe-action/package.json b/uni_modules/uv-swipe-action/package.json new file mode 100644 index 0000000..9eef69b --- /dev/null +++ b/uni_modules/uv-swipe-action/package.json @@ -0,0 +1,88 @@ +{ + "id": "uv-swipe-action", + "displayName": "uv-swipe-action 滑动单元格 全面兼容小程序、nvue、vue2、vue3等多端", + "version": "1.0.4", + "description": "滑动单元格组件一般用于左滑唤出操作菜单的场景,用的最多的是左滑删除操作。", + "keywords": [ + "uv-swipe-action", + "uvui", + "uv-ui", + "swipe-action", + "滑动单元格" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "uv-ui-tools", + "uv-icon" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-swipe-action/readme.md b/uni_modules/uv-swipe-action/readme.md new file mode 100644 index 0000000..3180696 --- /dev/null +++ b/uni_modules/uv-swipe-action/readme.md @@ -0,0 +1,11 @@ +## SwipeAction 滑动单元格 + +> **组件名:uv-swipe-action** + +该组件一般用于左滑唤出操作菜单的场景,用的最多的是左滑删除操作。 + +### 查看文档 + +### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui) + +#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:uv-ui官方QQ群 diff --git a/uni_modules/uv-ui-tools/changelog.md b/uni_modules/uv-ui-tools/changelog.md new file mode 100644 index 0000000..3c745b0 --- /dev/null +++ b/uni_modules/uv-ui-tools/changelog.md @@ -0,0 +1,66 @@ +## 1.1.20(2023-10-30) +1. 1.1.16版本 +## 1.1.19(2023-10-13) +1. 兼容vue3 +## 1.1.18(2023-10-12) +1. 1.1.15版本 +## 1.1.17(2023-09-27) +1. 1.1.14版本发布 +## 1.1.16(2023-09-15) +1. 1.1.13版本发布 +## 1.1.15(2023-09-15) +1. 更新button.js相关按钮支持open-type="agreePrivacyAuthorization" +## 1.1.14(2023-09-14) +1. 优化dayjs +## 1.1.13(2023-09-13) +1. 优化,$uv中增加unit参数,方便组件中使用 +## 1.1.12(2023-09-10) +1. 升级版本 +## 1.1.11(2023-09-04) +1. 1.1.11版本 +## 1.1.10(2023-08-31) +1. 修复customStyle和customClass存在冲突的问题 +## 1.1.9(2023-08-27) +1. 版本升级 +2. 优化 +## 1.1.8(2023-08-24) +1. 版本升级 +## 1.1.7(2023-08-22) +1. 版本升级 +## 1.1.6(2023-08-18) +uvui版本:1.1.6 +## 1.0.15(2023-08-14) +1. 更新uvui版本号 +## 1.0.13(2023-08-06) +1. 优化 +## 1.0.12(2023-08-06) +1. 修改版本号 +## 1.0.11(2023-08-06) +1. 路由增加events参数 +2. 路由拦截修复 +## 1.0.10(2023-08-01) +1. 优化 +## 1.0.9(2023-06-28) +优化openType.js +## 1.0.8(2023-06-15) +1. 修改支付宝报错的BUG +## 1.0.7(2023-06-07) +1. 解决微信小程序使用uvui提示 Some selectors are not allowed in component wxss, including tag name selectors, ID selectors, and attribute selectors +2. 解决上述提示,需要在uni.scss配置$uvui-nvue-style: false; 然后在APP.vue下面引入uvui内置的基础样式:@import '@/uni_modules/uv-ui-tools/index.scss'; +## 1.0.6(2023-06-04) +1. uv-ui-tools 优化工具组件,兼容更多功能 +2. 小程序分享功能优化等 +## 1.0.5(2023-06-02) +1. 修改扩展使用mixin中方法的问题 +## 1.0.4(2023-05-23) +1. 兼容百度小程序修改bem函数 +## 1.0.3(2023-05-16) +1. 优化组件依赖,修改后无需全局引入,组件导入即可使用 +2. 优化部分功能 +## 1.0.2(2023-05-10) +1. 增加Http请求封装 +2. 优化 +## 1.0.1(2023-05-04) +1. 修改名称及备注 +## 1.0.0(2023-05-04) +1. uv-ui工具集首次发布 diff --git a/uni_modules/uv-ui-tools/components/uv-ui-tools/uv-ui-tools.vue b/uni_modules/uv-ui-tools/components/uv-ui-tools/uv-ui-tools.vue new file mode 100644 index 0000000..baf45e9 --- /dev/null +++ b/uni_modules/uv-ui-tools/components/uv-ui-tools/uv-ui-tools.vue @@ -0,0 +1,6 @@ + + + diff --git a/uni_modules/uv-ui-tools/index.js b/uni_modules/uv-ui-tools/index.js new file mode 100644 index 0000000..2b677fb --- /dev/null +++ b/uni_modules/uv-ui-tools/index.js @@ -0,0 +1,79 @@ +// 全局挂载引入http相关请求拦截插件 +import Request from './libs/luch-request' + +// 引入全局mixin +import mixin from './libs/mixin/mixin.js' +// 小程序特有的mixin +import mpMixin from './libs/mixin/mpMixin.js' +// #ifdef MP +import mpShare from '@/uni_modules/uv-ui-tools/libs/mixin/mpShare.js' +// #endif + +// 路由封装 +import route from './libs/util/route.js' +// 公共工具函数 +import * as index from './libs/function/index.js' +// 防抖方法 +import debounce from './libs/function/debounce.js' +// 节流方法 +import throttle from './libs/function/throttle.js' +// 规则检验 +import * as test from './libs/function/test.js' + +// 颜色渐变相关,colorGradient-颜色渐变,hexToRgb-十六进制颜色转rgb颜色,rgbToHex-rgb转十六进制 +import * as colorGradient from './libs/function/colorGradient.js' + +// 配置信息 +import config from './libs/config/config.js' +// 平台 +import platform from './libs/function/platform' + +const $uv = { + route, + config, + test, + date: index.timeFormat, // 另名date + ...index, + colorGradient: colorGradient.colorGradient, + hexToRgb: colorGradient.hexToRgb, + rgbToHex: colorGradient.rgbToHex, + colorToRgba: colorGradient.colorToRgba, + http: new Request(), + debounce, + throttle, + platform, + mixin, + mpMixin +} +uni.$uv = $uv; +const install = (Vue,options={}) => { + // #ifndef APP-NVUE + const cloneMixin = index.deepClone(mixin); + delete cloneMixin?.props?.customClass; + delete cloneMixin?.props?.customStyle; + Vue.mixin(cloneMixin); + // #ifdef MP + if(options.mpShare){ + Vue.mixin(mpShare); + } + // #endif + // #endif + // #ifdef VUE2 + // 时间格式化,同时两个名称,date和timeFormat + Vue.filter('timeFormat', (timestamp, format) => uni.$uv.timeFormat(timestamp, format)); + Vue.filter('date', (timestamp, format) => uni.$uv.timeFormat(timestamp, format)); + // 将多久以前的方法,注入到全局过滤器 + Vue.filter('timeFrom', (timestamp, format) => uni.$uv.timeFrom(timestamp, format)); + // 同时挂载到uni和Vue.prototype中 + // #ifndef APP-NVUE + // 只有vue,挂载到Vue.prototype才有意义,因为nvue中全局Vue.prototype和Vue.mixin是无效的 + Vue.prototype.$uv = $uv; + // #endif + // #endif + // #ifdef VUE3 + Vue.config.globalProperties.$uv = $uv; + // #endif +} +export default { + install +} \ No newline at end of file diff --git a/uni_modules/uv-ui-tools/index.scss b/uni_modules/uv-ui-tools/index.scss new file mode 100644 index 0000000..8d05b8d --- /dev/null +++ b/uni_modules/uv-ui-tools/index.scss @@ -0,0 +1,7 @@ +// 引入公共基础类 +@import "./libs/css/common.scss"; + +// 非nvue的样式 +/* #ifndef APP-NVUE */ +@import "./libs/css/vue.scss"; +/* #endif */ \ No newline at end of file diff --git a/uni_modules/uv-ui-tools/libs/config/config.js b/uni_modules/uv-ui-tools/libs/config/config.js new file mode 100644 index 0000000..71e3f67 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/config/config.js @@ -0,0 +1,34 @@ +// 此版本发布于2023-10-30 +const version = '1.1.16' + +// 开发环境才提示,生产环境不会提示 +if (process.env.NODE_ENV === 'development') { + console.log(`\n %c uvui V${version} https://www.uvui.cn/ \n\n`, 'color: #ffffff; background: #3c9cff; padding:5px 0; border-radius: 5px;'); +} + +export default { + v: version, + version, + // 主题名称 + type: [ + 'primary', + 'success', + 'info', + 'error', + 'warning' + ], + // 颜色部分,本来可以通过scss的:export导出供js使用,但是奈何nvue不支持 + color: { + 'uv-primary': '#2979ff', + 'uv-warning': '#ff9900', + 'uv-success': '#19be6b', + 'uv-error': '#fa3534', + 'uv-info': '#909399', + 'uv-main-color': '#303133', + 'uv-content-color': '#606266', + 'uv-tips-color': '#909399', + 'uv-light-color': '#c0c4cc' + }, + // 默认单位,可以通过配置为rpx,那么在用于传入组件大小参数为数值时,就默认为rpx + unit: 'px' +} diff --git a/uni_modules/uv-ui-tools/libs/css/color.scss b/uni_modules/uv-ui-tools/libs/css/color.scss new file mode 100644 index 0000000..ce65743 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/css/color.scss @@ -0,0 +1,32 @@ +$uv-main-color: #303133 !default; +$uv-content-color: #606266 !default; +$uv-tips-color: #909193 !default; +$uv-light-color: #c0c4cc !default; +$uv-border-color: #dadbde !default; +$uv-bg-color: #f3f4f6 !default; +$uv-disabled-color: #c8c9cc !default; + +$uv-primary: #3c9cff !default; +$uv-primary-dark: #398ade !default; +$uv-primary-disabled: #9acafc !default; +$uv-primary-light: #ecf5ff !default; + +$uv-warning: #f9ae3d !default; +$uv-warning-dark: #f1a532 !default; +$uv-warning-disabled: #f9d39b !default; +$uv-warning-light: #fdf6ec !default; + +$uv-success: #5ac725 !default; +$uv-success-dark: #53c21d !default; +$uv-success-disabled: #a9e08f !default; +$uv-success-light: #f5fff0; + +$uv-error: #f56c6c !default; +$uv-error-dark: #e45656 !default; +$uv-error-disabled: #f7b2b2 !default; +$uv-error-light: #fef0f0 !default; + +$uv-info: #909399 !default; +$uv-info-dark: #767a82 !default; +$uv-info-disabled: #c4c6c9 !default; +$uv-info-light: #f4f4f5 !default; diff --git a/uni_modules/uv-ui-tools/libs/css/common.scss b/uni_modules/uv-ui-tools/libs/css/common.scss new file mode 100644 index 0000000..7ab99f8 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/css/common.scss @@ -0,0 +1,100 @@ +// 超出行数,自动显示行尾省略号,最多5行 +// 来自uvui的温馨提示:当您在控制台看到此报错,说明需要在App.vue的style标签加上【lang="scss"】 +@for $i from 1 through 5 { + .uv-line-#{$i} { + /* #ifdef APP-NVUE */ + // nvue下,可以直接使用lines属性,这是weex特有样式 + lines: $i; + text-overflow: ellipsis; + overflow: hidden; + flex: 1; + /* #endif */ + + /* #ifndef APP-NVUE */ + // vue下,单行和多行显示省略号需要单独处理 + @if $i == '1' { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + } @else { + display: -webkit-box!important; + overflow: hidden; + text-overflow: ellipsis; + word-break: break-all; + -webkit-line-clamp: $i; + -webkit-box-orient: vertical!important; + } + /* #endif */ + } +} +$uv-bordercolor: #dadbde; +@if variable-exists(uv-border-color) { + $uv-bordercolor: $uv-border-color; +} + +// 此处加上!important并非随意乱用,而是因为目前*.nvue页面编译到H5时, +// App.vue的样式会被uni-app的view元素的自带border属性覆盖,导致无效 +// 综上,这是uni-app的缺陷导致我们为了多端兼容,而必须要加上!important +// 移动端兼容性较好,直接使用0.5px去实现细边框,不使用伪元素形式实现 +.uv-border { + border-width: 0.5px!important; + border-color: $uv-bordercolor!important; + border-style: solid; +} + +.uv-border-top { + border-top-width: 0.5px!important; + border-color: $uv-bordercolor!important; + border-top-style: solid; +} + +.uv-border-left { + border-left-width: 0.5px!important; + border-color: $uv-bordercolor!important; + border-left-style: solid; +} + +.uv-border-right { + border-right-width: 0.5px!important; + border-color: $uv-bordercolor!important; + border-right-style: solid; +} + +.uv-border-bottom { + border-bottom-width: 0.5px!important; + border-color: $uv-bordercolor!important; + border-bottom-style: solid; +} + +.uv-border-top-bottom { + border-top-width: 0.5px!important; + border-bottom-width: 0.5px!important; + border-color: $uv-bordercolor!important; + border-top-style: solid; + border-bottom-style: solid; +} + +// 去除button的所有默认样式,让其表现跟普通的view、text元素一样 +.uv-reset-button { + padding: 0; + background-color: transparent; + /* #ifndef APP-PLUS */ + font-size: inherit; + line-height: inherit; + color: inherit; + /* #endif */ + /* #ifdef APP-NVUE */ + border-width: 0; + /* #endif */ +} + +/* #ifndef APP-NVUE */ +.uv-reset-button::after { + border: none; +} +/* #endif */ + +.uv-hover-class { + opacity: 0.7; +} + diff --git a/uni_modules/uv-ui-tools/libs/css/components.scss b/uni_modules/uv-ui-tools/libs/css/components.scss new file mode 100644 index 0000000..81ce15d --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/css/components.scss @@ -0,0 +1,23 @@ +@mixin flex($direction: row) { + /* #ifndef APP-NVUE */ + display: flex; + /* #endif */ + flex-direction: $direction; +} + +/* #ifndef APP-NVUE */ +// 由于uvui是基于nvue环境进行开发的,此环境中普通元素默认为flex-direction: column; +// 所以在非nvue中,需要对元素进行重置为flex-direction: column; 否则可能会表现异常 +$uvui-nvue-style: true !default; +@if $uvui-nvue-style == true { + view, scroll-view, swiper-item { + display: flex; + flex-direction: column; + flex-shrink: 0; + flex-grow: 0; + flex-basis: auto; + align-items: stretch; + align-content: flex-start; + } +} +/* #endif */ diff --git a/uni_modules/uv-ui-tools/libs/css/variable.scss b/uni_modules/uv-ui-tools/libs/css/variable.scss new file mode 100644 index 0000000..63903c9 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/css/variable.scss @@ -0,0 +1,111 @@ +// 超出行数,自动显示行尾省略号,最多5行 +// 来自uvui的温馨提示:当您在控制台看到此报错,说明需要在App.vue的style标签加上【lang="scss"】 +@if variable-exists(show-lines) { + @for $i from 1 through 5 { + .uv-line-#{$i} { + /* #ifdef APP-NVUE */ + // nvue下,可以直接使用lines属性,这是weex特有样式 + lines: $i; + text-overflow: ellipsis; + overflow: hidden; + flex: 1; + /* #endif */ + + /* #ifndef APP-NVUE */ + // vue下,单行和多行显示省略号需要单独处理 + @if $i == '1' { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + } @else { + display: -webkit-box!important; + overflow: hidden; + text-overflow: ellipsis; + word-break: break-all; + -webkit-line-clamp: $i; + -webkit-box-orient: vertical!important; + } + /* #endif */ + } + } +} +@if variable-exists(show-border) { + $uv-bordercolor: #dadbde; + @if variable-exists(uv-border-color) { + $uv-bordercolor: $uv-border-color; + } + // 此处加上!important并非随意乱用,而是因为目前*.nvue页面编译到H5时, + // App.vue的样式会被uni-app的view元素的自带border属性覆盖,导致无效 + // 综上,这是uni-app的缺陷导致我们为了多端兼容,而必须要加上!important + // 移动端兼容性较好,直接使用0.5px去实现细边框,不使用伪元素形式实现 + @if variable-exists(show-border-surround) { + .uv-border { + border-width: 0.5px!important; + border-color: $uv-bordercolor!important; + border-style: solid; + } + } + @if variable-exists(show-border-top) { + .uv-border-top { + border-top-width: 0.5px!important; + border-color: $uv-bordercolor!important; + border-top-style: solid; + } + } + @if variable-exists(show-border-left) { + .uv-border-left { + border-left-width: 0.5px!important; + border-color: $uv-bordercolor!important; + border-left-style: solid; + } + } + @if variable-exists(show-border-right) { + .uv-border-right { + border-right-width: 0.5px!important; + border-color: $uv-bordercolor!important; + border-right-style: solid; + } + } + @if variable-exists(show-border-bottom) { + .uv-border-bottom { + border-bottom-width: 0.5px!important; + border-color: $uv-bordercolor!important; + border-bottom-style: solid; + } + } + @if variable-exists(show-border-top-bottom) { + .uv-border-top-bottom { + border-top-width: 0.5px!important; + border-bottom-width: 0.5px!important; + border-color: $uv-bordercolor!important; + border-top-style: solid; + border-bottom-style: solid; + } + } +} +@if variable-exists(show-reset-button) { + // 去除button的所有默认样式,让其表现跟普通的view、text元素一样 + .uv-reset-button { + padding: 0; + background-color: transparent; + /* #ifndef APP-PLUS */ + font-size: inherit; + line-height: inherit; + color: inherit; + /* #endif */ + /* #ifdef APP-NVUE */ + border-width: 0; + /* #endif */ + } + + /* #ifndef APP-NVUE */ + .uv-reset-button::after { + border: none; + } + /* #endif */ +} +@if variable-exists(show-hover) { + .uv-hover-class { + opacity: 0.7; + } +} diff --git a/uni_modules/uv-ui-tools/libs/css/vue.scss b/uni_modules/uv-ui-tools/libs/css/vue.scss new file mode 100644 index 0000000..bdbefdd --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/css/vue.scss @@ -0,0 +1,40 @@ +// 历遍生成4个方向的底部安全区 +@each $d in top, right, bottom, left { + .uv-safe-area-inset-#{$d} { + padding-#{$d}: 0; + padding-#{$d}: constant(safe-area-inset-#{$d}); + padding-#{$d}: env(safe-area-inset-#{$d}); + } +} + +//提升H5端uni.toast()的层级,避免被uvui的modal等遮盖 +/* #ifdef H5 */ +uni-toast { + z-index: 10090; +} +uni-toast .uni-toast { + z-index: 10090; +} +/* #endif */ + +// 隐藏scroll-view的滚动条 +::-webkit-scrollbar { + display: none; + width: 0 !important; + height: 0 !important; + -webkit-appearance: none; + background: transparent; +} + +$uvui-nvue-style: true !default; +@if $uvui-nvue-style == false { + view, scroll-view, swiper-item { + display: flex; + flex-direction: column; + flex-shrink: 0; + flex-grow: 0; + flex-basis: auto; + align-items: stretch; + align-content: flex-start; + } +} diff --git a/uni_modules/uv-ui-tools/libs/function/colorGradient.js b/uni_modules/uv-ui-tools/libs/function/colorGradient.js new file mode 100644 index 0000000..55c188f --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/function/colorGradient.js @@ -0,0 +1,134 @@ +/** + * 求两个颜色之间的渐变值 + * @param {string} startColor 开始的颜色 + * @param {string} endColor 结束的颜色 + * @param {number} step 颜色等分的份额 + * */ +function colorGradient(startColor = 'rgb(0, 0, 0)', endColor = 'rgb(255, 255, 255)', step = 10) { + const startRGB = hexToRgb(startColor, false) // 转换为rgb数组模式 + const startR = startRGB[0] + const startG = startRGB[1] + const startB = startRGB[2] + + const endRGB = hexToRgb(endColor, false) + const endR = endRGB[0] + const endG = endRGB[1] + const endB = endRGB[2] + + const sR = (endR - startR) / step // 总差值 + const sG = (endG - startG) / step + const sB = (endB - startB) / step + const colorArr = [] + for (let i = 0; i < step; i++) { + // 计算每一步的hex值 + let hex = rgbToHex(`rgb(${Math.round((sR * i + startR))},${Math.round((sG * i + startG))},${Math.round((sB + * i + startB))})`) + // 确保第一个颜色值为startColor的值 + if (i === 0) hex = rgbToHex(startColor) + // 确保最后一个颜色值为endColor的值 + if (i === step - 1) hex = rgbToHex(endColor) + colorArr.push(hex) + } + return colorArr +} + +// 将hex表示方式转换为rgb表示方式(这里返回rgb数组模式) +function hexToRgb(sColor, str = true) { + const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/ + sColor = String(sColor).toLowerCase() + if (sColor && reg.test(sColor)) { + if (sColor.length === 4) { + let sColorNew = '#' + for (let i = 1; i < 4; i += 1) { + sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1)) + } + sColor = sColorNew + } + // 处理六位的颜色值 + const sColorChange = [] + for (let i = 1; i < 7; i += 2) { + sColorChange.push(parseInt(`0x${sColor.slice(i, i + 2)}`)) + } + if (!str) { + return sColorChange + } + return `rgb(${sColorChange[0]},${sColorChange[1]},${sColorChange[2]})` + } if (/^(rgb|RGB)/.test(sColor)) { + const arr = sColor.replace(/(?:\(|\)|rgb|RGB)*/g, '').split(',') + return arr.map((val) => Number(val)) + } + return sColor +} + +// 将rgb表示方式转换为hex表示方式 +function rgbToHex(rgb) { + const _this = rgb + const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/ + if (/^(rgb|RGB)/.test(_this)) { + const aColor = _this.replace(/(?:\(|\)|rgb|RGB)*/g, '').split(',') + let strHex = '#' + for (let i = 0; i < aColor.length; i++) { + let hex = Number(aColor[i]).toString(16) + hex = String(hex).length == 1 ? `${0}${hex}` : hex // 保证每个rgb的值为2位 + if (hex === '0') { + hex += hex + } + strHex += hex + } + if (strHex.length !== 7) { + strHex = _this + } + return strHex + } if (reg.test(_this)) { + const aNum = _this.replace(/#/, '').split('') + if (aNum.length === 6) { + return _this + } if (aNum.length === 3) { + let numHex = '#' + for (let i = 0; i < aNum.length; i += 1) { + numHex += (aNum[i] + aNum[i]) + } + return numHex + } + } else { + return _this + } +} + +/** +* JS颜色十六进制转换为rgb或rgba,返回的格式为 rgba(255,255,255,0.5)字符串 +* sHex为传入的十六进制的色值 +* alpha为rgba的透明度 +*/ +function colorToRgba(color, alpha) { + color = rgbToHex(color) + // 十六进制颜色值的正则表达式 + const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/ + /* 16进制颜色转为RGB格式 */ + let sColor = String(color).toLowerCase() + if (sColor && reg.test(sColor)) { + if (sColor.length === 4) { + let sColorNew = '#' + for (let i = 1; i < 4; i += 1) { + sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1)) + } + sColor = sColorNew + } + // 处理六位的颜色值 + const sColorChange = [] + for (let i = 1; i < 7; i += 2) { + sColorChange.push(parseInt(`0x${sColor.slice(i, i + 2)}`)) + } + // return sColorChange.join(',') + return `rgba(${sColorChange.join(',')},${alpha})` + } + + return sColor +} + +export { + colorGradient, + hexToRgb, + rgbToHex, + colorToRgba +} diff --git a/uni_modules/uv-ui-tools/libs/function/debounce.js b/uni_modules/uv-ui-tools/libs/function/debounce.js new file mode 100644 index 0000000..ad3996b --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/function/debounce.js @@ -0,0 +1,29 @@ +let timeout = null + +/** + * 防抖原理:一定时间内,只有最后一次操作,再过wait毫秒后才执行函数 + * + * @param {Function} func 要执行的回调函数 + * @param {Number} wait 延时的时间 + * @param {Boolean} immediate 是否立即执行 + * @return null + */ +function debounce(func, wait = 500, immediate = false) { + // 清除定时器 + if (timeout !== null) clearTimeout(timeout) + // 立即执行,此类情况一般用不到 + if (immediate) { + const callNow = !timeout + timeout = setTimeout(() => { + timeout = null + }, wait) + if (callNow) typeof func === 'function' && func() + } else { + // 设置定时器,当最后一次操作后,timeout不会再被清除,所以在延时wait毫秒后执行func回调方法 + timeout = setTimeout(() => { + typeof func === 'function' && func() + }, wait) + } +} + +export default debounce diff --git a/uni_modules/uv-ui-tools/libs/function/digit.js b/uni_modules/uv-ui-tools/libs/function/digit.js new file mode 100644 index 0000000..c8260a0 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/function/digit.js @@ -0,0 +1,167 @@ +let _boundaryCheckingState = true; // 是否进行越界检查的全局开关 + +/** + * 把错误的数据转正 + * @private + * @example strip(0.09999999999999998)=0.1 + */ +function strip(num, precision = 15) { + return +parseFloat(Number(num).toPrecision(precision)); +} + +/** + * Return digits length of a number + * @private + * @param {*number} num Input number + */ +function digitLength(num) { + // Get digit length of e + const eSplit = num.toString().split(/[eE]/); + const len = (eSplit[0].split('.')[1] || '').length - +(eSplit[1] || 0); + return len > 0 ? len : 0; +} + +/** + * 把小数转成整数,如果是小数则放大成整数 + * @private + * @param {*number} num 输入数 + */ +function float2Fixed(num) { + if (num.toString().indexOf('e') === -1) { + return Number(num.toString().replace('.', '')); + } + const dLen = digitLength(num); + return dLen > 0 ? strip(Number(num) * Math.pow(10, dLen)) : Number(num); +} + +/** + * 检测数字是否越界,如果越界给出提示 + * @private + * @param {*number} num 输入数 + */ +function checkBoundary(num) { + if (_boundaryCheckingState) { + if (num > Number.MAX_SAFE_INTEGER || num < Number.MIN_SAFE_INTEGER) { + console.warn(`${num} 超出了精度限制,结果可能不正确`); + } + } +} + +/** + * 把递归操作扁平迭代化 + * @param {number[]} arr 要操作的数字数组 + * @param {function} operation 迭代操作 + * @private + */ +function iteratorOperation(arr, operation) { + const [num1, num2, ...others] = arr; + let res = operation(num1, num2); + + others.forEach((num) => { + res = operation(res, num); + }); + + return res; +} + +/** + * 高精度乘法 + * @export + */ +export function times(...nums) { + if (nums.length > 2) { + return iteratorOperation(nums, times); + } + + const [num1, num2] = nums; + const num1Changed = float2Fixed(num1); + const num2Changed = float2Fixed(num2); + const baseNum = digitLength(num1) + digitLength(num2); + const leftValue = num1Changed * num2Changed; + + checkBoundary(leftValue); + + return leftValue / Math.pow(10, baseNum); +} + +/** + * 高精度加法 + * @export + */ +export function plus(...nums) { + if (nums.length > 2) { + return iteratorOperation(nums, plus); + } + + const [num1, num2] = nums; + // 取最大的小数位 + const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2))); + // 把小数都转为整数然后再计算 + return (times(num1, baseNum) + times(num2, baseNum)) / baseNum; +} + +/** + * 高精度减法 + * @export + */ +export function minus(...nums) { + if (nums.length > 2) { + return iteratorOperation(nums, minus); + } + + const [num1, num2] = nums; + const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2))); + return (times(num1, baseNum) - times(num2, baseNum)) / baseNum; +} + +/** + * 高精度除法 + * @export + */ +export function divide(...nums) { + if (nums.length > 2) { + return iteratorOperation(nums, divide); + } + + const [num1, num2] = nums; + const num1Changed = float2Fixed(num1); + const num2Changed = float2Fixed(num2); + checkBoundary(num1Changed); + checkBoundary(num2Changed); + // 重要,这里必须用strip进行修正 + return times(num1Changed / num2Changed, strip(Math.pow(10, digitLength(num2) - digitLength(num1)))); +} + +/** + * 四舍五入 + * @export + */ +export function round(num, ratio) { + const base = Math.pow(10, ratio); + let result = divide(Math.round(Math.abs(times(num, base))), base); + if (num < 0 && result !== 0) { + result = times(result, -1); + } + // 位数不足则补0 + return result; +} + +/** + * 是否进行边界检查,默认开启 + * @param flag 标记开关,true 为开启,false 为关闭,默认为 true + * @export + */ +export function enableBoundaryChecking(flag = true) { + _boundaryCheckingState = flag; +} + + +export default { + times, + plus, + minus, + divide, + round, + enableBoundaryChecking, +}; + diff --git a/uni_modules/uv-ui-tools/libs/function/index.js b/uni_modules/uv-ui-tools/libs/function/index.js new file mode 100644 index 0000000..b35e0ab --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/function/index.js @@ -0,0 +1,734 @@ +import { number, empty } from './test.js' +import { round } from './digit.js' +/** + * @description 如果value小于min,取min;如果value大于max,取max + * @param {number} min + * @param {number} max + * @param {number} value + */ +function range(min = 0, max = 0, value = 0) { + return Math.max(min, Math.min(max, Number(value))) +} + +/** + * @description 用于获取用户传递值的px值 如果用户传递了"xxpx"或者"xxrpx",取出其数值部分,如果是"xxxrpx"还需要用过uni.upx2px进行转换 + * @param {number|string} value 用户传递值的px值 + * @param {boolean} unit + * @returns {number|string} + */ +function getPx(value, unit = false) { + if (number(value)) { + return unit ? `${value}px` : Number(value) + } + // 如果带有rpx,先取出其数值部分,再转为px值 + if (/(rpx|upx)$/.test(value)) { + return unit ? `${uni.upx2px(parseInt(value))}px` : Number(uni.upx2px(parseInt(value))) + } + return unit ? `${parseInt(value)}px` : parseInt(value) +} + +/** + * @description 进行延时,以达到可以简写代码的目的 比如: await uni.$uv.sleep(20)将会阻塞20ms + * @param {number} value 堵塞时间 单位ms 毫秒 + * @returns {Promise} 返回promise + */ +function sleep(value = 30) { + return new Promise((resolve) => { + setTimeout(() => { + resolve() + }, value) + }) +} +/** + * @description 运行期判断平台 + * @returns {string} 返回所在平台(小写) + * @link 运行期判断平台 https://uniapp.dcloud.io/frame?id=判断平台 + */ +function os() { + return uni.getSystemInfoSync().platform.toLowerCase() +} +/** + * @description 获取系统信息同步接口 + * @link 获取系统信息同步接口 https://uniapp.dcloud.io/api/system/info?id=getsysteminfosync + */ +function sys() { + return uni.getSystemInfoSync() +} + +/** + * @description 取一个区间数 + * @param {Number} min 最小值 + * @param {Number} max 最大值 + */ +function random(min, max) { + if (min >= 0 && max > 0 && max >= min) { + const gab = max - min + 1 + return Math.floor(Math.random() * gab + min) + } + return 0 +} + +/** + * @param {Number} len uuid的长度 + * @param {Boolean} firstU 将返回的首字母置为"u" + * @param {Nubmer} radix 生成uuid的基数(意味着返回的字符串都是这个基数),2-二进制,8-八进制,10-十进制,16-十六进制 + */ +function guid(len = 32, firstU = true, radix = null) { + const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('') + const uuid = [] + radix = radix || chars.length + + if (len) { + // 如果指定uuid长度,只是取随机的字符,0|x为位运算,能去掉x的小数位,返回整数位 + for (let i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix] + } else { + let r + // rfc4122标准要求返回的uuid中,某些位为固定的字符 + uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-' + uuid[14] = '4' + + for (let i = 0; i < 36; i++) { + if (!uuid[i]) { + r = 0 | Math.random() * 16 + uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r] + } + } + } + // 移除第一个字符,并用u替代,因为第一个字符为数值时,该guuid不能用作id或者class + if (firstU) { + uuid.shift() + return `u${uuid.join('')}` + } + return uuid.join('') +} + +/** +* @description 获取父组件的参数,因为支付宝小程序不支持provide/inject的写法 + this.$parent在非H5中,可以准确获取到父组件,但是在H5中,需要多次this.$parent.$parent.xxx + 这里默认值等于undefined有它的含义,因为最顶层元素(组件)的$parent就是undefined,意味着不传name + 值(默认为undefined),就是查找最顶层的$parent +* @param {string|undefined} name 父组件的参数名 +*/ +function $parent(name = undefined) { + let parent = this.$parent + // 通过while历遍,这里主要是为了H5需要多层解析的问题 + while (parent) { + // 父组件 + if (parent.$options && parent.$options.name !== name) { + // 如果组件的name不相等,继续上一级寻找 + parent = parent.$parent + } else { + return parent + } + } + return false +} + +/** + * @description 样式转换 + * 对象转字符串,或者字符串转对象 + * @param {object | string} customStyle 需要转换的目标 + * @param {String} target 转换的目的,object-转为对象,string-转为字符串 + * @returns {object|string} + */ +function addStyle(customStyle, target = 'object') { + // 字符串转字符串,对象转对象情形,直接返回 + if (empty(customStyle) || typeof(customStyle) === 'object' && target === 'object' || target === 'string' && + typeof(customStyle) === 'string') { + return customStyle + } + // 字符串转对象 + if (target === 'object') { + // 去除字符串样式中的两端空格(中间的空格不能去掉,比如padding: 20px 0如果去掉了就错了),空格是无用的 + customStyle = trim(customStyle) + // 根据";"将字符串转为数组形式 + const styleArray = customStyle.split(';') + const style = {} + // 历遍数组,拼接成对象 + for (let i = 0; i < styleArray.length; i++) { + // 'font-size:20px;color:red;',如此最后字符串有";"的话,会导致styleArray最后一个元素为空字符串,这里需要过滤 + if (styleArray[i]) { + const item = styleArray[i].split(':') + style[trim(item[0])] = trim(item[1]) + } + } + return style + } + // 这里为对象转字符串形式 + let string = '' + for (const i in customStyle) { + // 驼峰转为中划线的形式,否则css内联样式,无法识别驼峰样式属性名 + const key = i.replace(/([A-Z])/g, '-$1').toLowerCase() + string += `${key}:${customStyle[i]};` + } + // 去除两端空格 + return trim(string) +} + +/** + * @description 添加单位,如果有rpx,upx,%,px等单位结尾或者值为auto,直接返回,否则加上px单位结尾 + * @param {string|number} value 需要添加单位的值 + * @param {string} unit 添加的单位名 比如px + */ +function addUnit(value = 'auto', unit = uni?.$uv?.config?.unit ? uni?.$uv?.config?.unit : 'px') { + value = String(value) + // 用uvui内置验证规则中的number判断是否为数值 + return number(value) ? `${value}${unit}` : value +} + +/** + * @description 深度克隆 + * @param {object} obj 需要深度克隆的对象 + * @param cache 缓存 + * @returns {*} 克隆后的对象或者原值(不是对象) + */ +function deepClone(obj, cache = new WeakMap()) { + if (obj === null || typeof obj !== 'object') return obj; + if (cache.has(obj)) return cache.get(obj); + let clone; + if (obj instanceof Date) { + clone = new Date(obj.getTime()); + } else if (obj instanceof RegExp) { + clone = new RegExp(obj); + } else if (obj instanceof Map) { + clone = new Map(Array.from(obj, ([key, value]) => [key, deepClone(value, cache)])); + } else if (obj instanceof Set) { + clone = new Set(Array.from(obj, value => deepClone(value, cache))); + } else if (Array.isArray(obj)) { + clone = obj.map(value => deepClone(value, cache)); + } else if (Object.prototype.toString.call(obj) === '[object Object]') { + clone = Object.create(Object.getPrototypeOf(obj)); + cache.set(obj, clone); + for (const [key, value] of Object.entries(obj)) { + clone[key] = deepClone(value, cache); + } + } else { + clone = Object.assign({}, obj); + } + cache.set(obj, clone); + return clone; +} + +/** + * @description JS对象深度合并 + * @param {object} target 需要拷贝的对象 + * @param {object} source 拷贝的来源对象 + * @returns {object|boolean} 深度合并后的对象或者false(入参有不是对象) + */ +function deepMerge(target = {}, source = {}) { + target = deepClone(target) + if (typeof target !== 'object' || target === null || typeof source !== 'object' || source === null) return target; + const merged = Array.isArray(target) ? target.slice() : Object.assign({}, target); + for (const prop in source) { + if (!source.hasOwnProperty(prop)) continue; + const sourceValue = source[prop]; + const targetValue = merged[prop]; + if (sourceValue instanceof Date) { + merged[prop] = new Date(sourceValue); + } else if (sourceValue instanceof RegExp) { + merged[prop] = new RegExp(sourceValue); + } else if (sourceValue instanceof Map) { + merged[prop] = new Map(sourceValue); + } else if (sourceValue instanceof Set) { + merged[prop] = new Set(sourceValue); + } else if (typeof sourceValue === 'object' && sourceValue !== null) { + merged[prop] = deepMerge(targetValue, sourceValue); + } else { + merged[prop] = sourceValue; + } + } + return merged; +} + +/** + * @description error提示 + * @param {*} err 错误内容 + */ +function error(err) { + // 开发环境才提示,生产环境不会提示 + if (process.env.NODE_ENV === 'development') { + console.error(`uvui提示:${err}`) + } +} + +/** + * @description 打乱数组 + * @param {array} array 需要打乱的数组 + * @returns {array} 打乱后的数组 + */ +function randomArray(array = []) { + // 原理是sort排序,Math.random()产生0<= x < 1之间的数,会导致x-0.05大于或者小于0 + return array.sort(() => Math.random() - 0.5) +} + +// padStart 的 polyfill,因为某些机型或情况,还无法支持es7的padStart,比如电脑版的微信小程序 +// 所以这里做一个兼容polyfill的兼容处理 +if (!String.prototype.padStart) { + // 为了方便表示这里 fillString 用了ES6 的默认参数,不影响理解 + String.prototype.padStart = function(maxLength, fillString = ' ') { + if (Object.prototype.toString.call(fillString) !== '[object String]') { + throw new TypeError( + 'fillString must be String' + ) + } + const str = this + // 返回 String(str) 这里是为了使返回的值是字符串字面量,在控制台中更符合直觉 + if (str.length >= maxLength) return String(str) + + const fillLength = maxLength - str.length + let times = Math.ceil(fillLength / fillString.length) + while (times >>= 1) { + fillString += fillString + if (times === 1) { + fillString += fillString + } + } + return fillString.slice(0, fillLength) + str + } +} + +/** + * @description 格式化时间 + * @param {String|Number} dateTime 需要格式化的时间戳 + * @param {String} fmt 格式化规则 yyyy:mm:dd|yyyy:mm|yyyy年mm月dd日|yyyy年mm月dd日 hh时MM分等,可自定义组合 默认yyyy-mm-dd + * @returns {string} 返回格式化后的字符串 + */ +function timeFormat(dateTime = null, formatStr = 'yyyy-mm-dd') { + let date + // 若传入时间为假值,则取当前时间 + if (!dateTime) { + date = new Date() + } + // 若为unix秒时间戳,则转为毫秒时间戳(逻辑有点奇怪,但不敢改,以保证历史兼容) + else if (/^\d{10}$/.test(dateTime?.toString().trim())) { + date = new Date(dateTime * 1000) + } + // 若用户传入字符串格式时间戳,new Date无法解析,需做兼容 + else if (typeof dateTime === 'string' && /^\d+$/.test(dateTime.trim())) { + date = new Date(Number(dateTime)) + } + // 处理平台性差异,在Safari/Webkit中,new Date仅支持/作为分割符的字符串时间 + // 处理 '2022-07-10 01:02:03',跳过 '2022-07-10T01:02:03' + else if (typeof dateTime === 'string' && dateTime.includes('-') && !dateTime.includes('T')) { + date = new Date(dateTime.replace(/-/g, '/')) + } + // 其他都认为符合 RFC 2822 规范 + else { + date = new Date(dateTime) + } + + const timeSource = { + 'y': date.getFullYear().toString(), // 年 + 'm': (date.getMonth() + 1).toString().padStart(2, '0'), // 月 + 'd': date.getDate().toString().padStart(2, '0'), // 日 + 'h': date.getHours().toString().padStart(2, '0'), // 时 + 'M': date.getMinutes().toString().padStart(2, '0'), // 分 + 's': date.getSeconds().toString().padStart(2, '0') // 秒 + // 有其他格式化字符需求可以继续添加,必须转化成字符串 + } + + for (const key in timeSource) { + const [ret] = new RegExp(`${key}+`).exec(formatStr) || [] + if (ret) { + // 年可能只需展示两位 + const beginIndex = key === 'y' && ret.length === 2 ? 2 : 0 + formatStr = formatStr.replace(ret, timeSource[key].slice(beginIndex)) + } + } + + return formatStr +} + +/** + * @description 时间戳转为多久之前 + * @param {String|Number} timestamp 时间戳 + * @param {String|Boolean} format + * 格式化规则如果为时间格式字符串,超出一定时间范围,返回固定的时间格式; + * 如果为布尔值false,无论什么时间,都返回多久以前的格式 + * @returns {string} 转化后的内容 + */ +function timeFrom(timestamp = null, format = 'yyyy-mm-dd') { + if (timestamp == null) timestamp = Number(new Date()) + timestamp = parseInt(timestamp) + // 判断用户输入的时间戳是秒还是毫秒,一般前端js获取的时间戳是毫秒(13位),后端传过来的为秒(10位) + if (timestamp.toString().length == 10) timestamp *= 1000 + let timer = (new Date()).getTime() - timestamp + timer = parseInt(timer / 1000) + // 如果小于5分钟,则返回"刚刚",其他以此类推 + let tips = '' + switch (true) { + case timer < 300: + tips = '刚刚' + break + case timer >= 300 && timer < 3600: + tips = `${parseInt(timer / 60)}分钟前` + break + case timer >= 3600 && timer < 86400: + tips = `${parseInt(timer / 3600)}小时前` + break + case timer >= 86400 && timer < 2592000: + tips = `${parseInt(timer / 86400)}天前` + break + default: + // 如果format为false,则无论什么时间戳,都显示xx之前 + if (format === false) { + if (timer >= 2592000 && timer < 365 * 86400) { + tips = `${parseInt(timer / (86400 * 30))}个月前` + } else { + tips = `${parseInt(timer / (86400 * 365))}年前` + } + } else { + tips = timeFormat(timestamp, format) + } + } + return tips +} + +/** + * @description 去除空格 + * @param String str 需要去除空格的字符串 + * @param String pos both(左右)|left|right|all 默认both + */ +function trim(str, pos = 'both') { + str = String(str) + if (pos == 'both') { + return str.replace(/^\s+|\s+$/g, '') + } + if (pos == 'left') { + return str.replace(/^\s*/, '') + } + if (pos == 'right') { + return str.replace(/(\s*$)/g, '') + } + if (pos == 'all') { + return str.replace(/\s+/g, '') + } + return str +} + +/** + * @description 对象转url参数 + * @param {object} data,对象 + * @param {Boolean} isPrefix,是否自动加上"?" + * @param {string} arrayFormat 规则 indices|brackets|repeat|comma + */ +function queryParams(data = {}, isPrefix = true, arrayFormat = 'brackets') { + const prefix = isPrefix ? '?' : '' + const _result = [] + if (['indices', 'brackets', 'repeat', 'comma'].indexOf(arrayFormat) == -1) arrayFormat = 'brackets' + for (const key in data) { + const value = data[key] + // 去掉为空的参数 + if (['', undefined, null].indexOf(value) >= 0) { + continue + } + // 如果值为数组,另行处理 + if (value.constructor === Array) { + // e.g. {ids: [1, 2, 3]} + switch (arrayFormat) { + case 'indices': + // 结果: ids[0]=1&ids[1]=2&ids[2]=3 + for (let i = 0; i < value.length; i++) { + _result.push(`${key}[${i}]=${value[i]}`) + } + break + case 'brackets': + // 结果: ids[]=1&ids[]=2&ids[]=3 + value.forEach((_value) => { + _result.push(`${key}[]=${_value}`) + }) + break + case 'repeat': + // 结果: ids=1&ids=2&ids=3 + value.forEach((_value) => { + _result.push(`${key}=${_value}`) + }) + break + case 'comma': + // 结果: ids=1,2,3 + let commaStr = '' + value.forEach((_value) => { + commaStr += (commaStr ? ',' : '') + _value + }) + _result.push(`${key}=${commaStr}`) + break + default: + value.forEach((_value) => { + _result.push(`${key}[]=${_value}`) + }) + } + } else { + _result.push(`${key}=${value}`) + } + } + return _result.length ? prefix + _result.join('&') : '' +} + +/** + * 显示消息提示框 + * @param {String} title 提示的内容,长度与 icon 取值有关。 + * @param {Number} duration 提示的延迟时间,单位毫秒,默认:2000 + */ +function toast(title, duration = 2000) { + uni.showToast({ + title: String(title), + icon: 'none', + duration + }) +} + +/** + * @description 根据主题type值,获取对应的图标 + * @param {String} type 主题名称,primary|info|error|warning|success + * @param {boolean} fill 是否使用fill填充实体的图标 + */ +function type2icon(type = 'success', fill = false) { + // 如果非预置值,默认为success + if (['primary', 'info', 'error', 'warning', 'success'].indexOf(type) == -1) type = 'success' + let iconName = '' + // 目前(2019-12-12),info和primary使用同一个图标 + switch (type) { + case 'primary': + iconName = 'info-circle' + break + case 'info': + iconName = 'info-circle' + break + case 'error': + iconName = 'close-circle' + break + case 'warning': + iconName = 'error-circle' + break + case 'success': + iconName = 'checkmark-circle' + break + default: + iconName = 'checkmark-circle' + } + // 是否是实体类型,加上-fill,在icon组件库中,实体的类名是后面加-fill的 + if (fill) iconName += '-fill' + return iconName +} + +/** + * @description 数字格式化 + * @param {number|string} number 要格式化的数字 + * @param {number} decimals 保留几位小数 + * @param {string} decimalPoint 小数点符号 + * @param {string} thousandsSeparator 千分位符号 + * @returns {string} 格式化后的数字 + */ +function priceFormat(number, decimals = 0, decimalPoint = '.', thousandsSeparator = ',') { + number = (`${number}`).replace(/[^0-9+-Ee.]/g, '') + const n = !isFinite(+number) ? 0 : +number + const prec = !isFinite(+decimals) ? 0 : Math.abs(decimals) + const sep = (typeof thousandsSeparator === 'undefined') ? ',' : thousandsSeparator + const dec = (typeof decimalPoint === 'undefined') ? '.' : decimalPoint + let s = '' + + s = (prec ? round(n, prec) + '' : `${Math.round(n)}`).split('.') + const re = /(-?\d+)(\d{3})/ + while (re.test(s[0])) { + s[0] = s[0].replace(re, `$1${sep}$2`) + } + + if ((s[1] || '').length < prec) { + s[1] = s[1] || '' + s[1] += new Array(prec - s[1].length + 1).join('0') + } + return s.join(dec) +} + +/** + * @description 获取duration值 + * 如果带有ms或者s直接返回,如果大于一定值,认为是ms单位,小于一定值,认为是s单位 + * 比如以30位阈值,那么300大于30,可以理解为用户想要的是300ms,而不是想花300s去执行一个动画 + * @param {String|number} value 比如: "1s"|"100ms"|1|100 + * @param {boolean} unit 提示: 如果是false 默认返回number + * @return {string|number} + */ +function getDuration(value, unit = true) { + const valueNum = parseInt(value) + if (unit) { + if (/s$/.test(value)) return value + return value > 30 ? `${value}ms` : `${value}s` + } + if (/ms$/.test(value)) return valueNum + if (/s$/.test(value)) return valueNum > 30 ? valueNum : valueNum * 1000 + return valueNum +} + +/** + * @description 日期的月或日补零操作 + * @param {String} value 需要补零的值 + */ +function padZero(value) { + return `00${value}`.slice(-2) +} + +/** + * @description 在uv-form的子组件内容发生变化,或者失去焦点时,尝试通知uv-form执行校验方法 + * @param {*} instance + * @param {*} event + */ +function formValidate(instance, event) { + const formItem = $parent.call(instance, 'uv-form-item') + const form = $parent.call(instance, 'uv-form') + // 如果发生变化的input或者textarea等,其父组件中有uv-form-item或者uv-form等,就执行form的validate方法 + // 同时将form-item的pros传递给form,让其进行精确对象验证 + if (formItem && form) { + form.validateField(formItem.prop, () => {}, event) + } +} + +/** + * @description 获取某个对象下的属性,用于通过类似'a.b.c'的形式去获取一个对象的的属性的形式 + * @param {object} obj 对象 + * @param {string} key 需要获取的属性字段 + * @returns {*} + */ +function getProperty(obj, key) { + if (!obj) { + return + } + if (typeof key !== 'string' || key === '') { + return '' + } + if (key.indexOf('.') !== -1) { + const keys = key.split('.') + let firstObj = obj[keys[0]] || {} + + for (let i = 1; i < keys.length; i++) { + if (firstObj) { + firstObj = firstObj[keys[i]] + } + } + return firstObj + } + return obj[key] +} + +/** + * @description 设置对象的属性值,如果'a.b.c'的形式进行设置 + * @param {object} obj 对象 + * @param {string} key 需要设置的属性 + * @param {string} value 设置的值 + */ +function setProperty(obj, key, value) { + if (!obj) { + return + } + // 递归赋值 + const inFn = function(_obj, keys, v) { + // 最后一个属性key + if (keys.length === 1) { + _obj[keys[0]] = v + return + } + // 0~length-1个key + while (keys.length > 1) { + const k = keys[0] + if (!_obj[k] || (typeof _obj[k] !== 'object')) { + _obj[k] = {} + } + const key = keys.shift() + // 自调用判断是否存在属性,不存在则自动创建对象 + inFn(_obj[k], keys, v) + } + } + + if (typeof key !== 'string' || key === '') { + + } else if (key.indexOf('.') !== -1) { // 支持多层级赋值操作 + const keys = key.split('.') + inFn(obj, keys, value) + } else { + obj[key] = value + } +} + +/** + * @description 获取当前页面路径 + */ +function page() { + const pages = getCurrentPages(); + const route = pages[pages.length - 1]?.route; + // 某些特殊情况下(比如页面进行redirectTo时的一些时机),pages可能为空数组 + return `/${route ? route : ''}` +} + +/** + * @description 获取当前路由栈实例数组 + */ +function pages() { + const pages = getCurrentPages() + return pages +} + +/** + * 获取页面历史栈指定层实例 + * @param back {number} [0] - 0或者负数,表示获取历史栈的哪一层,0表示获取当前页面实例,-1 表示获取上一个页面实例。默认0。 + */ +function getHistoryPage(back = 0) { + const pages = getCurrentPages() + const len = pages.length + return pages[len - 1 + back] +} + + + +/** + * @description 修改uvui内置属性值 + * @param {object} props 修改内置props属性 + * @param {object} config 修改内置config属性 + * @param {object} color 修改内置color属性 + * @param {object} zIndex 修改内置zIndex属性 + */ +function setConfig({ + props = {}, + config = {}, + color = {}, + zIndex = {} +}) { + const { + deepMerge, + } = uni.$uv + uni.$uv.config = deepMerge(uni.$uv.config, config) + uni.$uv.props = deepMerge(uni.$uv.props, props) + uni.$uv.color = deepMerge(uni.$uv.color, color) + uni.$uv.zIndex = deepMerge(uni.$uv.zIndex, zIndex) +} + +export { + range, + getPx, + sleep, + os, + sys, + random, + guid, + $parent, + addStyle, + addUnit, + deepClone, + deepMerge, + error, + randomArray, + timeFormat, + timeFrom, + trim, + queryParams, + toast, + type2icon, + priceFormat, + getDuration, + padZero, + formValidate, + getProperty, + setProperty, + page, + pages, + getHistoryPage, + setConfig +} \ No newline at end of file diff --git a/uni_modules/uv-ui-tools/libs/function/platform.js b/uni_modules/uv-ui-tools/libs/function/platform.js new file mode 100644 index 0000000..d6b926e --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/function/platform.js @@ -0,0 +1,75 @@ +/** + * 注意: + * 此部分内容,在vue-cli模式下,需要在vue.config.js加入如下内容才有效: + * module.exports = { + * transpileDependencies: ['uview-v2'] + * } + */ + +let platform = 'none' + +// #ifdef VUE3 +platform = 'vue3' +// #endif + +// #ifdef VUE2 +platform = 'vue2' +// #endif + +// #ifdef APP-PLUS +platform = 'plus' +// #endif + +// #ifdef APP-NVUE +platform = 'nvue' +// #endif + +// #ifdef H5 +platform = 'h5' +// #endif + +// #ifdef MP-WEIXIN +platform = 'weixin' +// #endif + +// #ifdef MP-ALIPAY +platform = 'alipay' +// #endif + +// #ifdef MP-BAIDU +platform = 'baidu' +// #endif + +// #ifdef MP-TOUTIAO +platform = 'toutiao' +// #endif + +// #ifdef MP-QQ +platform = 'qq' +// #endif + +// #ifdef MP-KUAISHOU +platform = 'kuaishou' +// #endif + +// #ifdef MP-360 +platform = '360' +// #endif + +// #ifdef MP +platform = 'mp' +// #endif + +// #ifdef QUICKAPP-WEBVIEW +platform = 'quickapp-webview' +// #endif + +// #ifdef QUICKAPP-WEBVIEW-HUAWEI +platform = 'quickapp-webview-huawei' +// #endif + +// #ifdef QUICKAPP-WEBVIEW-UNION +platform = 'quckapp-webview-union' +// #endif + +export default platform diff --git a/uni_modules/uv-ui-tools/libs/function/test.js b/uni_modules/uv-ui-tools/libs/function/test.js new file mode 100644 index 0000000..7c8b747 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/function/test.js @@ -0,0 +1,287 @@ +/** + * 验证电子邮箱格式 + */ +function email(value) { + return /^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/.test(value) +} + +/** + * 验证手机格式 + */ +function mobile(value) { + return /^1([3589]\d|4[5-9]|6[1-2,4-7]|7[0-8])\d{8}$/.test(value) +} + +/** + * 验证URL格式 + */ +function url(value) { + return /^((https|http|ftp|rtsp|mms):\/\/)(([0-9a-zA-Z_!~*'().&=+$%-]+: )?[0-9a-zA-Z_!~*'().&=+$%-]+@)?(([0-9]{1,3}.){3}[0-9]{1,3}|([0-9a-zA-Z_!~*'()-]+.)*([0-9a-zA-Z][0-9a-zA-Z-]{0,61})?[0-9a-zA-Z].[a-zA-Z]{2,6})(:[0-9]{1,4})?((\/?)|(\/[0-9a-zA-Z_!~*'().;?:@&=+$,%#-]+)+\/?)$/ + .test(value) +} + +/** + * 验证日期格式 + */ +function date(value) { + if (!value) return false + // 判断是否数值或者字符串数值(意味着为时间戳),转为数值,否则new Date无法识别字符串时间戳 + if (number(value)) value = +value + return !/Invalid|NaN/.test(new Date(value).toString()) +} + +/** + * 验证ISO类型的日期格式 + */ +function dateISO(value) { + return /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(value) +} + +/** + * 验证十进制数字 + */ +function number(value) { + return /^[\+-]?(\d+\.?\d*|\.\d+|\d\.\d+e\+\d+)$/.test(value) +} + +/** + * 验证字符串 + */ +function string(value) { + return typeof value === 'string' +} + +/** + * 验证整数 + */ +function digits(value) { + return /^\d+$/.test(value) +} + +/** + * 验证身份证号码 + */ +function idCard(value) { + return /^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test( + value + ) +} + +/** + * 是否车牌号 + */ +function carNo(value) { + // 新能源车牌 + const xreg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}(([0-9]{5}[DF]$)|([DF][A-HJ-NP-Z0-9][0-9]{4}$))/ + // 旧车牌 + const creg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]{1}$/ + if (value.length === 7) { + return creg.test(value) + } if (value.length === 8) { + return xreg.test(value) + } + return false +} + +/** + * 金额,只允许2位小数 + */ +function amount(value) { + // 金额,只允许保留两位小数 + return /^[1-9]\d*(,\d{3})*(\.\d{1,2})?$|^0\.\d{1,2}$/.test(value) +} + +/** + * 中文 + */ +function chinese(value) { + const reg = /^[\u4e00-\u9fa5]+$/gi + return reg.test(value) +} + +/** + * 只能输入字母 + */ +function letter(value) { + return /^[a-zA-Z]*$/.test(value) +} + +/** + * 只能是字母或者数字 + */ +function enOrNum(value) { + // 英文或者数字 + const reg = /^[0-9a-zA-Z]*$/g + return reg.test(value) +} + +/** + * 验证是否包含某个值 + */ +function contains(value, param) { + return value.indexOf(param) >= 0 +} + +/** + * 验证一个值范围[min, max] + */ +function range(value, param) { + return value >= param[0] && value <= param[1] +} + +/** + * 验证一个长度范围[min, max] + */ +function rangeLength(value, param) { + return value.length >= param[0] && value.length <= param[1] +} + +/** + * 是否固定电话 + */ +function landline(value) { + const reg = /^\d{3,4}-\d{7,8}(-\d{3,4})?$/ + return reg.test(value) +} + +/** + * 判断是否为空 + */ +function empty(value) { + switch (typeof value) { + case 'undefined': + return true + case 'string': + if (value.replace(/(^[ \t\n\r]*)|([ \t\n\r]*$)/g, '').length == 0) return true + break + case 'boolean': + if (!value) return true + break + case 'number': + if (value === 0 || isNaN(value)) return true + break + case 'object': + if (value === null || value.length === 0) return true + for (const i in value) { + return false + } + return true + } + return false +} + +/** + * 是否json字符串 + */ +function jsonString(value) { + if (typeof value === 'string') { + try { + const obj = JSON.parse(value) + if (typeof obj === 'object' && obj) { + return true + } + return false + } catch (e) { + return false + } + } + return false +} + +/** + * 是否数组 + */ +function array(value) { + if (typeof Array.isArray === 'function') { + return Array.isArray(value) + } + return Object.prototype.toString.call(value) === '[object Array]' +} + +/** + * 是否对象 + */ +function object(value) { + return Object.prototype.toString.call(value) === '[object Object]' +} + +/** + * 是否短信验证码 + */ +function code(value, len = 6) { + return new RegExp(`^\\d{${len}}$`).test(value) +} + +/** + * 是否函数方法 + * @param {Object} value + */ +function func(value) { + return typeof value === 'function' +} + +/** + * 是否promise对象 + * @param {Object} value + */ +function promise(value) { + return object(value) && func(value.then) && func(value.catch) +} + +/** 是否图片格式 + * @param {Object} value + */ +function image(value) { + const newValue = value.split('?')[0] + const IMAGE_REGEXP = /\.(jpeg|jpg|gif|png|svg|webp|jfif|bmp|dpg)/i + return IMAGE_REGEXP.test(newValue) +} + +/** + * 是否视频格式 + * @param {Object} value + */ +function video(value) { + const VIDEO_REGEXP = /\.(mp4|mpg|mpeg|dat|asf|avi|rm|rmvb|mov|wmv|flv|mkv|m3u8)/i + return VIDEO_REGEXP.test(value) +} + +/** + * 是否为正则对象 + * @param {Object} + * @return {Boolean} + */ +function regExp(o) { + return o && Object.prototype.toString.call(o) === '[object RegExp]' +} + +export { + email, + mobile, + url, + date, + dateISO, + number, + digits, + idCard, + carNo, + amount, + chinese, + letter, + enOrNum, + contains, + range, + rangeLength, + empty, + jsonString, + landline, + object, + array, + code, + func, + promise, + video, + image, + regExp, + string +} diff --git a/uni_modules/uv-ui-tools/libs/function/throttle.js b/uni_modules/uv-ui-tools/libs/function/throttle.js new file mode 100644 index 0000000..2f33611 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/function/throttle.js @@ -0,0 +1,30 @@ +let timer; let + flag +/** + * 节流原理:在一定时间内,只能触发一次 + * + * @param {Function} func 要执行的回调函数 + * @param {Number} wait 延时的时间 + * @param {Boolean} immediate 是否立即执行 + * @return null + */ +function throttle(func, wait = 500, immediate = true) { + if (immediate) { + if (!flag) { + flag = true + // 如果是立即执行,则在wait毫秒内开始时执行 + typeof func === 'function' && func() + timer = setTimeout(() => { + flag = false + }, wait) + } + } else if (!flag) { + flag = true + // 如果是非立即执行,则在wait毫秒内的结束处执行 + timer = setTimeout(() => { + flag = false + typeof func === 'function' && func() + }, wait) + } +} +export default throttle diff --git a/uni_modules/uv-ui-tools/libs/luch-request/adapters/index.js b/uni_modules/uv-ui-tools/libs/luch-request/adapters/index.js new file mode 100644 index 0000000..e03cf5f --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/luch-request/adapters/index.js @@ -0,0 +1,97 @@ +import buildURL from '../helpers/buildURL' +import buildFullPath from '../core/buildFullPath' +import settle from '../core/settle' +import { isUndefined } from '../utils' + +/** + * 返回可选值存在的配置 + * @param {Array} keys - 可选值数组 + * @param {Object} config2 - 配置 + * @return {{}} - 存在的配置项 + */ +const mergeKeys = (keys, config2) => { + const config = {} + keys.forEach((prop) => { + if (!isUndefined(config2[prop])) { + config[prop] = config2[prop] + } + }) + return config +} +export default (config) => new Promise((resolve, reject) => { + const fullPath = buildURL(buildFullPath(config.baseURL, config.url), config.params) + const _config = { + url: fullPath, + header: config.header, + complete: (response) => { + config.fullPath = fullPath + response.config = config + try { + // 对可能字符串不是json 的情况容错 + if (typeof response.data === 'string') { + response.data = JSON.parse(response.data) + } + // eslint-disable-next-line no-empty + } catch (e) { + } + settle(resolve, reject, response) + } + } + let requestTask + if (config.method === 'UPLOAD') { + delete _config.header['content-type'] + delete _config.header['Content-Type'] + const otherConfig = { + // #ifdef MP-ALIPAY + fileType: config.fileType, + // #endif + filePath: config.filePath, + name: config.name + } + const optionalKeys = [ + // #ifdef APP-PLUS || H5 + 'files', + // #endif + // #ifdef H5 + 'file', + // #endif + // #ifdef H5 || APP-PLUS + 'timeout', + // #endif + 'formData' + ] + requestTask = uni.uploadFile({ ..._config, ...otherConfig, ...mergeKeys(optionalKeys, config) }) + } else if (config.method === 'DOWNLOAD') { + // #ifdef H5 || APP-PLUS + if (!isUndefined(config.timeout)) { + _config.timeout = config.timeout + } + // #endif + requestTask = uni.downloadFile(_config) + } else { + const optionalKeys = [ + 'data', + 'method', + // #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN + 'timeout', + // #endif + 'dataType', + // #ifndef MP-ALIPAY + 'responseType', + // #endif + // #ifdef APP-PLUS + 'sslVerify', + // #endif + // #ifdef H5 + 'withCredentials', + // #endif + // #ifdef APP-PLUS + 'firstIpv4' + // #endif + ] + requestTask = uni.request({ ..._config, ...mergeKeys(optionalKeys, config) }) + } + if (config.getTask) { + config.getTask(requestTask, config) + } +}) diff --git a/uni_modules/uv-ui-tools/libs/luch-request/core/InterceptorManager.js b/uni_modules/uv-ui-tools/libs/luch-request/core/InterceptorManager.js new file mode 100644 index 0000000..3e8728d --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/luch-request/core/InterceptorManager.js @@ -0,0 +1,50 @@ +'use strict' + +function InterceptorManager() { + this.handlers = [] +} + +/** + * Add a new interceptor to the stack + * + * @param {Function} fulfilled The function to handle `then` for a `Promise` + * @param {Function} rejected The function to handle `reject` for a `Promise` + * + * @return {Number} An ID used to remove interceptor later + */ +InterceptorManager.prototype.use = function use(fulfilled, rejected) { + this.handlers.push({ + fulfilled, + rejected + }) + return this.handlers.length - 1 +} + +/** + * Remove an interceptor from the stack + * + * @param {Number} id The ID that was returned by `use` + */ +InterceptorManager.prototype.eject = function eject(id) { + if (this.handlers[id]) { + this.handlers[id] = null + } +} + +/** + * Iterate over all the registered interceptors + * + * This method is particularly useful for skipping over any + * interceptors that may have become `null` calling `eject`. + * + * @param {Function} fn The function to call for each interceptor + */ +InterceptorManager.prototype.forEach = function forEach(fn) { + this.handlers.forEach((h) => { + if (h !== null) { + fn(h) + } + }) +} + +export default InterceptorManager diff --git a/uni_modules/uv-ui-tools/libs/luch-request/core/Request.js b/uni_modules/uv-ui-tools/libs/luch-request/core/Request.js new file mode 100644 index 0000000..cc48566 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/luch-request/core/Request.js @@ -0,0 +1,198 @@ +/** + * @Class Request + * @description luch-request http请求插件 + * @version 3.0.7 + * @Author lu-ch + * @Date 2021-09-04 + * @Email webwork.s@qq.com + * 文档: https://www.quanzhan.co/luch-request/ + * github: https://github.com/lei-mu/luch-request + * DCloud: http://ext.dcloud.net.cn/plugin?id=392 + * HBuilderX: beat-3.0.4 alpha-3.0.4 + */ + +import dispatchRequest from './dispatchRequest' +import InterceptorManager from './InterceptorManager' +import mergeConfig from './mergeConfig' +import defaults from './defaults' +import { isPlainObject } from '../utils' +import clone from '../utils/clone' + +export default class Request { + /** + * @param {Object} arg - 全局配置 + * @param {String} arg.baseURL - 全局根路径 + * @param {Object} arg.header - 全局header + * @param {String} arg.method = [GET|POST|PUT|DELETE|CONNECT|HEAD|OPTIONS|TRACE] - 全局默认请求方式 + * @param {String} arg.dataType = [json] - 全局默认的dataType + * @param {String} arg.responseType = [text|arraybuffer] - 全局默认的responseType。支付宝小程序不支持 + * @param {Object} arg.custom - 全局默认的自定义参数 + * @param {Number} arg.timeout - 全局默认的超时时间,单位 ms。默认60000。H5(HBuilderX 2.9.9+)、APP(HBuilderX 2.9.9+)、微信小程序(2.10.0)、支付宝小程序 + * @param {Boolean} arg.sslVerify - 全局默认的是否验证 ssl 证书。默认true.仅App安卓端支持(HBuilderX 2.3.3+) + * @param {Boolean} arg.withCredentials - 全局默认的跨域请求时是否携带凭证(cookies)。默认false。仅H5支持(HBuilderX 2.6.15+) + * @param {Boolean} arg.firstIpv4 - 全DNS解析时优先使用ipv4。默认false。仅 App-Android 支持 (HBuilderX 2.8.0+) + * @param {Function(statusCode):Boolean} arg.validateStatus - 全局默认的自定义验证器。默认statusCode >= 200 && statusCode < 300 + */ + constructor(arg = {}) { + if (!isPlainObject(arg)) { + arg = {} + console.warn('设置全局参数必须接收一个Object') + } + this.config = clone({ ...defaults, ...arg }) + this.interceptors = { + request: new InterceptorManager(), + response: new InterceptorManager() + } + } + + /** + * @Function + * @param {Request~setConfigCallback} f - 设置全局默认配置 + */ + setConfig(f) { + this.config = f(this.config) + } + + middleware(config) { + config = mergeConfig(this.config, config) + const chain = [dispatchRequest, undefined] + let promise = Promise.resolve(config) + + this.interceptors.request.forEach((interceptor) => { + chain.unshift(interceptor.fulfilled, interceptor.rejected) + }) + + this.interceptors.response.forEach((interceptor) => { + chain.push(interceptor.fulfilled, interceptor.rejected) + }) + + while (chain.length) { + promise = promise.then(chain.shift(), chain.shift()) + } + + return promise + } + + /** + * @Function + * @param {Object} config - 请求配置项 + * @prop {String} options.url - 请求路径 + * @prop {Object} options.data - 请求参数 + * @prop {Object} [options.responseType = config.responseType] [text|arraybuffer] - 响应的数据类型 + * @prop {Object} [options.dataType = config.dataType] - 如果设为 json,会尝试对返回的数据做一次 JSON.parse + * @prop {Object} [options.header = config.header] - 请求header + * @prop {Object} [options.method = config.method] - 请求方法 + * @returns {Promise} + */ + request(config = {}) { + return this.middleware(config) + } + + get(url, options = {}) { + return this.middleware({ + url, + method: 'GET', + ...options + }) + } + + post(url, data, options = {}) { + return this.middleware({ + url, + data, + method: 'POST', + ...options + }) + } + + // #ifndef MP-ALIPAY + put(url, data, options = {}) { + return this.middleware({ + url, + data, + method: 'PUT', + ...options + }) + } + + // #endif + + // #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU + delete(url, data, options = {}) { + return this.middleware({ + url, + data, + method: 'DELETE', + ...options + }) + } + + // #endif + + // #ifdef H5 || MP-WEIXIN + connect(url, data, options = {}) { + return this.middleware({ + url, + data, + method: 'CONNECT', + ...options + }) + } + + // #endif + + // #ifdef H5 || MP-WEIXIN || MP-BAIDU + head(url, data, options = {}) { + return this.middleware({ + url, + data, + method: 'HEAD', + ...options + }) + } + + // #endif + + // #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU + options(url, data, options = {}) { + return this.middleware({ + url, + data, + method: 'OPTIONS', + ...options + }) + } + + // #endif + + // #ifdef H5 || MP-WEIXIN + trace(url, data, options = {}) { + return this.middleware({ + url, + data, + method: 'TRACE', + ...options + }) + } + + // #endif + + upload(url, config = {}) { + config.url = url + config.method = 'UPLOAD' + return this.middleware(config) + } + + download(url, config = {}) { + config.url = url + config.method = 'DOWNLOAD' + return this.middleware(config) + } +} + +/** + * setConfig回调 + * @return {Object} - 返回操作后的config + * @callback Request~setConfigCallback + * @param {Object} config - 全局默认config + */ diff --git a/uni_modules/uv-ui-tools/libs/luch-request/core/buildFullPath.js b/uni_modules/uv-ui-tools/libs/luch-request/core/buildFullPath.js new file mode 100644 index 0000000..5eb8a17 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/luch-request/core/buildFullPath.js @@ -0,0 +1,20 @@ +'use strict' + +import isAbsoluteURL from '../helpers/isAbsoluteURL' +import combineURLs from '../helpers/combineURLs' + +/** + * Creates a new URL by combining the baseURL with the requestedURL, + * only when the requestedURL is not already an absolute URL. + * If the requestURL is absolute, this function returns the requestedURL untouched. + * + * @param {string} baseURL The base URL + * @param {string} requestedURL Absolute or relative URL to combine + * @returns {string} The combined full path + */ +export default function buildFullPath(baseURL, requestedURL) { + if (baseURL && !isAbsoluteURL(requestedURL)) { + return combineURLs(baseURL, requestedURL) + } + return requestedURL +} diff --git a/uni_modules/uv-ui-tools/libs/luch-request/core/defaults.js b/uni_modules/uv-ui-tools/libs/luch-request/core/defaults.js new file mode 100644 index 0000000..be375a9 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/luch-request/core/defaults.js @@ -0,0 +1,29 @@ +/** + * 默认的全局配置 + */ + +export default { + baseURL: '', + header: {}, + method: 'GET', + dataType: 'json', + // #ifndef MP-ALIPAY + responseType: 'text', + // #endif + custom: {}, + // #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN + timeout: 60000, + // #endif + // #ifdef APP-PLUS + sslVerify: true, + // #endif + // #ifdef H5 + withCredentials: false, + // #endif + // #ifdef APP-PLUS + firstIpv4: false, + // #endif + validateStatus: function validateStatus(status) { + return status >= 200 && status < 300 + } +} diff --git a/uni_modules/uv-ui-tools/libs/luch-request/core/dispatchRequest.js b/uni_modules/uv-ui-tools/libs/luch-request/core/dispatchRequest.js new file mode 100644 index 0000000..724545c --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/luch-request/core/dispatchRequest.js @@ -0,0 +1,3 @@ +import adapter from '../adapters/index' + +export default (config) => adapter(config) diff --git a/uni_modules/uv-ui-tools/libs/luch-request/core/mergeConfig.js b/uni_modules/uv-ui-tools/libs/luch-request/core/mergeConfig.js new file mode 100644 index 0000000..08f8b9b --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/luch-request/core/mergeConfig.js @@ -0,0 +1,103 @@ +import { deepMerge, isUndefined } from '../utils' + +/** + * 合并局部配置优先的配置,如果局部有该配置项则用局部,如果全局有该配置项则用全局 + * @param {Array} keys - 配置项 + * @param {Object} globalsConfig - 当前的全局配置 + * @param {Object} config2 - 局部配置 + * @return {{}} + */ +const mergeKeys = (keys, globalsConfig, config2) => { + const config = {} + keys.forEach((prop) => { + if (!isUndefined(config2[prop])) { + config[prop] = config2[prop] + } else if (!isUndefined(globalsConfig[prop])) { + config[prop] = globalsConfig[prop] + } + }) + return config +} +/** + * + * @param globalsConfig - 当前实例的全局配置 + * @param config2 - 当前的局部配置 + * @return - 合并后的配置 + */ +export default (globalsConfig, config2 = {}) => { + const method = config2.method || globalsConfig.method || 'GET' + let config = { + baseURL: globalsConfig.baseURL || '', + method, + url: config2.url || '', + params: config2.params || {}, + custom: { ...(globalsConfig.custom || {}), ...(config2.custom || {}) }, + header: deepMerge(globalsConfig.header || {}, config2.header || {}) + } + const defaultToConfig2Keys = ['getTask', 'validateStatus'] + config = { ...config, ...mergeKeys(defaultToConfig2Keys, globalsConfig, config2) } + + // eslint-disable-next-line no-empty + if (method === 'DOWNLOAD') { + // #ifdef H5 || APP-PLUS + if (!isUndefined(config2.timeout)) { + config.timeout = config2.timeout + } else if (!isUndefined(globalsConfig.timeout)) { + config.timeout = globalsConfig.timeout + } + // #endif + } else if (method === 'UPLOAD') { + delete config.header['content-type'] + delete config.header['Content-Type'] + const uploadKeys = [ + // #ifdef APP-PLUS || H5 + 'files', + // #endif + // #ifdef MP-ALIPAY + 'fileType', + // #endif + // #ifdef H5 + 'file', + // #endif + 'filePath', + 'name', + // #ifdef H5 || APP-PLUS + 'timeout', + // #endif + 'formData' + ] + uploadKeys.forEach((prop) => { + if (!isUndefined(config2[prop])) { + config[prop] = config2[prop] + } + }) + // #ifdef H5 || APP-PLUS + if (isUndefined(config.timeout) && !isUndefined(globalsConfig.timeout)) { + config.timeout = globalsConfig.timeout + } + // #endif + } else { + const defaultsKeys = [ + 'data', + // #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN + 'timeout', + // #endif + 'dataType', + // #ifndef MP-ALIPAY + 'responseType', + // #endif + // #ifdef APP-PLUS + 'sslVerify', + // #endif + // #ifdef H5 + 'withCredentials', + // #endif + // #ifdef APP-PLUS + 'firstIpv4' + // #endif + ] + config = { ...config, ...mergeKeys(defaultsKeys, globalsConfig, config2) } + } + + return config +} diff --git a/uni_modules/uv-ui-tools/libs/luch-request/core/settle.js b/uni_modules/uv-ui-tools/libs/luch-request/core/settle.js new file mode 100644 index 0000000..8d3638f --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/luch-request/core/settle.js @@ -0,0 +1,16 @@ +/** + * Resolve or reject a Promise based on response status. + * + * @param {Function} resolve A function that resolves the promise. + * @param {Function} reject A function that rejects the promise. + * @param {object} response The response. + */ +export default function settle(resolve, reject, response) { + const { validateStatus } = response.config + const status = response.statusCode + if (status && (!validateStatus || validateStatus(status))) { + resolve(response) + } else { + reject(response) + } +} diff --git a/uni_modules/uv-ui-tools/libs/luch-request/helpers/buildURL.js b/uni_modules/uv-ui-tools/libs/luch-request/helpers/buildURL.js new file mode 100644 index 0000000..472ad6a --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/luch-request/helpers/buildURL.js @@ -0,0 +1,69 @@ +'use strict' + +import * as utils from '../utils' + +function encode(val) { + return encodeURIComponent(val) + .replace(/%40/gi, '@') + .replace(/%3A/gi, ':') + .replace(/%24/g, '$') + .replace(/%2C/gi, ',') + .replace(/%20/g, '+') + .replace(/%5B/gi, '[') + .replace(/%5D/gi, ']') +} + +/** + * Build a URL by appending params to the end + * + * @param {string} url The base of the url (e.g., http://www.google.com) + * @param {object} [params] The params to be appended + * @returns {string} The formatted url + */ +export default function buildURL(url, params) { + /* eslint no-param-reassign:0 */ + if (!params) { + return url + } + + let serializedParams + if (utils.isURLSearchParams(params)) { + serializedParams = params.toString() + } else { + const parts = [] + + utils.forEach(params, (val, key) => { + if (val === null || typeof val === 'undefined') { + return + } + + if (utils.isArray(val)) { + key = `${key}[]` + } else { + val = [val] + } + + utils.forEach(val, (v) => { + if (utils.isDate(v)) { + v = v.toISOString() + } else if (utils.isObject(v)) { + v = JSON.stringify(v) + } + parts.push(`${encode(key)}=${encode(v)}`) + }) + }) + + serializedParams = parts.join('&') + } + + if (serializedParams) { + const hashmarkIndex = url.indexOf('#') + if (hashmarkIndex !== -1) { + url = url.slice(0, hashmarkIndex) + } + + url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams + } + + return url +} diff --git a/uni_modules/uv-ui-tools/libs/luch-request/helpers/combineURLs.js b/uni_modules/uv-ui-tools/libs/luch-request/helpers/combineURLs.js new file mode 100644 index 0000000..ac7c124 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/luch-request/helpers/combineURLs.js @@ -0,0 +1,14 @@ +'use strict' + +/** + * Creates a new URL by combining the specified URLs + * + * @param {string} baseURL The base URL + * @param {string} relativeURL The relative URL + * @returns {string} The combined URL + */ +export default function combineURLs(baseURL, relativeURL) { + return relativeURL + ? `${baseURL.replace(/\/+$/, '')}/${relativeURL.replace(/^\/+/, '')}` + : baseURL +} diff --git a/uni_modules/uv-ui-tools/libs/luch-request/helpers/isAbsoluteURL.js b/uni_modules/uv-ui-tools/libs/luch-request/helpers/isAbsoluteURL.js new file mode 100644 index 0000000..63c6647 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/luch-request/helpers/isAbsoluteURL.js @@ -0,0 +1,14 @@ +'use strict' + +/** + * Determines whether the specified URL is absolute + * + * @param {string} url The URL to test + * @returns {boolean} True if the specified URL is absolute, otherwise false + */ +export default function isAbsoluteURL(url) { + // A URL is considered absolute if it begins with "://" or "//" (protocol-relative URL). + // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed + // by any combination of letters, digits, plus, period, or hyphen. + return /^([a-z][a-z\d+\-.]*:)?\/\//i.test(url) +} diff --git a/uni_modules/uv-ui-tools/libs/luch-request/index.d.ts b/uni_modules/uv-ui-tools/libs/luch-request/index.d.ts new file mode 100644 index 0000000..e939ce1 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/luch-request/index.d.ts @@ -0,0 +1,116 @@ +type AnyObject = Record +type HttpPromise = Promise>; +type Tasks = UniApp.RequestTask | UniApp.UploadTask | UniApp.DownloadTask +export interface RequestTask { + abort: () => void; + offHeadersReceived: () => void; + onHeadersReceived: () => void; +} +export interface HttpRequestConfig { + /** 请求基地址 */ + baseURL?: string; + /** 请求服务器接口地址 */ + url?: string; + + /** 请求查询参数,自动拼接为查询字符串 */ + params?: AnyObject; + /** 请求体参数 */ + data?: AnyObject; + + /** 文件对应的 key */ + name?: string; + /** HTTP 请求中其他额外的 form data */ + formData?: AnyObject; + /** 要上传文件资源的路径。 */ + filePath?: string; + /** 需要上传的文件列表。使用 files 时,filePath 和 name 不生效,App、H5( 2.6.15+) */ + files?: Array<{ + name?: string; + file?: File; + uri: string; + }>; + /** 要上传的文件对象,仅H5(2.6.15+)支持 */ + file?: File; + + /** 请求头信息 */ + header?: AnyObject; + /** 请求方式 */ + method?: "GET" | "POST" | "PUT" | "DELETE" | "CONNECT" | "HEAD" | "OPTIONS" | "TRACE" | "UPLOAD" | "DOWNLOAD"; + /** 如果设为 json,会尝试对返回的数据做一次 JSON.parse */ + dataType?: string; + /** 设置响应的数据类型,支付宝小程序不支持 */ + responseType?: "text" | "arraybuffer"; + /** 自定义参数 */ + custom?: AnyObject; + /** 超时时间,仅微信小程序(2.10.0)、支付宝小程序支持 */ + timeout?: number; + /** DNS解析时优先使用ipv4,仅 App-Android 支持 (HBuilderX 2.8.0+) */ + firstIpv4?: boolean; + /** 验证 ssl 证书 仅5+App安卓端支持(HBuilderX 2.3.3+) */ + sslVerify?: boolean; + /** 跨域请求时是否携带凭证(cookies)仅H5支持(HBuilderX 2.6.15+) */ + withCredentials?: boolean; + + /** 返回当前请求的task, options。请勿在此处修改options。 */ + getTask?: (task: T, options: HttpRequestConfig) => void; + /** 全局自定义验证器 */ + validateStatus?: (statusCode: number) => boolean | void; +} +export interface HttpResponse { + config: HttpRequestConfig; + statusCode: number; + cookies: Array; + data: T; + errMsg: string; + header: AnyObject; +} +export interface HttpUploadResponse { + config: HttpRequestConfig; + statusCode: number; + data: T; + errMsg: string; +} +export interface HttpDownloadResponse extends HttpResponse { + tempFilePath: string; +} +export interface HttpError { + config: HttpRequestConfig; + statusCode?: number; + cookies?: Array; + data?: any; + errMsg: string; + header?: AnyObject; +} +export interface HttpInterceptorManager { + use( + onFulfilled?: (config: V) => Promise | V, + onRejected?: (config: E) => Promise | E + ): void; + eject(id: number): void; +} +export abstract class HttpRequestAbstract { + constructor(config?: HttpRequestConfig); + config: HttpRequestConfig; + interceptors: { + request: HttpInterceptorManager; + response: HttpInterceptorManager; + } + middleware(config: HttpRequestConfig): HttpPromise; + request(config: HttpRequestConfig): HttpPromise; + get(url: string, config?: HttpRequestConfig): HttpPromise; + upload(url: string, config?: HttpRequestConfig): HttpPromise; + delete(url: string, data?: AnyObject, config?: HttpRequestConfig): HttpPromise; + head(url: string, data?: AnyObject, config?: HttpRequestConfig): HttpPromise; + post(url: string, data?: AnyObject, config?: HttpRequestConfig): HttpPromise; + put(url: string, data?: AnyObject, config?: HttpRequestConfig): HttpPromise; + connect(url: string, data?: AnyObject, config?: HttpRequestConfig): HttpPromise; + options(url: string, data?: AnyObject, config?: HttpRequestConfig): HttpPromise; + trace(url: string, data?: AnyObject, config?: HttpRequestConfig): HttpPromise; + + download(url: string, config?: HttpRequestConfig): Promise; + + setConfig(onSend: (config: HttpRequestConfig) => HttpRequestConfig): void; +} + +declare class HttpRequest extends HttpRequestAbstract { } +export default HttpRequest; diff --git a/uni_modules/uv-ui-tools/libs/luch-request/index.js b/uni_modules/uv-ui-tools/libs/luch-request/index.js new file mode 100644 index 0000000..8fb2b44 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/luch-request/index.js @@ -0,0 +1,3 @@ +import Request from './core/Request' + +export default Request diff --git a/uni_modules/uv-ui-tools/libs/luch-request/utils.js b/uni_modules/uv-ui-tools/libs/luch-request/utils.js new file mode 100644 index 0000000..847283d --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/luch-request/utils.js @@ -0,0 +1,131 @@ +'use strict' + +// utils is a library of generic helper functions non-specific to axios + +const { toString } = Object.prototype + +/** + * Determine if a value is an Array + * + * @param {Object} val The value to test + * @returns {boolean} True if value is an Array, otherwise false + */ +export function isArray(val) { + return toString.call(val) === '[object Array]' +} + +/** + * Determine if a value is an Object + * + * @param {Object} val The value to test + * @returns {boolean} True if value is an Object, otherwise false + */ +export function isObject(val) { + return val !== null && typeof val === 'object' +} + +/** + * Determine if a value is a Date + * + * @param {Object} val The value to test + * @returns {boolean} True if value is a Date, otherwise false + */ +export function isDate(val) { + return toString.call(val) === '[object Date]' +} + +/** + * Determine if a value is a URLSearchParams object + * + * @param {Object} val The value to test + * @returns {boolean} True if value is a URLSearchParams object, otherwise false + */ +export function isURLSearchParams(val) { + return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams +} + +/** + * Iterate over an Array or an Object invoking a function for each item. + * + * If `obj` is an Array callback will be called passing + * the value, index, and complete array for each item. + * + * If 'obj' is an Object callback will be called passing + * the value, key, and complete object for each property. + * + * @param {Object|Array} obj The object to iterate + * @param {Function} fn The callback to invoke for each item + */ +export function forEach(obj, fn) { + // Don't bother if no value provided + if (obj === null || typeof obj === 'undefined') { + return + } + + // Force an array if not already something iterable + if (typeof obj !== 'object') { + /* eslint no-param-reassign:0 */ + obj = [obj] + } + + if (isArray(obj)) { + // Iterate over array values + for (let i = 0, l = obj.length; i < l; i++) { + fn.call(null, obj[i], i, obj) + } + } else { + // Iterate over object keys + for (const key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + fn.call(null, obj[key], key, obj) + } + } + } +} + +/** + * 是否为boolean 值 + * @param val + * @returns {boolean} + */ +export function isBoolean(val) { + return typeof val === 'boolean' +} + +/** + * 是否为真正的对象{} new Object + * @param {any} obj - 检测的对象 + * @returns {boolean} + */ +export function isPlainObject(obj) { + return Object.prototype.toString.call(obj) === '[object Object]' +} + +/** + * Function equal to merge with the difference being that no reference + * to original objects is kept. + * + * @see merge + * @param {Object} obj1 Object to merge + * @returns {Object} Result of all merge properties + */ +export function deepMerge(/* obj1, obj2, obj3, ... */) { + const result = {} + function assignValue(val, key) { + if (typeof result[key] === 'object' && typeof val === 'object') { + result[key] = deepMerge(result[key], val) + } else if (typeof val === 'object') { + result[key] = deepMerge({}, val) + } else { + result[key] = val + } + } + for (let i = 0, l = arguments.length; i < l; i++) { + forEach(arguments[i], assignValue) + } + return result +} + +export function isUndefined(val) { + return typeof val === 'undefined' +} diff --git a/uni_modules/uv-ui-tools/libs/luch-request/utils/clone.js b/uni_modules/uv-ui-tools/libs/luch-request/utils/clone.js new file mode 100644 index 0000000..2fee704 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/luch-request/utils/clone.js @@ -0,0 +1,264 @@ +/* eslint-disable */ +var clone = (function() { + 'use strict'; + + function _instanceof(obj, type) { + return type != null && obj instanceof type; + } + + var nativeMap; + try { + nativeMap = Map; + } catch(_) { + // maybe a reference error because no `Map`. Give it a dummy value that no + // value will ever be an instanceof. + nativeMap = function() {}; + } + + var nativeSet; + try { + nativeSet = Set; + } catch(_) { + nativeSet = function() {}; + } + + var nativePromise; + try { + nativePromise = Promise; + } catch(_) { + nativePromise = function() {}; + } + + /** + * Clones (copies) an Object using deep copying. + * + * This function supports circular references by default, but if you are certain + * there are no circular references in your object, you can save some CPU time + * by calling clone(obj, false). + * + * Caution: if `circular` is false and `parent` contains circular references, + * your program may enter an infinite loop and crash. + * + * @param `parent` - the object to be cloned + * @param `circular` - set to true if the object to be cloned may contain + * circular references. (optional - true by default) + * @param `depth` - set to a number if the object is only to be cloned to + * a particular depth. (optional - defaults to Infinity) + * @param `prototype` - sets the prototype to be used when cloning an object. + * (optional - defaults to parent prototype). + * @param `includeNonEnumerable` - set to true if the non-enumerable properties + * should be cloned as well. Non-enumerable properties on the prototype + * chain will be ignored. (optional - false by default) + */ + function clone(parent, circular, depth, prototype, includeNonEnumerable) { + if (typeof circular === 'object') { + depth = circular.depth; + prototype = circular.prototype; + includeNonEnumerable = circular.includeNonEnumerable; + circular = circular.circular; + } + // maintain two arrays for circular references, where corresponding parents + // and children have the same index + var allParents = []; + var allChildren = []; + + var useBuffer = typeof Buffer != 'undefined'; + + if (typeof circular == 'undefined') + circular = true; + + if (typeof depth == 'undefined') + depth = Infinity; + + // recurse this function so we don't reset allParents and allChildren + function _clone(parent, depth) { + // cloning null always returns null + if (parent === null) + return null; + + if (depth === 0) + return parent; + + var child; + var proto; + if (typeof parent != 'object') { + return parent; + } + + if (_instanceof(parent, nativeMap)) { + child = new nativeMap(); + } else if (_instanceof(parent, nativeSet)) { + child = new nativeSet(); + } else if (_instanceof(parent, nativePromise)) { + child = new nativePromise(function (resolve, reject) { + parent.then(function(value) { + resolve(_clone(value, depth - 1)); + }, function(err) { + reject(_clone(err, depth - 1)); + }); + }); + } else if (clone.__isArray(parent)) { + child = []; + } else if (clone.__isRegExp(parent)) { + child = new RegExp(parent.source, __getRegExpFlags(parent)); + if (parent.lastIndex) child.lastIndex = parent.lastIndex; + } else if (clone.__isDate(parent)) { + child = new Date(parent.getTime()); + } else if (useBuffer && Buffer.isBuffer(parent)) { + if (Buffer.from) { + // Node.js >= 5.10.0 + child = Buffer.from(parent); + } else { + // Older Node.js versions + child = new Buffer(parent.length); + parent.copy(child); + } + return child; + } else if (_instanceof(parent, Error)) { + child = Object.create(parent); + } else { + if (typeof prototype == 'undefined') { + proto = Object.getPrototypeOf(parent); + child = Object.create(proto); + } + else { + child = Object.create(prototype); + proto = prototype; + } + } + + if (circular) { + var index = allParents.indexOf(parent); + + if (index != -1) { + return allChildren[index]; + } + allParents.push(parent); + allChildren.push(child); + } + + if (_instanceof(parent, nativeMap)) { + parent.forEach(function(value, key) { + var keyChild = _clone(key, depth - 1); + var valueChild = _clone(value, depth - 1); + child.set(keyChild, valueChild); + }); + } + if (_instanceof(parent, nativeSet)) { + parent.forEach(function(value) { + var entryChild = _clone(value, depth - 1); + child.add(entryChild); + }); + } + + for (var i in parent) { + var attrs = Object.getOwnPropertyDescriptor(parent, i); + if (attrs) { + child[i] = _clone(parent[i], depth - 1); + } + + try { + var objProperty = Object.getOwnPropertyDescriptor(parent, i); + if (objProperty.set === 'undefined') { + // no setter defined. Skip cloning this property + continue; + } + child[i] = _clone(parent[i], depth - 1); + } catch(e){ + if (e instanceof TypeError) { + // when in strict mode, TypeError will be thrown if child[i] property only has a getter + // we can't do anything about this, other than inform the user that this property cannot be set. + continue + } else if (e instanceof ReferenceError) { + //this may happen in non strict mode + continue + } + } + + } + + if (Object.getOwnPropertySymbols) { + var symbols = Object.getOwnPropertySymbols(parent); + for (var i = 0; i < symbols.length; i++) { + // Don't need to worry about cloning a symbol because it is a primitive, + // like a number or string. + var symbol = symbols[i]; + var descriptor = Object.getOwnPropertyDescriptor(parent, symbol); + if (descriptor && !descriptor.enumerable && !includeNonEnumerable) { + continue; + } + child[symbol] = _clone(parent[symbol], depth - 1); + Object.defineProperty(child, symbol, descriptor); + } + } + + if (includeNonEnumerable) { + var allPropertyNames = Object.getOwnPropertyNames(parent); + for (var i = 0; i < allPropertyNames.length; i++) { + var propertyName = allPropertyNames[i]; + var descriptor = Object.getOwnPropertyDescriptor(parent, propertyName); + if (descriptor && descriptor.enumerable) { + continue; + } + child[propertyName] = _clone(parent[propertyName], depth - 1); + Object.defineProperty(child, propertyName, descriptor); + } + } + + return child; + } + + return _clone(parent, depth); + } + + /** + * Simple flat clone using prototype, accepts only objects, usefull for property + * override on FLAT configuration object (no nested props). + * + * USE WITH CAUTION! This may not behave as you wish if you do not know how this + * works. + */ + clone.clonePrototype = function clonePrototype(parent) { + if (parent === null) + return null; + + var c = function () {}; + c.prototype = parent; + return new c(); + }; + +// private utility functions + + function __objToStr(o) { + return Object.prototype.toString.call(o); + } + clone.__objToStr = __objToStr; + + function __isDate(o) { + return typeof o === 'object' && __objToStr(o) === '[object Date]'; + } + clone.__isDate = __isDate; + + function __isArray(o) { + return typeof o === 'object' && __objToStr(o) === '[object Array]'; + } + clone.__isArray = __isArray; + + function __isRegExp(o) { + return typeof o === 'object' && __objToStr(o) === '[object RegExp]'; + } + clone.__isRegExp = __isRegExp; + + function __getRegExpFlags(re) { + var flags = ''; + if (re.global) flags += 'g'; + if (re.ignoreCase) flags += 'i'; + if (re.multiline) flags += 'm'; + return flags; + } + clone.__getRegExpFlags = __getRegExpFlags; + + return clone; +})(); + +export default clone diff --git a/uni_modules/uv-ui-tools/libs/mixin/button.js b/uni_modules/uv-ui-tools/libs/mixin/button.js new file mode 100644 index 0000000..0c019c2 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/mixin/button.js @@ -0,0 +1,13 @@ +export default { + props: { + lang: String, + sessionFrom: String, + sendMessageTitle: String, + sendMessagePath: String, + sendMessageImg: String, + showMessageCard: Boolean, + appParameter: String, + formType: String, + openType: String + } +} diff --git a/uni_modules/uv-ui-tools/libs/mixin/mixin.js b/uni_modules/uv-ui-tools/libs/mixin/mixin.js new file mode 100644 index 0000000..e1f7c4f --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/mixin/mixin.js @@ -0,0 +1,166 @@ +import * as index from '../function/index.js'; +import * as test from '../function/test.js'; +export default { + // 定义每个组件都可能需要用到的外部样式以及类名 + props: { + // 每个组件都有的父组件传递的样式,可以为字符串或者对象形式 + customStyle: { + type: [Object, String], + default: () => ({}) + }, + customClass: { + type: String, + default: '' + }, + // 跳转的页面路径 + url: { + type: String, + default: '' + }, + // 页面跳转的类型 + linkType: { + type: String, + default: 'navigateTo' + } + }, + data() { + return {} + }, + onLoad() { + // getRect挂载到$uv上,因为这方法需要使用in(this),所以无法把它独立成一个单独的文件导出 + this.$uv.getRect = this.$uvGetRect + }, + created() { + // 组件当中,只有created声明周期,为了能在组件使用,故也在created中将方法挂载到$uv + this.$uv.getRect = this.$uvGetRect + }, + computed: { + $uv() { + return { + ...index, + test, + unit: uni?.$uv?.config?.unit + } + }, + /** + * 生成bem规则类名 + * 由于微信小程序,H5,nvue之间绑定class的差异,无法通过:class="[bem()]"的形式进行同用 + * 故采用如下折中做法,最后返回的是数组(一般平台)或字符串(支付宝和字节跳动平台),类似['a', 'b', 'c']或'a b c'的形式 + * @param {String} name 组件名称 + * @param {Array} fixed 一直会存在的类名 + * @param {Array} change 会根据变量值为true或者false而出现或者隐藏的类名 + * @returns {Array|string} + */ + bem() { + return function(name, fixed, change) { + // 类名前缀 + const prefix = `uv-${name}--` + const classes = {} + if (fixed) { + fixed.map((item) => { + // 这里的类名,会一直存在 + classes[prefix + this[item]] = true + }) + } + if (change) { + change.map((item) => { + // 这里的类名,会根据this[item]的值为true或者false,而进行添加或者移除某一个类 + this[item] ? (classes[prefix + item] = this[item]) : (delete classes[prefix + item]) + }) + } + return Object.keys(classes) + // 支付宝,头条小程序无法动态绑定一个数组类名,否则解析出来的结果会带有",",而导致失效 + // #ifdef MP-ALIPAY || MP-TOUTIAO || MP-LARK || MP-BAIDU + .join(' ') + // #endif + } + } + }, + methods: { + // 跳转某一个页面 + openPage(urlKey = 'url') { + const url = this[urlKey] + if (url) { + // 执行类似uni.navigateTo的方法 + uni[this.linkType]({ + url + }) + } + }, + // 查询节点信息 + // 目前此方法在支付宝小程序中无法获取组件跟接点的尺寸,为支付宝的bug(2020-07-21) + // 解决办法为在组件根部再套一个没有任何作用的view元素 + $uvGetRect(selector, all) { + return new Promise((resolve) => { + uni.createSelectorQuery() + .in(this)[all ? 'selectAll' : 'select'](selector) + .boundingClientRect((rect) => { + if (all && Array.isArray(rect) && rect.length) { + resolve(rect) + } + if (!all && rect) { + resolve(rect) + } + }) + .exec() + }) + }, + getParentData(parentName = '') { + // 避免在created中去定义parent变量 + if (!this.parent) this.parent = {} + // 这里的本质原理是,通过获取父组件实例(也即类似uv-radio的父组件uv-radio-group的this) + // 将父组件this中对应的参数,赋值给本组件(uv-radio的this)的parentData对象中对应的属性 + // 之所以需要这么做,是因为所有端中,头条小程序不支持通过this.parent.xxx去监听父组件参数的变化 + // 此处并不会自动更新子组件的数据,而是依赖父组件uv-radio-group去监听data的变化,手动调用更新子组件的方法去重新获取 + this.parent = this.$uv.$parent.call(this, parentName) + if (this.parent.children) { + // 如果父组件的children不存在本组件的实例,才将本实例添加到父组件的children中 + this.parent.children.indexOf(this) === -1 && this.parent.children.push(this) + } + if (this.parent && this.parentData) { + // 历遍parentData中的属性,将parent中的同名属性赋值给parentData + Object.keys(this.parentData).map((key) => { + this.parentData[key] = this.parent[key] + }) + } + }, + // 阻止事件冒泡 + preventEvent(e) { + e && typeof(e.stopPropagation) === 'function' && e.stopPropagation() + }, + // 空操作 + noop(e) { + this.preventEvent(e) + } + }, + onReachBottom() { + uni.$emit('uvOnReachBottom') + }, + beforeDestroy() { + // 判断当前页面是否存在parent和chldren,一般在checkbox和checkbox-group父子联动的场景会有此情况 + // 组件销毁时,移除子组件在父组件children数组中的实例,释放资源,避免数据混乱 + if (this.parent && test.array(this.parent.children)) { + // 组件销毁时,移除父组件中的children数组中对应的实例 + const childrenList = this.parent.children + childrenList.map((child, index) => { + // 如果相等,则移除 + if (child === this) { + childrenList.splice(index, 1) + } + }) + } + }, + // 兼容vue3 + unmounted() { + if (this.parent && test.array(this.parent.children)) { + // 组件销毁时,移除父组件中的children数组中对应的实例 + const childrenList = this.parent.children + childrenList.map((child, index) => { + // 如果相等,则移除 + if (child === this) { + childrenList.splice(index, 1) + } + }) + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js b/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js new file mode 100644 index 0000000..90b6903 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js @@ -0,0 +1,8 @@ +export default { + // #ifdef MP-WEIXIN + // 将自定义节点设置成虚拟的(去掉自定义组件包裹层),更加接近Vue组件的表现,能更好的使用flex属性 + options: { + virtualHost: true + } + // #endif +} \ No newline at end of file diff --git a/uni_modules/uv-ui-tools/libs/mixin/mpShare.js b/uni_modules/uv-ui-tools/libs/mixin/mpShare.js new file mode 100644 index 0000000..c9695a0 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/mixin/mpShare.js @@ -0,0 +1,13 @@ +export default { + onLoad() { + // 设置默认的转发参数 + uni.$uv.mpShare = { + title: '', // 默认为小程序名称 + path: '', // 默认为当前页面路径 + imageUrl: '' // 默认为当前页面的截图 + } + }, + onShareAppMessage() { + return uni.$uv.mpShare + } +} \ No newline at end of file diff --git a/uni_modules/uv-ui-tools/libs/mixin/openType.js b/uni_modules/uv-ui-tools/libs/mixin/openType.js new file mode 100644 index 0000000..1b94b7e --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/mixin/openType.js @@ -0,0 +1,47 @@ +export default { + props: { + openType: String + }, + emits: ['getphonenumber','getuserinfo','error','opensetting','launchapp','contact','chooseavatar','addgroupapp','chooseaddress','subscribe','login','im'], + methods: { + onGetPhoneNumber(event) { + this.$emit('getphonenumber', event.detail) + }, + onGetUserInfo(event) { + this.$emit('getuserinfo', event.detail) + }, + onError(event) { + this.$emit('error', event.detail) + }, + onOpenSetting(event) { + this.$emit('opensetting', event.detail) + }, + onLaunchApp(event) { + this.$emit('launchapp', event.detail) + }, + onContact(event) { + this.$emit('contact', event.detail) + }, + onChooseavatar(event) { + this.$emit('chooseavatar', event.detail) + }, + onAgreeprivacyauthorization(event) { + this.$emit('agreeprivacyauthorization', event.detail) + }, + onAddgroupapp(event) { + this.$emit('addgroupapp', event.detail) + }, + onChooseaddress(event) { + this.$emit('chooseaddress', event.detail) + }, + onSubscribe(event) { + this.$emit('subscribe', event.detail) + }, + onLogin(event) { + this.$emit('login', event.detail) + }, + onIm(event) { + this.$emit('im', event.detail) + } + } +} diff --git a/uni_modules/uv-ui-tools/libs/mixin/touch.js b/uni_modules/uv-ui-tools/libs/mixin/touch.js new file mode 100644 index 0000000..0ecbd88 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/mixin/touch.js @@ -0,0 +1,59 @@ +const MIN_DISTANCE = 10 + +function getDirection(x, y) { + if (x > y && x > MIN_DISTANCE) { + return 'horizontal' + } + if (y > x && y > MIN_DISTANCE) { + return 'vertical' + } + return '' +} + +export default { + methods: { + getTouchPoint(e) { + if (!e) { + return { + x: 0, + y: 0 + } + } if (e.touches && e.touches[0]) { + return { + x: e.touches[0].pageX, + y: e.touches[0].pageY + } + } if (e.changedTouches && e.changedTouches[0]) { + return { + x: e.changedTouches[0].pageX, + y: e.changedTouches[0].pageY + } + } + return { + x: e.clientX || 0, + y: e.clientY || 0 + } + }, + resetTouchStatus() { + this.direction = '' + this.deltaX = 0 + this.deltaY = 0 + this.offsetX = 0 + this.offsetY = 0 + }, + touchStart(event) { + this.resetTouchStatus() + const touch = this.getTouchPoint(event) + this.startX = touch.x + this.startY = touch.y + }, + touchMove(event) { + const touch = this.getTouchPoint(event) + this.deltaX = touch.x - this.startX + this.deltaY = touch.y - this.startY + this.offsetX = Math.abs(this.deltaX) + this.offsetY = Math.abs(this.deltaY) + this.direction = this.direction || getDirection(this.offsetX, this.offsetY) + } + } +} diff --git a/uni_modules/uv-ui-tools/libs/util/dayjs.js b/uni_modules/uv-ui-tools/libs/util/dayjs.js new file mode 100644 index 0000000..c84ab68 --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/util/dayjs.js @@ -0,0 +1,216 @@ +var __getOwnPropNames = Object.getOwnPropertyNames; +var __commonJS = (cb, mod) => function __require() { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; +}; + +var require_dayjs_min = __commonJS({ + "uvuidayjs"(exports, module) { + !function(t, e) { + "object" == typeof exports && "undefined" != typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define(e) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs = e(); + }(exports, function() { + "use strict"; + var t = 1e3, e = 6e4, n = 36e5, r = "millisecond", i = "second", s = "minute", u = "hour", a = "day", o = "week", f = "month", h = "quarter", c = "year", d = "date", l = "Invalid Date", $ = /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/, y = /\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g, M = { name: "en", weekdays: "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), months: "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), ordinal: function(t2) { + var e2 = ["th", "st", "nd", "rd"], n2 = t2 % 100; + return "[" + t2 + (e2[(n2 - 20) % 10] || e2[n2] || e2[0]) + "]"; + } }, m = function(t2, e2, n2) { + var r2 = String(t2); + return !r2 || r2.length >= e2 ? t2 : "" + Array(e2 + 1 - r2.length).join(n2) + t2; + }, v = { s: m, z: function(t2) { + var e2 = -t2.utcOffset(), n2 = Math.abs(e2), r2 = Math.floor(n2 / 60), i2 = n2 % 60; + return (e2 <= 0 ? "+" : "-") + m(r2, 2, "0") + ":" + m(i2, 2, "0"); + }, m: function t2(e2, n2) { + if (e2.date() < n2.date()) + return -t2(n2, e2); + var r2 = 12 * (n2.year() - e2.year()) + (n2.month() - e2.month()), i2 = e2.clone().add(r2, f), s2 = n2 - i2 < 0, u2 = e2.clone().add(r2 + (s2 ? -1 : 1), f); + return +(-(r2 + (n2 - i2) / (s2 ? i2 - u2 : u2 - i2)) || 0); + }, a: function(t2) { + return t2 < 0 ? Math.ceil(t2) || 0 : Math.floor(t2); + }, p: function(t2) { + return { M: f, y: c, w: o, d: a, D: d, h: u, m: s, s: i, ms: r, Q: h }[t2] || String(t2 || "").toLowerCase().replace(/s$/, ""); + }, u: function(t2) { + return void 0 === t2; + } }, g = "en", D = {}; + D[g] = M; + var p = function(t2) { + return t2 instanceof _; + }, S = function t2(e2, n2, r2) { + var i2; + if (!e2) + return g; + if ("string" == typeof e2) { + var s2 = e2.toLowerCase(); + D[s2] && (i2 = s2), n2 && (D[s2] = n2, i2 = s2); + var u2 = e2.split("-"); + if (!i2 && u2.length > 1) + return t2(u2[0]); + } else { + var a2 = e2.name; + D[a2] = e2, i2 = a2; + } + return !r2 && i2 && (g = i2), i2 || !r2 && g; + }, w = function(t2, e2) { + if (p(t2)) + return t2.clone(); + var n2 = "object" == typeof e2 ? e2 : {}; + return n2.date = t2, n2.args = arguments, new _(n2); + }, O = v; + O.l = S, O.i = p, O.w = function(t2, e2) { + return w(t2, { locale: e2.$L, utc: e2.$u, x: e2.$x, $offset: e2.$offset }); + }; + var _ = function() { + function M2(t2) { + this.$L = S(t2.locale, null, true), this.parse(t2); + } + var m2 = M2.prototype; + return m2.parse = function(t2) { + this.$d = function(t3) { + var e2 = t3.date, n2 = t3.utc; + if (null === e2) + return new Date(NaN); + if (O.u(e2)) + return new Date(); + if (e2 instanceof Date) + return new Date(e2); + if ("string" == typeof e2 && !/Z$/i.test(e2)) { + var r2 = e2.match($); + if (r2) { + var i2 = r2[2] - 1 || 0, s2 = (r2[7] || "0").substring(0, 3); + return n2 ? new Date(Date.UTC(r2[1], i2, r2[3] || 1, r2[4] || 0, r2[5] || 0, r2[6] || 0, s2)) : new Date(r2[1], i2, r2[3] || 1, r2[4] || 0, r2[5] || 0, r2[6] || 0, s2); + } + } + return new Date(e2); + }(t2), this.$x = t2.x || {}, this.init(); + }, m2.init = function() { + var t2 = this.$d; + this.$y = t2.getFullYear(), this.$M = t2.getMonth(), this.$D = t2.getDate(), this.$W = t2.getDay(), this.$H = t2.getHours(), this.$m = t2.getMinutes(), this.$s = t2.getSeconds(), this.$ms = t2.getMilliseconds(); + }, m2.$utils = function() { + return O; + }, m2.isValid = function() { + return !(this.$d.toString() === l); + }, m2.isSame = function(t2, e2) { + var n2 = w(t2); + return this.startOf(e2) <= n2 && n2 <= this.endOf(e2); + }, m2.isAfter = function(t2, e2) { + return w(t2) < this.startOf(e2); + }, m2.isBefore = function(t2, e2) { + return this.endOf(e2) < w(t2); + }, m2.$g = function(t2, e2, n2) { + return O.u(t2) ? this[e2] : this.set(n2, t2); + }, m2.unix = function() { + return Math.floor(this.valueOf() / 1e3); + }, m2.valueOf = function() { + return this.$d.getTime(); + }, m2.startOf = function(t2, e2) { + var n2 = this, r2 = !!O.u(e2) || e2, h2 = O.p(t2), l2 = function(t3, e3) { + var i2 = O.w(n2.$u ? Date.UTC(n2.$y, e3, t3) : new Date(n2.$y, e3, t3), n2); + return r2 ? i2 : i2.endOf(a); + }, $2 = function(t3, e3) { + return O.w(n2.toDate()[t3].apply(n2.toDate("s"), (r2 ? [0, 0, 0, 0] : [23, 59, 59, 999]).slice(e3)), n2); + }, y2 = this.$W, M3 = this.$M, m3 = this.$D, v2 = "set" + (this.$u ? "UTC" : ""); + switch (h2) { + case c: + return r2 ? l2(1, 0) : l2(31, 11); + case f: + return r2 ? l2(1, M3) : l2(0, M3 + 1); + case o: + var g2 = this.$locale().weekStart || 0, D2 = (y2 < g2 ? y2 + 7 : y2) - g2; + return l2(r2 ? m3 - D2 : m3 + (6 - D2), M3); + case a: + case d: + return $2(v2 + "Hours", 0); + case u: + return $2(v2 + "Minutes", 1); + case s: + return $2(v2 + "Seconds", 2); + case i: + return $2(v2 + "Milliseconds", 3); + default: + return this.clone(); + } + }, m2.endOf = function(t2) { + return this.startOf(t2, false); + }, m2.$set = function(t2, e2) { + var n2, o2 = O.p(t2), h2 = "set" + (this.$u ? "UTC" : ""), l2 = (n2 = {}, n2[a] = h2 + "Date", n2[d] = h2 + "Date", n2[f] = h2 + "Month", n2[c] = h2 + "FullYear", n2[u] = h2 + "Hours", n2[s] = h2 + "Minutes", n2[i] = h2 + "Seconds", n2[r] = h2 + "Milliseconds", n2)[o2], $2 = o2 === a ? this.$D + (e2 - this.$W) : e2; + if (o2 === f || o2 === c) { + var y2 = this.clone().set(d, 1); + y2.$d[l2]($2), y2.init(), this.$d = y2.set(d, Math.min(this.$D, y2.daysInMonth())).$d; + } else + l2 && this.$d[l2]($2); + return this.init(), this; + }, m2.set = function(t2, e2) { + return this.clone().$set(t2, e2); + }, m2.get = function(t2) { + return this[O.p(t2)](); + }, m2.add = function(r2, h2) { + var d2, l2 = this; + r2 = Number(r2); + var $2 = O.p(h2), y2 = function(t2) { + var e2 = w(l2); + return O.w(e2.date(e2.date() + Math.round(t2 * r2)), l2); + }; + if ($2 === f) + return this.set(f, this.$M + r2); + if ($2 === c) + return this.set(c, this.$y + r2); + if ($2 === a) + return y2(1); + if ($2 === o) + return y2(7); + var M3 = (d2 = {}, d2[s] = e, d2[u] = n, d2[i] = t, d2)[$2] || 1, m3 = this.$d.getTime() + r2 * M3; + return O.w(m3, this); + }, m2.subtract = function(t2, e2) { + return this.add(-1 * t2, e2); + }, m2.format = function(t2) { + var e2 = this, n2 = this.$locale(); + if (!this.isValid()) + return n2.invalidDate || l; + var r2 = t2 || "YYYY-MM-DDTHH:mm:ssZ", i2 = O.z(this), s2 = this.$H, u2 = this.$m, a2 = this.$M, o2 = n2.weekdays, f2 = n2.months, h2 = function(t3, n3, i3, s3) { + return t3 && (t3[n3] || t3(e2, r2)) || i3[n3].slice(0, s3); + }, c2 = function(t3) { + return O.s(s2 % 12 || 12, t3, "0"); + }, d2 = n2.meridiem || function(t3, e3, n3) { + var r3 = t3 < 12 ? "AM" : "PM"; + return n3 ? r3.toLowerCase() : r3; + }, $2 = { YY: String(this.$y).slice(-2), YYYY: this.$y, M: a2 + 1, MM: O.s(a2 + 1, 2, "0"), MMM: h2(n2.monthsShort, a2, f2, 3), MMMM: h2(f2, a2), D: this.$D, DD: O.s(this.$D, 2, "0"), d: String(this.$W), dd: h2(n2.weekdaysMin, this.$W, o2, 2), ddd: h2(n2.weekdaysShort, this.$W, o2, 3), dddd: o2[this.$W], H: String(s2), HH: O.s(s2, 2, "0"), h: c2(1), hh: c2(2), a: d2(s2, u2, true), A: d2(s2, u2, false), m: String(u2), mm: O.s(u2, 2, "0"), s: String(this.$s), ss: O.s(this.$s, 2, "0"), SSS: O.s(this.$ms, 3, "0"), Z: i2 }; + return r2.replace(y, function(t3, e3) { + return e3 || $2[t3] || i2.replace(":", ""); + }); + }, m2.utcOffset = function() { + return 15 * -Math.round(this.$d.getTimezoneOffset() / 15); + }, m2.diff = function(r2, d2, l2) { + var $2, y2 = O.p(d2), M3 = w(r2), m3 = (M3.utcOffset() - this.utcOffset()) * e, v2 = this - M3, g2 = O.m(this, M3); + return g2 = ($2 = {}, $2[c] = g2 / 12, $2[f] = g2, $2[h] = g2 / 3, $2[o] = (v2 - m3) / 6048e5, $2[a] = (v2 - m3) / 864e5, $2[u] = v2 / n, $2[s] = v2 / e, $2[i] = v2 / t, $2)[y2] || v2, l2 ? g2 : O.a(g2); + }, m2.daysInMonth = function() { + return this.endOf(f).$D; + }, m2.$locale = function() { + return D[this.$L]; + }, m2.locale = function(t2, e2) { + if (!t2) + return this.$L; + var n2 = this.clone(), r2 = S(t2, e2, true); + return r2 && (n2.$L = r2), n2; + }, m2.clone = function() { + return O.w(this.$d, this); + }, m2.toDate = function() { + return new Date(this.valueOf()); + }, m2.toJSON = function() { + return this.isValid() ? this.toISOString() : null; + }, m2.toISOString = function() { + return this.$d.toISOString(); + }, m2.toString = function() { + return this.$d.toUTCString(); + }, M2; + }(), T = _.prototype; + return w.prototype = T, [["$ms", r], ["$s", i], ["$m", s], ["$H", u], ["$W", a], ["$M", f], ["$y", c], ["$D", d]].forEach(function(t2) { + T[t2[1]] = function(e2) { + return this.$g(e2, t2[0], t2[1]); + }; + }), w.extend = function(t2, e2) { + return t2.$i || (t2(e2, _, w), t2.$i = true), w; + }, w.locale = S, w.isDayjs = p, w.unix = function(t2) { + return w(1e3 * t2); + }, w.en = D[g], w.Ls = D, w.p = {}, w; + }); + } +}); +export default require_dayjs_min(); diff --git a/uni_modules/uv-ui-tools/libs/util/route.js b/uni_modules/uv-ui-tools/libs/util/route.js new file mode 100644 index 0000000..80c0afd --- /dev/null +++ b/uni_modules/uv-ui-tools/libs/util/route.js @@ -0,0 +1,126 @@ +/** + * 路由跳转方法,该方法相对于直接使用uni.xxx的好处是使用更加简单快捷 + * 并且带有路由拦截功能 + */ +import { queryParams, deepMerge, page } from '@/uni_modules/uv-ui-tools/libs/function/index.js' +class Router { + constructor() { + // 原始属性定义 + this.config = { + type: 'navigateTo', + url: '', + delta: 1, // navigateBack页面后退时,回退的层数 + params: {}, // 传递的参数 + animationType: 'pop-in', // 窗口动画,只在APP有效 + animationDuration: 300, // 窗口动画持续时间,单位毫秒,只在APP有效 + intercept: false ,// 是否需要拦截 + events: {} // 页面间通信接口,用于监听被打开页面发送到当前页面的数据。hbuilderx 2.8.9+ 开始支持。 + } + // 因为route方法是需要对外赋值给另外的对象使用,同时route内部有使用this,会导致route失去上下文 + // 这里在构造函数中进行this绑定 + this.route = this.route.bind(this) + } + + // 判断url前面是否有"/",如果没有则加上,否则无法跳转 + addRootPath(url) { + return url[0] === '/' ? url : `/${url}` + } + + // 整合路由参数 + mixinParam(url, params) { + url = url && this.addRootPath(url) + + // 使用正则匹配,主要依据是判断是否有"/","?","="等,如“/page/index/index?name=mary" + // 如果有url中有get参数,转换后无需带上"?" + let query = '' + if (/.*\/.*\?.*=.*/.test(url)) { + // object对象转为get类型的参数 + query = queryParams(params, false) + // 因为已有get参数,所以后面拼接的参数需要带上"&"隔开 + return url += `&${query}` + } + // 直接拼接参数,因为此处url中没有后面的query参数,也就没有"?/&"之类的符号 + query = queryParams(params) + return url += query + } + + // 对外的方法名称 + async route(options = {}, params = {}) { + // 合并用户的配置和内部的默认配置 + let mergeConfig = {} + + if (typeof options === 'string') { + // 如果options为字符串,则为route(url, params)的形式 + mergeConfig.url = this.mixinParam(options, params) + mergeConfig.type = 'navigateTo' + } else { + mergeConfig = deepMerge(this.config, options) + // 否则正常使用mergeConfig中的url和params进行拼接 + mergeConfig.url = this.mixinParam(options.url, options.params) + } + // 如果本次跳转的路径和本页面路径一致,不执行跳转,防止用户快速点击跳转按钮,造成多次跳转同一个页面的问题 + if (mergeConfig.url === page()) return + + if (params.intercept) { + mergeConfig.intercept = params.intercept + } + // params参数也带给拦截器 + mergeConfig.params = params + // 合并内外部参数 + mergeConfig = deepMerge(this.config, mergeConfig) + // 判断用户是否定义了拦截器 + if (typeof mergeConfig.intercept === 'function') { + // 定一个promise,根据用户执行resolve(true)或者resolve(false)来决定是否进行路由跳转 + const isNext = await new Promise((resolve, reject) => { + mergeConfig.intercept(mergeConfig, resolve) + }) + // 如果isNext为true,则执行路由跳转 + isNext && this.openPage(mergeConfig) + } else { + this.openPage(mergeConfig) + } + } + + // 执行路由跳转 + openPage(config) { + // 解构参数 + const { + url, + type, + delta, + animationType, + animationDuration, + events + } = config + if (config.type == 'navigateTo' || config.type == 'to') { + uni.navigateTo({ + url, + animationType, + animationDuration, + events + }) + } + if (config.type == 'redirectTo' || config.type == 'redirect') { + uni.redirectTo({ + url + }) + } + if (config.type == 'switchTab' || config.type == 'tab') { + uni.switchTab({ + url + }) + } + if (config.type == 'reLaunch' || config.type == 'launch') { + uni.reLaunch({ + url + }) + } + if (config.type == 'navigateBack' || config.type == 'back') { + uni.navigateBack({ + delta + }) + } + } +} + +export default (new Router()).route \ No newline at end of file diff --git a/uni_modules/uv-ui-tools/package.json b/uni_modules/uv-ui-tools/package.json new file mode 100644 index 0000000..9750b06 --- /dev/null +++ b/uni_modules/uv-ui-tools/package.json @@ -0,0 +1,81 @@ +{ + "id": "uv-ui-tools", + "displayName": "uv-ui-tools 工具集 全面兼容vue3+2、app、h5、小程序等多端", + "version": "1.1.20", + "description": "uv-ui-tools,集成工具库,强大的Http请求封装,清晰的文档说明,开箱即用。方便使用,可以全局使用", + "keywords": [ + "uv-ui-tools,uv-ui组件库,工具集,uvui,uView2.x" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "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", + "钉钉": "y", + "快手": "y", + "飞书": "y", + "京东": "y" + }, + "快应用": { + "华为": "y", + "联盟": "y" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uv-ui-tools/readme.md b/uni_modules/uv-ui-tools/readme.md new file mode 100644 index 0000000..79a7df5 --- /dev/null +++ b/uni_modules/uv-ui-tools/readme.md @@ -0,0 +1,23 @@ +## uv-ui-tools 工具集 + +> **组件名:uv-ui-tools** + +uv-ui工具集成,包括网络Http请求、便捷工具、节流防抖、对象操作、时间格式化、路由跳转、全局唯一标识符、规则校验等等。 + +该组件推荐配合[uv-ui组件库](https://www.uvui.cn/components/intro.html)使用,单独下载也可以在自己项目中使用,需要做相应的配置,可查看文档。强烈推荐使用[uv-ui组件库](https://www.uvui.cn/components/intro.html),导入组件都会自动导入`uv-ui-tools`。需要在自己的项目中使用请参考[扩展配置](https://www.uvui.cn/components/setting.html)。 + +uv-ui破釜沉舟之兼容vue3+2、app、h5、多端小程序的uni-app生态框架,大部分组件基于uView2.x,在经过改进后全面支持vue3,部分组件做了进一步的优化,修复大量BUG,支持单独导入,方便开发者选择导入需要的组件。开箱即用,灵活配置。 + +# 查看文档 + +## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) (请不要 下载插件ZIP) + +### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui) + + + +![image](https://mp-a667b617-c5f1-4a2d-9a54-683a67cff588.cdn.bspapp.com/uv-ui/banner.png) + + + +#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:官方QQ群 \ No newline at end of file diff --git a/uni_modules/uv-ui-tools/theme.scss b/uni_modules/uv-ui-tools/theme.scss new file mode 100644 index 0000000..cfaae92 --- /dev/null +++ b/uni_modules/uv-ui-tools/theme.scss @@ -0,0 +1,43 @@ +// 此文件为uvUI的主题变量,这些变量目前只能通过uni.scss引入才有效,另外由于 +// uni.scss中引入的样式会同时混入到全局样式文件和单独每一个页面的样式中,造成微信程序包太大, +// 故uni.scss只建议放scss变量名相关样式,其他的样式可以通过main.js或者App.vue引入 + +$uv-main-color: #303133; +$uv-content-color: #606266; +$uv-tips-color: #909193; +$uv-light-color: #c0c4cc; +$uv-border-color: #dadbde; +$uv-bg-color: #f3f4f6; +$uv-disabled-color: #c8c9cc; + +$uv-primary: #3c9cff; +$uv-primary-dark: #398ade; +$uv-primary-disabled: #9acafc; +$uv-primary-light: #ecf5ff; + +$uv-warning: #f9ae3d; +$uv-warning-dark: #f1a532; +$uv-warning-disabled: #f9d39b; +$uv-warning-light: #fdf6ec; + +$uv-success: #5ac725; +$uv-success-dark: #53c21d; +$uv-success-disabled: #a9e08f; +$uv-success-light: #f5fff0; + +$uv-error: #f56c6c; +$uv-error-dark: #e45656; +$uv-error-disabled: #f7b2b2; +$uv-error-light: #fef0f0; + +$uv-info: #909399; +$uv-info-dark: #767a82; +$uv-info-disabled: #c4c6c9; +$uv-info-light: #f4f4f5; + +@mixin flex($direction: row) { + /* #ifndef APP-NVUE */ + display: flex; + /* #endif */ + flex-direction: $direction; +} \ No newline at end of file diff --git a/uni_modules/uview-ui/LICENSE b/uni_modules/uview-ui/LICENSE new file mode 100644 index 0000000..4db40ef --- /dev/null +++ b/uni_modules/uview-ui/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 www.uviewui.com + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/uni_modules/uview-ui/README.md b/uni_modules/uview-ui/README.md new file mode 100644 index 0000000..c78ff47 --- /dev/null +++ b/uni_modules/uview-ui/README.md @@ -0,0 +1,66 @@ +

+ logo +

+

uView 2.0

+

多平台快速开发的UI框架

+ +[![stars](https://img.shields.io/github/stars/umicro/uView2.0?style=flat-square&logo=GitHub)](https://github.com/umicro/uView2.0) +[![forks](https://img.shields.io/github/forks/umicro/uView2.0?style=flat-square&logo=GitHub)](https://github.com/umicro/uView2.0) +[![issues](https://img.shields.io/github/issues/umicro/uView2.0?style=flat-square&logo=GitHub)](https://github.com/umicro/uView2.0/issues) +[![Website](https://img.shields.io/badge/uView-up-blue?style=flat-square)](https://uviewui.com) +[![release](https://img.shields.io/github/v/release/umicro/uView2.0?style=flat-square)](https://gitee.com/umicro/uView2.0/releases) +[![license](https://img.shields.io/github/license/umicro/uView2.0?style=flat-square)](https://en.wikipedia.org/wiki/MIT_License) + +## 说明 + +uView UI,是[uni-app](https://uniapp.dcloud.io/)全面兼容nvue的uni-app生态框架,全面的组件和便捷的工具会让您信手拈来,如鱼得水 + +## [官方文档:https://uviewui.com](https://uviewui.com) + + +## 预览 + +您可以通过**微信**扫码,查看最佳的演示效果。 +
+
+ + + +## 链接 + +- [官方文档](https://www.uviewui.com/) +- [更新日志](https://www.uviewui.com/components/changelog.html) +- [升级指南](https://www.uviewui.com/components/changeGuide.html) +- [关于我们](https://www.uviewui.com/cooperation/about.html) + +## 交流反馈 + +欢迎加入我们的QQ群交流反馈:[点此跳转](https://www.uviewui.com/components/addQQGroup.html) + +## 关于PR + +> 我们非常乐意接受各位的优质PR,但在此之前我希望您了解uView2.0是一个需要兼容多个平台的(小程序、h5、ios app、android app)包括nvue页面、vue页面。 +> 所以希望在您修复bug并提交之前尽可能的去这些平台测试一下兼容性。最好能携带测试截图以方便审核。非常感谢! + +## 安装 + +#### **uni-app插件市场链接** —— [https://ext.dcloud.net.cn/plugin?id=1593](https://ext.dcloud.net.cn/plugin?id=1593) + +请通过[官网安装文档](https://www.uviewui.com/components/install.html)了解更详细的内容 + +## 快速上手 + +请通过[快速上手](https://uviewui.com/components/quickstart.html)了解更详细的内容 + +## 使用方法 +配置easycom规则后,自动按需引入,无需`import`组件,直接引用即可。 + +```html + +``` + +## 版权信息 +uView遵循[MIT](https://en.wikipedia.org/wiki/MIT_License)开源协议,意味着您无需支付任何费用,也无需授权,即可将uView应用到您的产品中。 + diff --git a/uni_modules/uview-ui/changelog.md b/uni_modules/uview-ui/changelog.md new file mode 100644 index 0000000..f2bae72 --- /dev/null +++ b/uni_modules/uview-ui/changelog.md @@ -0,0 +1,362 @@ +## 2.0.36(2023-03-27) +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 重构`deepClone` & `deepMerge`方法 +2. 其他优化 +## 2.0.34(2022-09-24) +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. `u-input`、`u-textarea`增加`ignoreCompositionEvent`属性 +2. 修复`route`方法调用可能报错的问题 +3. 修复`u-no-network`组件`z-index`无效的问题 +4. 修复`textarea`组件在h5上confirmType=""报错的问题 +5. `u-rate`适配`nvue` +6. 优化验证手机号码的正则表达式(根据工信部发布的《电信网编号计划(2017年版)》进行修改。) +7. `form-item`添加`labelPosition`属性 +8. `u-calendar`修复`maxDate`设置为当前日期,并且当前时间大于08:00时无法显示日期列表的问题 (#724) +9. `u-radio`增加一个默认插槽用于自定义修改label内容 (#680) +10. 修复`timeFormat`函数在safari重的兼容性问题 (#664) +## 2.0.33(2022-06-17) +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 修复`loadmore`组件`lineColor`类型错误问题 +2. 修复`u-parse`组件`imgtap`、`linktap`不生效问题 +## 2.0.32(2022-06-16) +# uView2.0重磅发布,利剑出鞘,一统江湖 +1. `u-loadmore`新增自定义颜色、虚/实线 +2. 修复`u-swiper-action`组件部分平台不能上下滑动的问题 +3. 修复`u-list`回弹问题 +4. 修复`notice-bar`组件动画在低端安卓机可能会抖动的问题 +5. `u-loading-page`添加控制图标大小的属性`iconSize` +6. 修复`u-tooltip`组件`color`参数不生效的问题 +7. 修复`u--input`组件使用`blur`事件输出为`undefined`的bug +8. `u-code-input`组件新增键盘弹起时,是否自动上推页面参数`adjustPosition` +9. 修复`image`组件`load`事件无回调对象问题 +10. 修复`button`组件`loadingSize`设置无效问题 +10. 其他修复 +## 2.0.31(2022-04-19) +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 修复`upload`在`vue`页面上传成功后没有成功标志的问题 +2. 解决演示项目中微信小程序模拟上传图片一直出于上传中问题 +3. 修复`u-code-input`组件在`nvue`页面编译到`app`平台上光标异常问题(`app`去除此功能) +4. 修复`actionSheet`组件标题关闭按钮点击事件名称错误的问题 +5. 其他修复 +## 2.0.30(2022-04-04) +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. `u-rate`增加`readonly`属性 +2. `tabs`滑块支持设置背景图片 +3. 修复`u-subsection` `mode`为`subsection`时,滑块样式不正确的问题 +4. `u-code-input`添加光标效果动画 +5. 修复`popup`的`open`事件不触发 +6. 修复`u-flex-column`无效的问题 +7. 修复`u-datetime-picker`索引在特定场合异常问题 +8. 修复`u-datetime-picker`最小时间字符串模板错误问题 +9. `u-swiper`添加`m3u8`验证 +10. `u-swiper`修改判断image和video逻辑 +11. 修复`swiper`无法使用本地图片问题,增加`type`参数 +12. 修复`u-row-notice`格式错误问题 +13. 修复`u-switch`组件当`unit`为`rpx`时,`nodeStyle`消失的问题 +14. 修复`datetime-picker`组件`showToolbar`与`visibleItemCount`属性无效的问题 +15. 修复`upload`组件条件编译位置判断错误,导致`previewImage`属性设置为`false`时,整个组件都会被隐藏的问题 +16. 修复`u-checkbox-group`设置`shape`属性无效的问题 +17. 修复`u-upload`的`capture`传入字符串的时候不生效的问题 +18. 修复`u-action-sheet`组件,关闭事件逻辑错误的问题 +19. 修复`u-list`触顶事件的触发错误的问题 +20. 修复`u-text`只有手机号可拨打的问题 +21. 修复`u-textarea`不能换行的问题 +22. 其他修复 +## 2.0.29(2022-03-13) +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 修复`u--text`组件设置`decoration`属性未生效的问题 +2. 修复`u-datetime-picker`使用`formatter`后返回值不正确 +3. 修复`u-datetime-picker` `intercept` 可能为undefined +4. 修复已设置单位 uni..config.unit = 'rpx'时,线型指示器 `transform` 的位置翻倍,导致指示器超出宽度 +5. 修复mixin中bem方法生成的类名在支付宝和字节小程序中失效 +6. 修复默认值传值为空的时候,打开`u-datetime-picker`报错,不能选中第一列时间的bug +7. 修复`u-datetime-picker`使用`formatter`后返回值不正确 +8. 修复`u-image`组件`loading`无效果的问题 +9. 修复`config.unit`属性设为`rpx`时,导航栏占用高度不足导致塌陷的问题 +10. 修复`u-datetime-picker`组件`itemHeight`无效问题 +11. 其他修复 +## 2.0.28(2022-02-22) +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. search组件新增searchIconSize属性 +2. 兼容Safari/Webkit中传入时间格式如2022-02-17 12:00:56 +3. 修复text value.js 判断日期出format错误问题 +4. priceFormat格式化金额出现精度错误 +5. priceFormat在部分情况下出现精度损失问题 +6. 优化表单rules提示 +7. 修复avatar组件src为空时,展示状态不对 +8. 其他修复 +## 2.0.27(2022-01-28) +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1.样式修复 +## 2.0.26(2022-01-28) +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1.样式修复 +## 2.0.25(2022-01-27) +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 修复text组件mode=price时,可能会导致精度错误的问题 +2. 添加$u.setConfig()方法,可设置uView内置的config, props, zIndex, color属性,详见:[修改uView内置配置方案](https://uviewui.com/components/setting.html#%E9%BB%98%E8%AE%A4%E5%8D%95%E4%BD%8D%E9%85%8D%E7%BD%AE) +3. 优化form组件在errorType=toast时,如果输入错误页面会有抖动的问题 +4. 修复$u.addUnit()对配置默认单位可能无效的问题 +## 2.0.24(2022-01-25) +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 修复swiper在current指定非0时缩放有误 +2. 修复u-icon添加stop属性的时候报错 +3. 优化遗留的通过正则判断rpx单位的问题 +4. 优化Layout布局 vue使用gutter时,会超出固定区域 +5. 优化search组件高度单位问题(rpx -> px) +6. 修复u-image slot 加载和错误的图片失去了高度 +7. 修复u-index-list中footer插槽与header插槽存在性判断错误 +8. 修复部分机型下u-popup关闭时会闪烁 +9. 修复u-image在nvue-app下失去宽高 +10. 修复u-popup运行报错 +11. 修复u-tooltip报错 +12. 修复box-sizing在app下的警告 +13. 修复u-navbar在小程序中报运行时错误 +14. 其他修复 +## 2.0.23(2022-01-24) +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 修复image组件在hx3.3.9的nvue下可能会显示异常的问题 +2. 修复col组件gutter参数带rpx单位处理不正确的问题 +3. 修复text组件单行时无法显示省略号的问题 +4. navbar添加titleStyle参数 +5. 升级到hx3.3.9可消除nvue下控制台样式警告的问题 +## 2.0.22(2022-01-19) +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. $u.page()方法优化,避免在特殊场景可能报错的问题 +2. picker组件添加immediateChange参数 +3. 新增$u.pages()方法 +## 2.0.21(2022-01-19) +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 优化:form组件在用户设置rules的时候提示用户model必传 +2. 优化遗留的通过正则判断rpx单位的问题 +3. 修复微信小程序环境中tabbar组件开启safeAreaInsetBottom属性后,placeholder高度填充不正确 +4. 修复swiper在current指定非0时缩放有误 +5. 修复u-icon添加stop属性的时候报错 +6. 修复upload组件在accept=all的时候没有作用 +7. 修复在text组件mode为phone时call属性无效的问题 +8. 处理u-form clearValidate方法 +9. 其他修复 +## 2.0.20(2022-01-14) +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 修复calendar默认会选择一个日期,如果直接点确定的话,无法取到值的问题 +2. 修复Slider缺少disabled props 还有注释 +3. 修复u-notice-bar点击事件无法拿到index索引值的问题 +4. 修复u-collapse-item在vue文件下,app端自定义插槽不生效的问题 +5. 优化头像为空时显示默认头像 +6. 修复图片地址赋值后判断加载状态为完成问题 +7. 修复日历滚动到默认日期月份区域 +8. search组件暴露点击左边icon事件 +9. 修复u-form clearValidate方法不生效 +10. upload h5端增加返回文件参数(文件的name参数) +11. 处理upload选择文件后url为blob类型无法预览的问题 +12. u-code-input 修复输入框没有往左移出一半屏幕 +13. 修复Upload上传 disabled为true时,控制台报hoverClass类型错误 +14. 临时处理ios app下grid点击坍塌问题 +15. 其他修复 +## 2.0.19(2021-12-29) +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 优化微信小程序包体积可在微信中预览,请升级HbuilderX3.3.4,同时在“运行->运行到小程序模拟器”中勾选“运行时是否压缩代码” +2. 优化微信小程序setData性能,处理某些方法如$u.route()无法在模板中使用的问题 +3. navbar添加autoBack参数 +4. 允许avatar组件的事件冒泡 +5. 修复cell组件报错问题 +6. 其他修复 +## 2.0.18(2021-12-28) +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 修复app端编译报错问题 +2. 重新处理微信小程序端setData过大的性能问题 +3. 修复边框问题 +4. 修复最大最小月份不大于0则没有数据出现的问题 +5. 修复SwipeAction微信小程序端无法上下滑动问题 +6. 修复input的placeholder在小程序端默认显示为true问题 +7. 修复divider组件click事件无效问题 +8. 修复u-code-input maxlength 属性值为 String 类型时显示异常 +9. 修复当 grid只有 1到2时 在小程序端algin设置无效的问题 +10. 处理form-item的label为top时,取消错误提示的左边距 +11. 其他修复 +## 2.0.17(2021-12-26) +## uView正在参与开源中国的“年度最佳项目”评选,之前投过票的现在也可以投票,恳请同学们投一票,[点此帮助uView](https://www.oschina.net/project/top_cn_2021/?id=583) + +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 解决HBuilderX3.3.3.20211225版本导致的样式问题 +2. calendar日历添加monthNum参数 +3. navbar添加center slot +## 2.0.16(2021-12-25) +## uView正在参与开源中国的“年度最佳项目”评选,之前投过票的现在也可以投票,恳请同学们投一票,[点此帮助uView](https://www.oschina.net/project/top_cn_2021/?id=583) + +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 解决微信小程序setData性能问题 +2. 修复count-down组件change事件不触发问题 +## 2.0.15(2021-12-21) +## uView正在参与开源中国的“年度最佳项目”评选,之前投过票的现在也可以投票,恳请同学们投一票,[点此帮助uView](https://www.oschina.net/project/top_cn_2021/?id=583) + +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 修复Cell单元格titleWidth无效 +2. 修复cheakbox组件ischecked不更新 +3. 修复keyboard是否显示"."按键默认值问题 +4. 修复number-keyboard是否显示键盘的"."符号问题 +5. 修复Input输入框 readonly无效 +6. 修复u-avatar 导致打包app、H5时候报错问题 +7. 修复Upload上传deletable无效 +8. 修复upload当设置maxSize时无效的问题 +9. 修复tabs lineWidth传入带单位的字符串的时候偏移量计算错误问题 +10. 修复rate组件在有padding的view内,显示的星星位置和可触摸区域不匹配,无法正常选中星星 +## 2.0.13(2021-12-14) +## [点击加群交流反馈:364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY) + +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 修复配置默认单位为rpx可能会导致自定义导航栏高度异常的问题 +## 2.0.12(2021-12-14) +## [点击加群交流反馈:364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY) + +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 修复tabs组件在vue环境下划线消失的问题 +2. 修复upload组件在安卓小程序无法选择视频的问题 +3. 添加uni.$u.config.unit配置,用于配置参数默认单位,详见:[默认单位配置](https://www.uviewui.com/components/setting.html#%E9%BB%98%E8%AE%A4%E5%8D%95%E4%BD%8D%E9%85%8D%E7%BD%AE) +4. 修复textarea组件在没绑定v-model时,字符统计不生效问题 +5. 修复nvue下控制是否出现滚动条失效问题 +## 2.0.11(2021-12-13) +## [点击加群交流反馈:364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY) + +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. text组件align参数无效的问题 +2. subsection组件添加keyName参数 +3. upload组件无法判断[Object file]类型的问题 +4. 处理notify层级过低问题 +5. codeInput组件添加disabledDot参数 +6. 处理actionSheet组件round参数无效的问题 +7. calendar组件添加round参数用于控制圆角值 +8. 处理swipeAction组件在vue环境下默认被打开的问题 +9. button组件的throttleTime节流参数无效的问题 +10. 解决u-notify手动关闭方法close()无效的问题 +11. input组件readonly不生效问题 +12. tag组件type参数为info不生效问题 +## 2.0.10(2021-12-08) +## [点击加群交流反馈:364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY) + +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 修复button sendMessagePath属性不生效 +2. 修复DatetimePicker选择器title无效 +3. 修复u-toast设置loading=true不生效 +4. 修复u-text金额模式传0报错 +5. 修复u-toast组件的icon属性配置不生效 +6. button的icon在特殊场景下的颜色优化 +7. IndexList优化,增加# +## 2.0.9(2021-12-01) +## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU) + +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 优化swiper的height支持100%值(仅vue有效),修复嵌入视频时click事件无法触发的问题 +2. 优化tabs组件对list值为空的判断,或者动态变化list时重新计算相关尺寸的问题 +3. 优化datetime-picker组件逻辑,让其后续打开的默认值为上一次的选中值,需要通过v-model绑定值才有效 +4. 修复upload内嵌在其他组件中,选择图片可能不会换行的问题 +## 2.0.8(2021-12-01) +## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU) + +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 修复toast的position参数无效问题 +2. 处理input在ios nvue上无法获得焦点的问题 +3. avatar-group组件添加extraValue参数,让剩余展示数量可手动控制 +4. tabs组件添加keyName参数用于配置从对象中读取的键名 +5. 处理text组件名字脱敏默认配置无效的问题 +6. 处理picker组件item文本太长换行问题 +## 2.0.7(2021-11-30) +## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU) + +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 修复radio和checkbox动态改变v-model无效的问题。 +2. 优化form规则validator在微信小程序用法 +3. 修复backtop组件mode参数在微信小程序无效的问题 +4. 处理Album的previewFullImage属性无效的问题 +5. 处理u-datetime-picker组件mode='time'在选择改变时间时,控制台报错的问题 +## 2.0.6(2021-11-27) +## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU) + +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 处理tag组件在vue下边框无效的问题。 +2. 处理popup组件圆角参数可能无效的问题。 +3. 处理tabs组件lineColor参数可能无效的问题。 +4. propgress组件在值很小时,显示异常的问题。 +## 2.0.5(2021-11-25) +## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU) + +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. calendar在vue下显示异常问题。 +2. form组件labelPosition和errorType参数无效的问题 +3. input组件inputAlign无效的问题 +4. 其他一些修复 +## 2.0.4(2021-11-23) +## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU) + +# uView2.0重磅发布,利剑出鞘,一统江湖 + +0. input组件缺失@confirm事件,以及subfix和prefix无效问题 +1. component.scss文件样式在vue下干扰全局布局问题 +2. 修复subsection在vue环境下表现异常的问题 +3. tag组件的bgColor等参数无效的问题 +4. upload组件不换行的问题 +5. 其他的一些修复处理 +## 2.0.3(2021-11-16) +## [点击加群交流反馈:1129077272](https://jq.qq.com/?_wv=1027&k=KnbeceDU) + +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. uView2.0已实现全面兼容nvue +2. uView2.0对1.x进行了架构重构,细节和性能都有极大提升 +3. 目前uView2.0为公测阶段,相关细节可能会有变动 +4. 我们写了一份与1.x的对比指南,详见[对比1.x](https://www.uviewui.com/components/diff1.x.html) +5. 处理modal的confirm回调事件拼写错误问题 +6. 处理input组件@input事件参数错误问题 +7. 其他一些修复 +## 2.0.2(2021-11-16) +## [点击加群交流反馈:1129077272](https://jq.qq.com/?_wv=1027&k=KnbeceDU) + +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. uView2.0已实现全面兼容nvue +2. uView2.0对1.x进行了架构重构,细节和性能都有极大提升 +3. 目前uView2.0为公测阶段,相关细节可能会有变动 +4. 我们写了一份与1.x的对比指南,详见[对比1.x](https://www.uviewui.com/components/diff1.x.html) +5. 修复input组件formatter参数缺失问题 +6. 优化loading-icon组件的scss写法问题,防止不兼容新版本scss +## 2.0.0(2020-11-15) +## [点击加群交流反馈:1129077272](https://jq.qq.com/?_wv=1027&k=KnbeceDU) + +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. uView2.0已实现全面兼容nvue +2. uView2.0对1.x进行了架构重构,细节和性能都有极大提升 +3. 目前uView2.0为公测阶段,相关细节可能会有变动 +4. 我们写了一份与1.x的对比指南,详见[对比1.x](https://www.uviewui.com/components/diff1.x.html) +5. 修复input组件formatter参数缺失问题 + + diff --git a/uni_modules/uview-ui/components/u--form/u--form.vue b/uni_modules/uview-ui/components/u--form/u--form.vue new file mode 100644 index 0000000..fdfc212 --- /dev/null +++ b/uni_modules/uview-ui/components/u--form/u--form.vue @@ -0,0 +1,78 @@ + + + diff --git a/uni_modules/uview-ui/components/u--image/u--image.vue b/uni_modules/uview-ui/components/u--image/u--image.vue new file mode 100644 index 0000000..21b7ab1 --- /dev/null +++ b/uni_modules/uview-ui/components/u--image/u--image.vue @@ -0,0 +1,47 @@ + + + \ No newline at end of file diff --git a/uni_modules/uview-ui/components/u--input/u--input.vue b/uni_modules/uview-ui/components/u--input/u--input.vue new file mode 100644 index 0000000..1e58b01 --- /dev/null +++ b/uni_modules/uview-ui/components/u--input/u--input.vue @@ -0,0 +1,73 @@ + + + \ No newline at end of file diff --git a/uni_modules/uview-ui/components/u--text/u--text.vue b/uni_modules/uview-ui/components/u--text/u--text.vue new file mode 100644 index 0000000..44ee52a --- /dev/null +++ b/uni_modules/uview-ui/components/u--text/u--text.vue @@ -0,0 +1,44 @@ + + + diff --git a/uni_modules/uview-ui/components/u--textarea/u--textarea.vue b/uni_modules/uview-ui/components/u--textarea/u--textarea.vue new file mode 100644 index 0000000..f4df0b9 --- /dev/null +++ b/uni_modules/uview-ui/components/u--textarea/u--textarea.vue @@ -0,0 +1,48 @@ + + + diff --git a/uni_modules/uview-ui/components/u-action-sheet/props.js b/uni_modules/uview-ui/components/u-action-sheet/props.js new file mode 100644 index 0000000..e96e04f --- /dev/null +++ b/uni_modules/uview-ui/components/u-action-sheet/props.js @@ -0,0 +1,54 @@ +export default { + props: { + // 操作菜单是否展示 (默认false) + show: { + type: Boolean, + default: uni.$u.props.actionSheet.show + }, + // 标题 + title: { + type: String, + default: uni.$u.props.actionSheet.title + }, + // 选项上方的描述信息 + description: { + type: String, + default: uni.$u.props.actionSheet.description + }, + // 数据 + actions: { + type: Array, + default: uni.$u.props.actionSheet.actions + }, + // 取消按钮的文字,不为空时显示按钮 + cancelText: { + type: String, + default: uni.$u.props.actionSheet.cancelText + }, + // 点击某个菜单项时是否关闭弹窗 + closeOnClickAction: { + type: Boolean, + default: uni.$u.props.actionSheet.closeOnClickAction + }, + // 处理底部安全区(默认true) + safeAreaInsetBottom: { + type: Boolean, + default: uni.$u.props.actionSheet.safeAreaInsetBottom + }, + // 小程序的打开方式 + openType: { + type: String, + default: uni.$u.props.actionSheet.openType + }, + // 点击遮罩是否允许关闭 (默认true) + closeOnClickOverlay: { + type: Boolean, + default: uni.$u.props.actionSheet.closeOnClickOverlay + }, + // 圆角值 + round: { + type: [Boolean, String, Number], + default: uni.$u.props.actionSheet.round + } + } +} diff --git a/uni_modules/uview-ui/components/u-action-sheet/u-action-sheet.vue b/uni_modules/uview-ui/components/u-action-sheet/u-action-sheet.vue new file mode 100644 index 0000000..26d5d8d --- /dev/null +++ b/uni_modules/uview-ui/components/u-action-sheet/u-action-sheet.vue @@ -0,0 +1,278 @@ + + + + + + diff --git a/uni_modules/uview-ui/components/u-album/props.js b/uni_modules/uview-ui/components/u-album/props.js new file mode 100644 index 0000000..75cdb37 --- /dev/null +++ b/uni_modules/uview-ui/components/u-album/props.js @@ -0,0 +1,59 @@ +export default { + props: { + // 图片地址,Array|Array形式 + urls: { + type: Array, + default: uni.$u.props.album.urls + }, + // 指定从数组的对象元素中读取哪个属性作为图片地址 + keyName: { + type: String, + default: uni.$u.props.album.keyName + }, + // 单图时,图片长边的长度 + singleSize: { + type: [String, Number], + default: uni.$u.props.album.singleSize + }, + // 多图时,图片边长 + multipleSize: { + type: [String, Number], + default: uni.$u.props.album.multipleSize + }, + // 多图时,图片水平和垂直之间的间隔 + space: { + type: [String, Number], + default: uni.$u.props.album.space + }, + // 单图时,图片缩放裁剪的模式 + singleMode: { + type: String, + default: uni.$u.props.album.singleMode + }, + // 多图时,图片缩放裁剪的模式 + multipleMode: { + type: String, + default: uni.$u.props.album.multipleMode + }, + // 最多展示的图片数量,超出时最后一个位置将会显示剩余图片数量 + maxCount: { + type: [String, Number], + default: uni.$u.props.album.maxCount + }, + // 是否可以预览图片 + previewFullImage: { + type: Boolean, + default: uni.$u.props.album.previewFullImage + }, + // 每行展示图片数量,如设置,singleSize和multipleSize将会无效 + rowCount: { + type: [String, Number], + default: uni.$u.props.album.rowCount + }, + // 超出maxCount时是否显示查看更多的提示 + showMore: { + type: Boolean, + default: uni.$u.props.album.showMore + } + } +} diff --git a/uni_modules/uview-ui/components/u-album/u-album.vue b/uni_modules/uview-ui/components/u-album/u-album.vue new file mode 100644 index 0000000..687e2d5 --- /dev/null +++ b/uni_modules/uview-ui/components/u-album/u-album.vue @@ -0,0 +1,259 @@ + + + + + \ No newline at end of file diff --git a/uni_modules/uview-ui/components/u-alert/props.js b/uni_modules/uview-ui/components/u-alert/props.js new file mode 100644 index 0000000..4297e2c --- /dev/null +++ b/uni_modules/uview-ui/components/u-alert/props.js @@ -0,0 +1,44 @@ +export default { + props: { + // 显示文字 + title: { + type: String, + default: uni.$u.props.alert.title + }, + // 主题,success/warning/info/error + type: { + type: String, + default: uni.$u.props.alert.type + }, + // 辅助性文字 + description: { + type: String, + default: uni.$u.props.alert.description + }, + // 是否可关闭 + closable: { + type: Boolean, + default: uni.$u.props.alert.closable + }, + // 是否显示图标 + showIcon: { + type: Boolean, + default: uni.$u.props.alert.showIcon + }, + // 浅或深色调,light-浅色,dark-深色 + effect: { + type: String, + default: uni.$u.props.alert.effect + }, + // 文字是否居中 + center: { + type: Boolean, + default: uni.$u.props.alert.center + }, + // 字体大小 + fontSize: { + type: [String, Number], + default: uni.$u.props.alert.fontSize + } + } +} diff --git a/uni_modules/uview-ui/components/u-alert/u-alert.vue b/uni_modules/uview-ui/components/u-alert/u-alert.vue new file mode 100644 index 0000000..81f7d43 --- /dev/null +++ b/uni_modules/uview-ui/components/u-alert/u-alert.vue @@ -0,0 +1,243 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-avatar-group/props.js b/uni_modules/uview-ui/components/u-avatar-group/props.js new file mode 100644 index 0000000..58b42ac --- /dev/null +++ b/uni_modules/uview-ui/components/u-avatar-group/props.js @@ -0,0 +1,52 @@ +export default { + props: { + // 头像图片组 + urls: { + type: Array, + default: uni.$u.props.avatarGroup.urls + }, + // 最多展示的头像数量 + maxCount: { + type: [String, Number], + default: uni.$u.props.avatarGroup.maxCount + }, + // 头像形状 + shape: { + type: String, + default: uni.$u.props.avatarGroup.shape + }, + // 图片裁剪模式 + mode: { + type: String, + default: uni.$u.props.avatarGroup.mode + }, + // 超出maxCount时是否显示查看更多的提示 + showMore: { + type: Boolean, + default: uni.$u.props.avatarGroup.showMore + }, + // 头像大小 + size: { + type: [String, Number], + default: uni.$u.props.avatarGroup.size + }, + // 指定从数组的对象元素中读取哪个属性作为图片地址 + keyName: { + type: String, + default: uni.$u.props.avatarGroup.keyName + }, + // 头像之间的遮挡比例 + gap: { + type: [String, Number], + validator(value) { + return value >= 0 && value <= 1 + }, + default: uni.$u.props.avatarGroup.gap + }, + // 需额外显示的值 + extraValue: { + type: [Number, String], + default: uni.$u.props.avatarGroup.extraValue + } + } +} diff --git a/uni_modules/uview-ui/components/u-avatar-group/u-avatar-group.vue b/uni_modules/uview-ui/components/u-avatar-group/u-avatar-group.vue new file mode 100644 index 0000000..7e996d7 --- /dev/null +++ b/uni_modules/uview-ui/components/u-avatar-group/u-avatar-group.vue @@ -0,0 +1,103 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-avatar/props.js b/uni_modules/uview-ui/components/u-avatar/props.js new file mode 100644 index 0000000..34ca0f2 --- /dev/null +++ b/uni_modules/uview-ui/components/u-avatar/props.js @@ -0,0 +1,78 @@ +export default { + props: { + // 头像图片路径(不能为相对路径) + src: { + type: String, + default: uni.$u.props.avatar.src + }, + // 头像形状,circle-圆形,square-方形 + shape: { + type: String, + default: uni.$u.props.avatar.shape + }, + // 头像尺寸 + size: { + type: [String, Number], + default: uni.$u.props.avatar.size + }, + // 裁剪模式 + mode: { + type: String, + default: uni.$u.props.avatar.mode + }, + // 显示的文字 + text: { + type: String, + default: uni.$u.props.avatar.text + }, + // 背景色 + bgColor: { + type: String, + default: uni.$u.props.avatar.bgColor + }, + // 文字颜色 + color: { + type: String, + default: uni.$u.props.avatar.color + }, + // 文字大小 + fontSize: { + type: [String, Number], + default: uni.$u.props.avatar.fontSize + }, + // 显示的图标 + icon: { + type: String, + default: uni.$u.props.avatar.icon + }, + // 显示小程序头像,只对百度,微信,QQ小程序有效 + mpAvatar: { + type: Boolean, + default: uni.$u.props.avatar.mpAvatar + }, + // 是否使用随机背景色 + randomBgColor: { + type: Boolean, + default: uni.$u.props.avatar.randomBgColor + }, + // 加载失败的默认头像(组件有内置默认图片) + defaultUrl: { + type: String, + default: uni.$u.props.avatar.defaultUrl + }, + // 如果配置了randomBgColor为true,且配置了此值,则从默认的背景色数组中取出对应索引的颜色值,取值0-19之间 + colorIndex: { + type: [String, Number], + // 校验参数规则,索引在0-19之间 + validator(n) { + return uni.$u.test.range(n, [0, 19]) || n === '' + }, + default: uni.$u.props.avatar.colorIndex + }, + // 组件标识符 + name: { + type: String, + default: uni.$u.props.avatar.name + } + } +} diff --git a/uni_modules/uview-ui/components/u-avatar/u-avatar.vue b/uni_modules/uview-ui/components/u-avatar/u-avatar.vue new file mode 100644 index 0000000..3319be5 --- /dev/null +++ b/uni_modules/uview-ui/components/u-avatar/u-avatar.vue @@ -0,0 +1,172 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-back-top/props.js b/uni_modules/uview-ui/components/u-back-top/props.js new file mode 100644 index 0000000..6c702c2 --- /dev/null +++ b/uni_modules/uview-ui/components/u-back-top/props.js @@ -0,0 +1,54 @@ +export default { + props: { + // 返回顶部的形状,circle-圆形,square-方形 + mode: { + type: String, + default: uni.$u.props.backtop.mode + }, + // 自定义图标 + icon: { + type: String, + default: uni.$u.props.backtop.icon + }, + // 提示文字 + text: { + type: String, + default: uni.$u.props.backtop.text + }, + // 返回顶部滚动时间 + duration: { + type: [String, Number], + default: uni.$u.props.backtop.duration + }, + // 滚动距离 + scrollTop: { + type: [String, Number], + default: uni.$u.props.backtop.scrollTop + }, + // 距离顶部多少距离显示,单位px + top: { + type: [String, Number], + default: uni.$u.props.backtop.top + }, + // 返回顶部按钮到底部的距离,单位px + bottom: { + type: [String, Number], + default: uni.$u.props.backtop.bottom + }, + // 返回顶部按钮到右边的距离,单位px + right: { + type: [String, Number], + default: uni.$u.props.backtop.right + }, + // 层级 + zIndex: { + type: [String, Number], + default: uni.$u.props.backtop.zIndex + }, + // 图标的样式,对象形式 + iconStyle: { + type: Object, + default: uni.$u.props.backtop.iconStyle + } + } +} diff --git a/uni_modules/uview-ui/components/u-back-top/u-back-top.vue b/uni_modules/uview-ui/components/u-back-top/u-back-top.vue new file mode 100644 index 0000000..2d07566 --- /dev/null +++ b/uni_modules/uview-ui/components/u-back-top/u-back-top.vue @@ -0,0 +1,129 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-badge/props.js b/uni_modules/uview-ui/components/u-badge/props.js new file mode 100644 index 0000000..74c032c --- /dev/null +++ b/uni_modules/uview-ui/components/u-badge/props.js @@ -0,0 +1,72 @@ +export default { + props: { + // 是否显示圆点 + isDot: { + type: Boolean, + default: uni.$u.props.badge.isDot + }, + // 显示的内容 + value: { + type: [Number, String], + default: uni.$u.props.badge.value + }, + // 是否显示 + show: { + type: Boolean, + default: uni.$u.props.badge.show + }, + // 最大值,超过最大值会显示 '{max}+' + max: { + type: [Number, String], + default: uni.$u.props.badge.max + }, + // 主题类型,error|warning|success|primary + type: { + type: String, + default: uni.$u.props.badge.type + }, + // 当数值为 0 时,是否展示 Badge + showZero: { + type: Boolean, + default: uni.$u.props.badge.showZero + }, + // 背景颜色,优先级比type高,如设置,type参数会失效 + bgColor: { + type: [String, null], + default: uni.$u.props.badge.bgColor + }, + // 字体颜色 + color: { + type: [String, null], + default: uni.$u.props.badge.color + }, + // 徽标形状,circle-四角均为圆角,horn-左下角为直角 + shape: { + type: String, + default: uni.$u.props.badge.shape + }, + // 设置数字的显示方式,overflow|ellipsis|limit + // overflow会根据max字段判断,超出显示`${max}+` + // ellipsis会根据max判断,超出显示`${max}...` + // limit会依据1000作为判断条件,超出1000,显示`${value/1000}K`,比如2.2k、3.34w,最多保留2位小数 + numberType: { + type: String, + default: uni.$u.props.badge.numberType + }, + // 设置badge的位置偏移,格式为 [x, y],也即设置的为top和right的值,absolute为true时有效 + offset: { + type: Array, + default: uni.$u.props.badge.offset + }, + // 是否反转背景和字体颜色 + inverted: { + type: Boolean, + default: uni.$u.props.badge.inverted + }, + // 是否绝对定位 + absolute: { + type: Boolean, + default: uni.$u.props.badge.absolute + } + } +} diff --git a/uni_modules/uview-ui/components/u-badge/u-badge.vue b/uni_modules/uview-ui/components/u-badge/u-badge.vue new file mode 100644 index 0000000..53cfc81 --- /dev/null +++ b/uni_modules/uview-ui/components/u-badge/u-badge.vue @@ -0,0 +1,171 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-button/nvue.scss b/uni_modules/uview-ui/components/u-button/nvue.scss new file mode 100644 index 0000000..490db7d --- /dev/null +++ b/uni_modules/uview-ui/components/u-button/nvue.scss @@ -0,0 +1,46 @@ +$u-button-active-opacity:0.75 !default; +$u-button-loading-text-margin-left:4px !default; +$u-button-text-color: #FFFFFF !default; +$u-button-text-plain-error-color:$u-error !default; +$u-button-text-plain-warning-color:$u-warning !default; +$u-button-text-plain-success-color:$u-success !default; +$u-button-text-plain-info-color:$u-info !default; +$u-button-text-plain-primary-color:$u-primary !default; +.u-button { + &--active { + opacity: $u-button-active-opacity; + } + + &--active--plain { + background-color: rgb(217, 217, 217); + } + + &__loading-text { + margin-left:$u-button-loading-text-margin-left; + } + + &__text, + &__loading-text { + color:$u-button-text-color; + } + + &__text--plain--error { + color:$u-button-text-plain-error-color; + } + + &__text--plain--warning { + color:$u-button-text-plain-warning-color; + } + + &__text--plain--success{ + color:$u-button-text-plain-success-color; + } + + &__text--plain--info { + color:$u-button-text-plain-info-color; + } + + &__text--plain--primary { + color:$u-button-text-plain-primary-color; + } +} \ No newline at end of file diff --git a/uni_modules/uview-ui/components/u-button/props.js b/uni_modules/uview-ui/components/u-button/props.js new file mode 100644 index 0000000..07fd844 --- /dev/null +++ b/uni_modules/uview-ui/components/u-button/props.js @@ -0,0 +1,161 @@ +/* + * @Author : LQ + * @Description : + * @version : 1.0 + * @Date : 2021-08-16 10:04:04 + * @LastAuthor : LQ + * @lastTime : 2021-08-16 10:04:24 + * @FilePath : /u-view2.0/uview-ui/components/u-button/props.js + */ +export default { + props: { + // 是否细边框 + hairline: { + type: Boolean, + default: uni.$u.props.button.hairline + }, + // 按钮的预置样式,info,primary,error,warning,success + type: { + type: String, + default: uni.$u.props.button.type + }, + // 按钮尺寸,large,normal,small,mini + size: { + type: String, + default: uni.$u.props.button.size + }, + // 按钮形状,circle(两边为半圆),square(带圆角) + shape: { + type: String, + default: uni.$u.props.button.shape + }, + // 按钮是否镂空 + plain: { + type: Boolean, + default: uni.$u.props.button.plain + }, + // 是否禁止状态 + disabled: { + type: Boolean, + default: uni.$u.props.button.disabled + }, + // 是否加载中 + loading: { + type: Boolean, + default: uni.$u.props.button.loading + }, + // 加载中提示文字 + loadingText: { + type: [String, Number], + default: uni.$u.props.button.loadingText + }, + // 加载状态图标类型 + loadingMode: { + type: String, + default: uni.$u.props.button.loadingMode + }, + // 加载图标大小 + loadingSize: { + type: [String, Number], + default: uni.$u.props.button.loadingSize + }, + // 开放能力,具体请看uniapp稳定关于button组件部分说明 + // https://uniapp.dcloud.io/component/button + openType: { + type: String, + default: uni.$u.props.button.openType + }, + // 用于
组件,点击分别会触发 组件的 submit/reset 事件 + // 取值为submit(提交表单),reset(重置表单) + formType: { + type: String, + default: uni.$u.props.button.formType + }, + // 打开 APP 时,向 APP 传递的参数,open-type=launchApp时有效 + // 只微信小程序、QQ小程序有效 + appParameter: { + type: String, + default: uni.$u.props.button.appParameter + }, + // 指定是否阻止本节点的祖先节点出现点击态,微信小程序有效 + hoverStopPropagation: { + type: Boolean, + default: uni.$u.props.button.hoverStopPropagation + }, + // 指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文。只微信小程序有效 + lang: { + type: String, + default: uni.$u.props.button.lang + }, + // 会话来源,open-type="contact"时有效。只微信小程序有效 + sessionFrom: { + type: String, + default: uni.$u.props.button.sessionFrom + }, + // 会话内消息卡片标题,open-type="contact"时有效 + // 默认当前标题,只微信小程序有效 + sendMessageTitle: { + type: String, + default: uni.$u.props.button.sendMessageTitle + }, + // 会话内消息卡片点击跳转小程序路径,open-type="contact"时有效 + // 默认当前分享路径,只微信小程序有效 + sendMessagePath: { + type: String, + default: uni.$u.props.button.sendMessagePath + }, + // 会话内消息卡片图片,open-type="contact"时有效 + // 默认当前页面截图,只微信小程序有效 + sendMessageImg: { + type: String, + default: uni.$u.props.button.sendMessageImg + }, + // 是否显示会话内消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示"可能要发送的小程序"提示, + // 用户点击后可以快速发送小程序消息,open-type="contact"时有效 + showMessageCard: { + type: Boolean, + default: uni.$u.props.button.showMessageCard + }, + // 额外传参参数,用于小程序的data-xxx属性,通过target.dataset.name获取 + dataName: { + type: String, + default: uni.$u.props.button.dataName + }, + // 节流,一定时间内只能触发一次 + throttleTime: { + type: [String, Number], + default: uni.$u.props.button.throttleTime + }, + // 按住后多久出现点击态,单位毫秒 + hoverStartTime: { + type: [String, Number], + default: uni.$u.props.button.hoverStartTime + }, + // 手指松开后点击态保留时间,单位毫秒 + hoverStayTime: { + type: [String, Number], + default: uni.$u.props.button.hoverStayTime + }, + // 按钮文字,之所以通过props传入,是因为slot传入的话 + // nvue中无法控制文字的样式 + text: { + type: [String, Number], + default: uni.$u.props.button.text + }, + // 按钮图标 + icon: { + type: String, + default: uni.$u.props.button.icon + }, + // 按钮图标 + iconColor: { + type: String, + default: uni.$u.props.button.icon + }, + // 按钮颜色,支持传入linear-gradient渐变色 + color: { + type: String, + default: uni.$u.props.button.color + } + } +} diff --git a/uni_modules/uview-ui/components/u-button/u-button.vue b/uni_modules/uview-ui/components/u-button/u-button.vue new file mode 100644 index 0000000..5494351 --- /dev/null +++ b/uni_modules/uview-ui/components/u-button/u-button.vue @@ -0,0 +1,490 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-button/vue.scss b/uni_modules/uview-ui/components/u-button/vue.scss new file mode 100644 index 0000000..32019b2 --- /dev/null +++ b/uni_modules/uview-ui/components/u-button/vue.scss @@ -0,0 +1,80 @@ +// nvue下hover-class无效 +$u-button-before-top:50% !default; +$u-button-before-left:50% !default; +$u-button-before-width:100% !default; +$u-button-before-height:100% !default; +$u-button-before-transform:translate(-50%, -50%) !default; +$u-button-before-opacity:0 !default; +$u-button-before-background-color:#000 !default; +$u-button-before-border-color:#000 !default; +$u-button-active-before-opacity:.15 !default; +$u-button-icon-margin-left:4px !default; +$u-button-plain-u-button-info-color:$u-info; +$u-button-plain-u-button-success-color:$u-success; +$u-button-plain-u-button-error-color:$u-error; +$u-button-plain-u-button-warning-color:$u-error; + +.u-button { + width: 100%; + + &__text { + white-space: nowrap; + line-height: 1; + } + + &:before { + position: absolute; + top:$u-button-before-top; + left:$u-button-before-left; + width:$u-button-before-width; + height:$u-button-before-height; + border: inherit; + border-radius: inherit; + transform:$u-button-before-transform; + opacity:$u-button-before-opacity; + content: " "; + background-color:$u-button-before-background-color; + border-color:$u-button-before-border-color; + } + + &--active { + &:before { + opacity: .15 + } + } + + &__icon+&__text:not(:empty), + &__loading-text { + margin-left:$u-button-icon-margin-left; + } + + &--plain { + &.u-button--primary { + color: $u-primary; + } + } + + &--plain { + &.u-button--info { + color:$u-button-plain-u-button-info-color; + } + } + + &--plain { + &.u-button--success { + color:$u-button-plain-u-button-success-color; + } + } + + &--plain { + &.u-button--error { + color:$u-button-plain-u-button-error-color; + } + } + + &--plain { + &.u-button--warning { + color:$u-button-plain-u-button-warning-color; + } + } +} diff --git a/uni_modules/uview-ui/components/u-calendar/header.vue b/uni_modules/uview-ui/components/u-calendar/header.vue new file mode 100644 index 0000000..dc4f7d0 --- /dev/null +++ b/uni_modules/uview-ui/components/u-calendar/header.vue @@ -0,0 +1,99 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-calendar/month.vue b/uni_modules/uview-ui/components/u-calendar/month.vue new file mode 100644 index 0000000..c20937f --- /dev/null +++ b/uni_modules/uview-ui/components/u-calendar/month.vue @@ -0,0 +1,579 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-calendar/props.js b/uni_modules/uview-ui/components/u-calendar/props.js new file mode 100644 index 0000000..2ad7bc7 --- /dev/null +++ b/uni_modules/uview-ui/components/u-calendar/props.js @@ -0,0 +1,144 @@ +export default { + props: { + // 日历顶部标题 + title: { + type: String, + default: uni.$u.props.calendar.title + }, + // 是否显示标题 + showTitle: { + type: Boolean, + default: uni.$u.props.calendar.showTitle + }, + // 是否显示副标题 + showSubtitle: { + type: Boolean, + default: uni.$u.props.calendar.showSubtitle + }, + // 日期类型选择,single-选择单个日期,multiple-可以选择多个日期,range-选择日期范围 + mode: { + type: String, + default: uni.$u.props.calendar.mode + }, + // mode=range时,第一个日期底部的提示文字 + startText: { + type: String, + default: uni.$u.props.calendar.startText + }, + // mode=range时,最后一个日期底部的提示文字 + endText: { + type: String, + default: uni.$u.props.calendar.endText + }, + // 自定义列表 + customList: { + type: Array, + default: uni.$u.props.calendar.customList + }, + // 主题色,对底部按钮和选中日期有效 + color: { + type: String, + default: uni.$u.props.calendar.color + }, + // 最小的可选日期 + minDate: { + type: [String, Number], + default: uni.$u.props.calendar.minDate + }, + // 最大可选日期 + maxDate: { + type: [String, Number], + default: uni.$u.props.calendar.maxDate + }, + // 默认选中的日期,mode为multiple或range是必须为数组格式 + defaultDate: { + type: [Array, String, Date, null], + default: uni.$u.props.calendar.defaultDate + }, + // mode=multiple时,最多可选多少个日期 + maxCount: { + type: [String, Number], + default: uni.$u.props.calendar.maxCount + }, + // 日期行高 + rowHeight: { + type: [String, Number], + default: uni.$u.props.calendar.rowHeight + }, + // 日期格式化函数 + formatter: { + type: [Function, null], + default: uni.$u.props.calendar.formatter + }, + // 是否显示农历 + showLunar: { + type: Boolean, + default: uni.$u.props.calendar.showLunar + }, + // 是否显示月份背景色 + showMark: { + type: Boolean, + default: uni.$u.props.calendar.showMark + }, + // 确定按钮的文字 + confirmText: { + type: String, + default: uni.$u.props.calendar.confirmText + }, + // 确认按钮处于禁用状态时的文字 + confirmDisabledText: { + type: String, + default: uni.$u.props.calendar.confirmDisabledText + }, + // 是否显示日历弹窗 + show: { + type: Boolean, + default: uni.$u.props.calendar.show + }, + // 是否允许点击遮罩关闭日历 + closeOnClickOverlay: { + type: Boolean, + default: uni.$u.props.calendar.closeOnClickOverlay + }, + // 是否为只读状态,只读状态下禁止选择日期 + readonly: { + type: Boolean, + default: uni.$u.props.calendar.readonly + }, + // 是否展示确认按钮 + showConfirm: { + type: Boolean, + default: uni.$u.props.calendar.showConfirm + }, + // 日期区间最多可选天数,默认无限制,mode = range时有效 + maxRange: { + type: [Number, String], + default: uni.$u.props.calendar.maxRange + }, + // 范围选择超过最多可选天数时的提示文案,mode = range时有效 + rangePrompt: { + type: String, + default: uni.$u.props.calendar.rangePrompt + }, + // 范围选择超过最多可选天数时,是否展示提示文案,mode = range时有效 + showRangePrompt: { + type: Boolean, + default: uni.$u.props.calendar.showRangePrompt + }, + // 是否允许日期范围的起止时间为同一天,mode = range时有效 + allowSameDay: { + type: Boolean, + default: uni.$u.props.calendar.allowSameDay + }, + // 圆角值 + round: { + type: [Boolean, String, Number], + default: uni.$u.props.calendar.round + }, + // 最多展示月份数量 + monthNum: { + type: [Number, String], + default: 3 + } + } +} diff --git a/uni_modules/uview-ui/components/u-calendar/u-calendar.vue b/uni_modules/uview-ui/components/u-calendar/u-calendar.vue new file mode 100644 index 0000000..511f993 --- /dev/null +++ b/uni_modules/uview-ui/components/u-calendar/u-calendar.vue @@ -0,0 +1,384 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-calendar/util.js b/uni_modules/uview-ui/components/u-calendar/util.js new file mode 100644 index 0000000..ca4736b --- /dev/null +++ b/uni_modules/uview-ui/components/u-calendar/util.js @@ -0,0 +1,85 @@ +export default { + methods: { + // 设置月份数据 + setMonth() { + // 月初是周几 + const day = dayjs(this.date).date(1).day() + const start = day == 0 ? 6 : day - 1 + + // 本月天数 + const days = dayjs(this.date).endOf('month').format('D') + + // 上个月天数 + const prevDays = dayjs(this.date).endOf('month').subtract(1, 'month').format('D') + + // 日期数据 + const arr = [] + // 清空表格 + this.month = [] + + // 添加上月数据 + arr.push( + ...new Array(start).fill(1).map((e, i) => { + const day = prevDays - start + i + 1 + + return { + value: day, + disabled: true, + date: dayjs(this.date).subtract(1, 'month').date(day).format('YYYY-MM-DD') + } + }) + ) + + // 添加本月数据 + arr.push( + ...new Array(days - 0).fill(1).map((e, i) => { + const day = i + 1 + + return { + value: day, + date: dayjs(this.date).date(day).format('YYYY-MM-DD') + } + }) + ) + + // 添加下个月 + arr.push( + ...new Array(42 - days - start).fill(1).map((e, i) => { + const day = i + 1 + + return { + value: day, + disabled: true, + date: dayjs(this.date).add(1, 'month').date(day).format('YYYY-MM-DD') + } + }) + ) + + // 分割数组 + for (let n = 0; n < arr.length; n += 7) { + this.month.push( + arr.slice(n, n + 7).map((e, i) => { + e.index = i + n + + // 自定义信息 + const custom = this.customList.find((c) => c.date == e.date) + + // 农历 + if (this.lunar) { + const { + IDayCn, + IMonthCn + } = this.getLunar(e.date) + e.lunar = IDayCn == '初一' ? IMonthCn : IDayCn + } + + return { + ...e, + ...custom + } + }) + ) + } + } + } +} diff --git a/uni_modules/uview-ui/components/u-car-keyboard/props.js b/uni_modules/uview-ui/components/u-car-keyboard/props.js new file mode 100644 index 0000000..3553647 --- /dev/null +++ b/uni_modules/uview-ui/components/u-car-keyboard/props.js @@ -0,0 +1,14 @@ +export default { + props: { + // 是否打乱键盘按键的顺序 + random: { + type: Boolean, + default: false + }, + // 输入一个中文后,是否自动切换到英文 + autoChange: { + type: Boolean, + default: false + } + } +} diff --git a/uni_modules/uview-ui/components/u-car-keyboard/u-car-keyboard.vue b/uni_modules/uview-ui/components/u-car-keyboard/u-car-keyboard.vue new file mode 100644 index 0000000..51175b5 --- /dev/null +++ b/uni_modules/uview-ui/components/u-car-keyboard/u-car-keyboard.vue @@ -0,0 +1,311 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-cell-group/props.js b/uni_modules/uview-ui/components/u-cell-group/props.js new file mode 100644 index 0000000..350ef40 --- /dev/null +++ b/uni_modules/uview-ui/components/u-cell-group/props.js @@ -0,0 +1,14 @@ +export default { + props: { + // 分组标题 + title: { + type: String, + default: uni.$u.props.cellGroup.title + }, + // 是否显示外边框 + border: { + type: Boolean, + default: uni.$u.props.cellGroup.border + } + } +} diff --git a/uni_modules/uview-ui/components/u-cell-group/u-cell-group.vue b/uni_modules/uview-ui/components/u-cell-group/u-cell-group.vue new file mode 100644 index 0000000..a9508c0 --- /dev/null +++ b/uni_modules/uview-ui/components/u-cell-group/u-cell-group.vue @@ -0,0 +1,61 @@ + + + + + + diff --git a/uni_modules/uview-ui/components/u-cell/props.js b/uni_modules/uview-ui/components/u-cell/props.js new file mode 100644 index 0000000..da03330 --- /dev/null +++ b/uni_modules/uview-ui/components/u-cell/props.js @@ -0,0 +1,110 @@ +export default { + props: { + // 标题 + title: { + type: [String, Number], + default: uni.$u.props.cell.title + }, + // 标题下方的描述信息 + label: { + type: [String, Number], + default: uni.$u.props.cell.label + }, + // 右侧的内容 + value: { + type: [String, Number], + default: uni.$u.props.cell.value + }, + // 左侧图标名称,或者图片链接(本地文件建议使用绝对地址) + icon: { + type: String, + default: uni.$u.props.cell.icon + }, + // 是否禁用cell + disabled: { + type: Boolean, + default: uni.$u.props.cell.disabled + }, + // 是否显示下边框 + border: { + type: Boolean, + default: uni.$u.props.cell.border + }, + // 内容是否垂直居中(主要是针对右侧的value部分) + center: { + type: Boolean, + default: uni.$u.props.cell.center + }, + // 点击后跳转的URL地址 + url: { + type: String, + default: uni.$u.props.cell.url + }, + // 链接跳转的方式,内部使用的是uView封装的route方法,可能会进行拦截操作 + linkType: { + type: String, + default: uni.$u.props.cell.linkType + }, + // 是否开启点击反馈(表现为点击时加上灰色背景) + clickable: { + type: Boolean, + default: uni.$u.props.cell.clickable + }, + // 是否展示右侧箭头并开启点击反馈 + isLink: { + type: Boolean, + default: uni.$u.props.cell.isLink + }, + // 是否显示表单状态下的必填星号(此组件可能会内嵌入input组件) + required: { + type: Boolean, + default: uni.$u.props.cell.required + }, + // 右侧的图标箭头 + rightIcon: { + type: String, + default: uni.$u.props.cell.rightIcon + }, + // 右侧箭头的方向,可选值为:left,up,down + arrowDirection: { + type: String, + default: uni.$u.props.cell.arrowDirection + }, + // 左侧图标样式 + iconStyle: { + type: [Object, String], + default: () => { + return uni.$u.props.cell.iconStyle + } + }, + // 右侧箭头图标的样式 + rightIconStyle: { + type: [Object, String], + default: () => { + return uni.$u.props.cell.rightIconStyle + } + }, + // 标题的样式 + titleStyle: { + type: [Object, String], + default: () => { + return uni.$u.props.cell.titleStyle + } + }, + // 单位元的大小,可选值为large + size: { + type: String, + default: uni.$u.props.cell.size + }, + // 点击cell是否阻止事件传播 + stop: { + type: Boolean, + default: uni.$u.props.cell.stop + }, + // 标识符,cell被点击时返回 + name: { + type: [Number, String], + default: uni.$u.props.cell.name + } + } +} diff --git a/uni_modules/uview-ui/components/u-cell/u-cell.vue b/uni_modules/uview-ui/components/u-cell/u-cell.vue new file mode 100644 index 0000000..b099c90 --- /dev/null +++ b/uni_modules/uview-ui/components/u-cell/u-cell.vue @@ -0,0 +1,229 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-checkbox-group/props.js b/uni_modules/uview-ui/components/u-checkbox-group/props.js new file mode 100644 index 0000000..2f818a1 --- /dev/null +++ b/uni_modules/uview-ui/components/u-checkbox-group/props.js @@ -0,0 +1,82 @@ +export default { + props: { + // 标识符 + name: { + type: String, + default: uni.$u.props.checkboxGroup.name + }, + // 绑定的值 + value: { + type: Array, + default: uni.$u.props.checkboxGroup.value + }, + // 形状,circle-圆形,square-方形 + shape: { + type: String, + default: uni.$u.props.checkboxGroup.shape + }, + // 是否禁用全部checkbox + disabled: { + type: Boolean, + default: uni.$u.props.checkboxGroup.disabled + }, + + // 选中状态下的颜色,如设置此值,将会覆盖parent的activeColor值 + activeColor: { + type: String, + default: uni.$u.props.checkboxGroup.activeColor + }, + // 未选中的颜色 + inactiveColor: { + type: String, + default: uni.$u.props.checkboxGroup.inactiveColor + }, + + // 整个组件的尺寸,默认px + size: { + type: [String, Number], + default: uni.$u.props.checkboxGroup.size + }, + // 布局方式,row-横向,column-纵向 + placement: { + type: String, + default: uni.$u.props.checkboxGroup.placement + }, + // label的字体大小,px单位 + labelSize: { + type: [String, Number], + default: uni.$u.props.checkboxGroup.labelSize + }, + // label的字体颜色 + labelColor: { + type: [String], + default: uni.$u.props.checkboxGroup.labelColor + }, + // 是否禁止点击文本操作 + labelDisabled: { + type: Boolean, + default: uni.$u.props.checkboxGroup.labelDisabled + }, + // 图标颜色 + iconColor: { + type: String, + default: uni.$u.props.checkboxGroup.iconColor + }, + // 图标的大小,单位px + iconSize: { + type: [String, Number], + default: uni.$u.props.checkboxGroup.iconSize + }, + // 勾选图标的对齐方式,left-左边,right-右边 + iconPlacement: { + type: String, + default: uni.$u.props.checkboxGroup.iconPlacement + }, + // 竖向配列时,是否显示下划线 + borderBottom: { + type: Boolean, + default: uni.$u.props.checkboxGroup.borderBottom + } + + } +} diff --git a/uni_modules/uview-ui/components/u-checkbox-group/u-checkbox-group.vue b/uni_modules/uview-ui/components/u-checkbox-group/u-checkbox-group.vue new file mode 100644 index 0000000..7a6b4fa --- /dev/null +++ b/uni_modules/uview-ui/components/u-checkbox-group/u-checkbox-group.vue @@ -0,0 +1,103 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-checkbox/props.js b/uni_modules/uview-ui/components/u-checkbox/props.js new file mode 100644 index 0000000..93f4fd9 --- /dev/null +++ b/uni_modules/uview-ui/components/u-checkbox/props.js @@ -0,0 +1,69 @@ +export default { + props: { + // checkbox的名称 + name: { + type: [String, Number, Boolean], + default: uni.$u.props.checkbox.name + }, + // 形状,square为方形,circle为圆型 + shape: { + type: String, + default: uni.$u.props.checkbox.shape + }, + // 整体的大小 + size: { + type: [String, Number], + default: uni.$u.props.checkbox.size + }, + // 是否默认选中 + checked: { + type: Boolean, + default: uni.$u.props.checkbox.checked + }, + // 是否禁用 + disabled: { + type: [String, Boolean], + default: uni.$u.props.checkbox.disabled + }, + // 选中状态下的颜色,如设置此值,将会覆盖parent的activeColor值 + activeColor: { + type: String, + default: uni.$u.props.checkbox.activeColor + }, + // 未选中的颜色 + inactiveColor: { + type: String, + default: uni.$u.props.checkbox.inactiveColor + }, + // 图标的大小,单位px + iconSize: { + type: [String, Number], + default: uni.$u.props.checkbox.iconSize + }, + // 图标颜色 + iconColor: { + type: String, + default: uni.$u.props.checkbox.iconColor + }, + // label提示文字,因为nvue下,直接slot进来的文字,由于特殊的结构,无法修改样式 + label: { + type: [String, Number], + default: uni.$u.props.checkbox.label + }, + // label的字体大小,px单位 + labelSize: { + type: [String, Number], + default: uni.$u.props.checkbox.labelSize + }, + // label的颜色 + labelColor: { + type: String, + default: uni.$u.props.checkbox.labelColor + }, + // 是否禁止点击提示语选中复选框 + labelDisabled: { + type: [String, Boolean], + default: uni.$u.props.checkbox.labelDisabled + } + } +} diff --git a/uni_modules/uview-ui/components/u-checkbox/u-checkbox.vue b/uni_modules/uview-ui/components/u-checkbox/u-checkbox.vue new file mode 100644 index 0000000..6429cca --- /dev/null +++ b/uni_modules/uview-ui/components/u-checkbox/u-checkbox.vue @@ -0,0 +1,344 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-circle-progress/props.js b/uni_modules/uview-ui/components/u-circle-progress/props.js new file mode 100644 index 0000000..d776cfb --- /dev/null +++ b/uni_modules/uview-ui/components/u-circle-progress/props.js @@ -0,0 +1,8 @@ +export default { + props: { + percentage: { + type: [String, Number], + default: uni.$u.props.circleProgress.percentage + } + } +} diff --git a/uni_modules/uview-ui/components/u-circle-progress/u-circle-progress.vue b/uni_modules/uview-ui/components/u-circle-progress/u-circle-progress.vue new file mode 100644 index 0000000..d1ee286 --- /dev/null +++ b/uni_modules/uview-ui/components/u-circle-progress/u-circle-progress.vue @@ -0,0 +1,198 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-code-input/props.js b/uni_modules/uview-ui/components/u-code-input/props.js new file mode 100644 index 0000000..0f016ee --- /dev/null +++ b/uni_modules/uview-ui/components/u-code-input/props.js @@ -0,0 +1,79 @@ +export default { + props: { + // 键盘弹起时,是否自动上推页面 + adjustPosition: { + type: Boolean, + default: uni.$u.props.codeInput.adjustPosition + }, + // 最大输入长度 + maxlength: { + type: [String, Number], + default: uni.$u.props.codeInput.maxlength + }, + // 是否用圆点填充 + dot: { + type: Boolean, + default: uni.$u.props.codeInput.dot + }, + // 显示模式,box-盒子模式,line-底部横线模式 + mode: { + type: String, + default: uni.$u.props.codeInput.mode + }, + // 是否细边框 + hairline: { + type: Boolean, + default: uni.$u.props.codeInput.hairline + }, + // 字符间的距离 + space: { + type: [String, Number], + default: uni.$u.props.codeInput.space + }, + // 预置值 + value: { + type: [String, Number], + default: uni.$u.props.codeInput.value + }, + // 是否自动获取焦点 + focus: { + type: Boolean, + default: uni.$u.props.codeInput.focus + }, + // 字体是否加粗 + bold: { + type: Boolean, + default: uni.$u.props.codeInput.bold + }, + // 字体颜色 + color: { + type: String, + default: uni.$u.props.codeInput.color + }, + // 字体大小 + fontSize: { + type: [String, Number], + default: uni.$u.props.codeInput.fontSize + }, + // 输入框的大小,宽等于高 + size: { + type: [String, Number], + default: uni.$u.props.codeInput.size + }, + // 是否隐藏原生键盘,如果想用自定义键盘的话,需设置此参数为true + disabledKeyboard: { + type: Boolean, + default: uni.$u.props.codeInput.disabledKeyboard + }, + // 边框和线条颜色 + borderColor: { + type: String, + default: uni.$u.props.codeInput.borderColor + }, + // 是否禁止输入"."符号 + disabledDot: { + type: Boolean, + default: uni.$u.props.codeInput.disabledDot + } + } +} diff --git a/uni_modules/uview-ui/components/u-code-input/u-code-input.vue b/uni_modules/uview-ui/components/u-code-input/u-code-input.vue new file mode 100644 index 0000000..96241cf --- /dev/null +++ b/uni_modules/uview-ui/components/u-code-input/u-code-input.vue @@ -0,0 +1,252 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-code/props.js b/uni_modules/uview-ui/components/u-code/props.js new file mode 100644 index 0000000..eaf80d0 --- /dev/null +++ b/uni_modules/uview-ui/components/u-code/props.js @@ -0,0 +1,34 @@ +export default { + props: { + // 倒计时总秒数 + seconds: { + type: [String, Number], + default: uni.$u.props.code.seconds + }, + // 尚未开始时提示 + startText: { + type: String, + default: uni.$u.props.code.startText + }, + // 正在倒计时中的提示 + changeText: { + type: String, + default: uni.$u.props.code.changeText + }, + // 倒计时结束时的提示 + endText: { + type: String, + default: uni.$u.props.code.endText + }, + // 是否在H5刷新或各端返回再进入时继续倒计时 + keepRunning: { + type: Boolean, + default: uni.$u.props.code.keepRunning + }, + // 为了区分多个页面,或者一个页面多个倒计时组件本地存储的继续倒计时变了 + uniqueKey: { + type: String, + default: uni.$u.props.code.uniqueKey + } + } +} diff --git a/uni_modules/uview-ui/components/u-code/u-code.vue b/uni_modules/uview-ui/components/u-code/u-code.vue new file mode 100644 index 0000000..f79a09a --- /dev/null +++ b/uni_modules/uview-ui/components/u-code/u-code.vue @@ -0,0 +1,129 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-col/props.js b/uni_modules/uview-ui/components/u-col/props.js new file mode 100644 index 0000000..0622251 --- /dev/null +++ b/uni_modules/uview-ui/components/u-col/props.js @@ -0,0 +1,29 @@ +export default { + props: { + // 占父容器宽度的多少等分,总分为12份 + span: { + type: [String, Number], + default: uni.$u.props.col.span + }, + // 指定栅格左侧的间隔数(总12栏) + offset: { + type: [String, Number], + default: uni.$u.props.col.offset + }, + // 水平排列方式,可选值为`start`(或`flex-start`)、`end`(或`flex-end`)、`center`、`around`(或`space-around`)、`between`(或`space-between`) + justify: { + type: String, + default: uni.$u.props.col.justify + }, + // 垂直对齐方式,可选值为top、center、bottom、stretch + align: { + type: String, + default: uni.$u.props.col.align + }, + // 文字对齐方式 + textAlign: { + type: String, + default: uni.$u.props.col.textAlign + } + } +} diff --git a/uni_modules/uview-ui/components/u-col/u-col.vue b/uni_modules/uview-ui/components/u-col/u-col.vue new file mode 100644 index 0000000..8be1517 --- /dev/null +++ b/uni_modules/uview-ui/components/u-col/u-col.vue @@ -0,0 +1,162 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-collapse-item/props.js b/uni_modules/uview-ui/components/u-collapse-item/props.js new file mode 100644 index 0000000..bd5749b --- /dev/null +++ b/uni_modules/uview-ui/components/u-collapse-item/props.js @@ -0,0 +1,59 @@ +export default { + props: { + // 标题 + title: { + type: String, + default: uni.$u.props.collapseItem.title + }, + // 标题右侧内容 + value: { + type: String, + default: uni.$u.props.collapseItem.value + }, + // 标题下方的描述信息 + label: { + type: String, + default: uni.$u.props.collapseItem.label + }, + // 是否禁用折叠面板 + disabled: { + type: Boolean, + default: uni.$u.props.collapseItem.disabled + }, + // 是否展示右侧箭头并开启点击反馈 + isLink: { + type: Boolean, + default: uni.$u.props.collapseItem.isLink + }, + // 是否开启点击反馈 + clickable: { + type: Boolean, + default: uni.$u.props.collapseItem.clickable + }, + // 是否显示内边框 + border: { + type: Boolean, + default: uni.$u.props.collapseItem.border + }, + // 标题的对齐方式 + align: { + type: String, + default: uni.$u.props.collapseItem.align + }, + // 唯一标识符 + name: { + type: [String, Number], + default: uni.$u.props.collapseItem.name + }, + // 标题左侧图片,可为绝对路径的图片或内置图标 + icon: { + type: String, + default: uni.$u.props.collapseItem.icon + }, + // 面板展开收起的过渡时间,单位ms + duration: { + type: Number, + default: uni.$u.props.collapseItem.duration + } + } +} diff --git a/uni_modules/uview-ui/components/u-collapse-item/u-collapse-item.vue b/uni_modules/uview-ui/components/u-collapse-item/u-collapse-item.vue new file mode 100644 index 0000000..0e1b703 --- /dev/null +++ b/uni_modules/uview-ui/components/u-collapse-item/u-collapse-item.vue @@ -0,0 +1,225 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-collapse/props.js b/uni_modules/uview-ui/components/u-collapse/props.js new file mode 100644 index 0000000..7ee6d31 --- /dev/null +++ b/uni_modules/uview-ui/components/u-collapse/props.js @@ -0,0 +1,19 @@ +export default { + props: { + // 当前展开面板的name,非手风琴模式:[],手风琴模式:string | number + value: { + type: [String, Number, Array, null], + default: uni.$u.props.collapse.value + }, + // 是否手风琴模式 + accordion: { + type: Boolean, + default: uni.$u.props.collapse.accordion + }, + // 是否显示外边框 + border: { + type: Boolean, + default: uni.$u.props.collapse.border + } + } +} diff --git a/uni_modules/uview-ui/components/u-collapse/u-collapse.vue b/uni_modules/uview-ui/components/u-collapse/u-collapse.vue new file mode 100644 index 0000000..fc188a2 --- /dev/null +++ b/uni_modules/uview-ui/components/u-collapse/u-collapse.vue @@ -0,0 +1,90 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-column-notice/props.js b/uni_modules/uview-ui/components/u-column-notice/props.js new file mode 100644 index 0000000..4809154 --- /dev/null +++ b/uni_modules/uview-ui/components/u-column-notice/props.js @@ -0,0 +1,55 @@ +export default { + props: { + // 显示的内容,字符串 + text: { + type: [Array], + default: uni.$u.props.columnNotice.text + }, + // 是否显示左侧的音量图标 + icon: { + type: String, + default: uni.$u.props.columnNotice.icon + }, + // 通告模式,link-显示右箭头,closable-显示右侧关闭图标 + mode: { + type: String, + default: uni.$u.props.columnNotice.mode + }, + // 文字颜色,各图标也会使用文字颜色 + color: { + type: String, + default: uni.$u.props.columnNotice.color + }, + // 背景颜色 + bgColor: { + type: String, + default: uni.$u.props.columnNotice.bgColor + }, + // 字体大小,单位px + fontSize: { + type: [String, Number], + default: uni.$u.props.columnNotice.fontSize + }, + // 水平滚动时的滚动速度,即每秒滚动多少px(px),这有利于控制文字无论多少时,都能有一个恒定的速度 + speed: { + type: [String, Number], + default: uni.$u.props.columnNotice.speed + }, + // direction = row时,是否使用步进形式滚动 + step: { + type: Boolean, + default: uni.$u.props.columnNotice.step + }, + // 滚动一个周期的时间长,单位ms + duration: { + type: [String, Number], + default: uni.$u.props.columnNotice.duration + }, + // 是否禁止用手滑动切换 + // 目前HX2.6.11,只支持App 2.5.5+、H5 2.5.5+、支付宝小程序、字节跳动小程序 + disableTouch: { + type: Boolean, + default: uni.$u.props.columnNotice.disableTouch + } + } +} diff --git a/uni_modules/uview-ui/components/u-column-notice/u-column-notice.vue b/uni_modules/uview-ui/components/u-column-notice/u-column-notice.vue new file mode 100644 index 0000000..fc39532 --- /dev/null +++ b/uni_modules/uview-ui/components/u-column-notice/u-column-notice.vue @@ -0,0 +1,160 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-count-down/props.js b/uni_modules/uview-ui/components/u-count-down/props.js new file mode 100644 index 0000000..d62f025 --- /dev/null +++ b/uni_modules/uview-ui/components/u-count-down/props.js @@ -0,0 +1,24 @@ +export default { + props: { + // 倒计时时长,单位ms + time: { + type: [String, Number], + default: uni.$u.props.countDown.time + }, + // 时间格式,DD-日,HH-时,mm-分,ss-秒,SSS-毫秒 + format: { + type: String, + default: uni.$u.props.countDown.format + }, + // 是否自动开始倒计时 + autoStart: { + type: Boolean, + default: uni.$u.props.countDown.autoStart + }, + // 是否展示毫秒倒计时 + millisecond: { + type: Boolean, + default: uni.$u.props.countDown.millisecond + } + } +} diff --git a/uni_modules/uview-ui/components/u-count-down/u-count-down.vue b/uni_modules/uview-ui/components/u-count-down/u-count-down.vue new file mode 100644 index 0000000..b5e85a6 --- /dev/null +++ b/uni_modules/uview-ui/components/u-count-down/u-count-down.vue @@ -0,0 +1,163 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-count-down/utils.js b/uni_modules/uview-ui/components/u-count-down/utils.js new file mode 100644 index 0000000..8c75005 --- /dev/null +++ b/uni_modules/uview-ui/components/u-count-down/utils.js @@ -0,0 +1,62 @@ +// 补0,如1 -> 01 +function padZero(num, targetLength = 2) { + let str = `${num}` + while (str.length < targetLength) { + str = `0${str}` + } + return str +} +const SECOND = 1000 +const MINUTE = 60 * SECOND +const HOUR = 60 * MINUTE +const DAY = 24 * HOUR +export function parseTimeData(time) { + const days = Math.floor(time / DAY) + const hours = Math.floor((time % DAY) / HOUR) + const minutes = Math.floor((time % HOUR) / MINUTE) + const seconds = Math.floor((time % MINUTE) / SECOND) + const milliseconds = Math.floor(time % SECOND) + return { + days, + hours, + minutes, + seconds, + milliseconds + } +} +export function parseFormat(format, timeData) { + let { + days, + hours, + minutes, + seconds, + milliseconds + } = timeData + // 如果格式化字符串中不存在DD(天),则将天的时间转为小时中去 + if (format.indexOf('DD') === -1) { + hours += days * 24 + } else { + // 对天补0 + format = format.replace('DD', padZero(days)) + } + // 其他同理于DD的格式化处理方式 + if (format.indexOf('HH') === -1) { + minutes += hours * 60 + } else { + format = format.replace('HH', padZero(hours)) + } + if (format.indexOf('mm') === -1) { + seconds += minutes * 60 + } else { + format = format.replace('mm', padZero(minutes)) + } + if (format.indexOf('ss') === -1) { + milliseconds += seconds * 1000 + } else { + format = format.replace('ss', padZero(seconds)) + } + return format.replace('SSS', padZero(milliseconds, 3)) +} +export function isSameSecond(time1, time2) { + return Math.floor(time1 / 1000) === Math.floor(time2 / 1000) +} diff --git a/uni_modules/uview-ui/components/u-count-to/props.js b/uni_modules/uview-ui/components/u-count-to/props.js new file mode 100644 index 0000000..86873c1 --- /dev/null +++ b/uni_modules/uview-ui/components/u-count-to/props.js @@ -0,0 +1,59 @@ +export default { + props: { + // 开始的数值,默认从0增长到某一个数 + startVal: { + type: [String, Number], + default: uni.$u.props.countTo.startVal + }, + // 要滚动的目标数值,必须 + endVal: { + type: [String, Number], + default: uni.$u.props.countTo.endVal + }, + // 滚动到目标数值的动画持续时间,单位为毫秒(ms) + duration: { + type: [String, Number], + default: uni.$u.props.countTo.duration + }, + // 设置数值后是否自动开始滚动 + autoplay: { + type: Boolean, + default: uni.$u.props.countTo.autoplay + }, + // 要显示的小数位数 + decimals: { + type: [String, Number], + default: uni.$u.props.countTo.decimals + }, + // 是否在即将到达目标数值的时候,使用缓慢滚动的效果 + useEasing: { + type: Boolean, + default: uni.$u.props.countTo.useEasing + }, + // 十进制分割 + decimal: { + type: [String, Number], + default: uni.$u.props.countTo.decimal + }, + // 字体颜色 + color: { + type: String, + default: uni.$u.props.countTo.color + }, + // 字体大小 + fontSize: { + type: [String, Number], + default: uni.$u.props.countTo.fontSize + }, + // 是否加粗字体 + bold: { + type: Boolean, + default: uni.$u.props.countTo.bold + }, + // 千位分隔符,类似金额的分割(¥23,321.05中的",") + separator: { + type: String, + default: uni.$u.props.countTo.separator + } + } +} diff --git a/uni_modules/uview-ui/components/u-count-to/u-count-to.vue b/uni_modules/uview-ui/components/u-count-to/u-count-to.vue new file mode 100644 index 0000000..417b732 --- /dev/null +++ b/uni_modules/uview-ui/components/u-count-to/u-count-to.vue @@ -0,0 +1,184 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-datetime-picker/props.js b/uni_modules/uview-ui/components/u-datetime-picker/props.js new file mode 100644 index 0000000..f44c0f9 --- /dev/null +++ b/uni_modules/uview-ui/components/u-datetime-picker/props.js @@ -0,0 +1,116 @@ +export default { + props: { + // 是否打开组件 + show: { + type: Boolean, + default: uni.$u.props.datetimePicker.show + }, + // 是否展示顶部的操作栏 + showToolbar: { + type: Boolean, + default: uni.$u.props.datetimePicker.showToolbar + }, + // 绑定值 + value: { + type: [String, Number], + default: uni.$u.props.datetimePicker.value + }, + // 顶部标题 + title: { + type: String, + default: uni.$u.props.datetimePicker.title + }, + // 展示格式,mode=date为日期选择,mode=time为时间选择,mode=year-month为年月选择,mode=datetime为日期时间选择 + mode: { + type: String, + default: uni.$u.props.datetimePicker.mode + }, + // 可选的最大时间 + maxDate: { + type: Number, + // 最大默认值为后10年 + default: uni.$u.props.datetimePicker.maxDate + }, + // 可选的最小时间 + minDate: { + type: Number, + // 最小默认值为前10年 + default: uni.$u.props.datetimePicker.minDate + }, + // 可选的最小小时,仅mode=time有效 + minHour: { + type: Number, + default: uni.$u.props.datetimePicker.minHour + }, + // 可选的最大小时,仅mode=time有效 + maxHour: { + type: Number, + default: uni.$u.props.datetimePicker.maxHour + }, + // 可选的最小分钟,仅mode=time有效 + minMinute: { + type: Number, + default: uni.$u.props.datetimePicker.minMinute + }, + // 可选的最大分钟,仅mode=time有效 + maxMinute: { + type: Number, + default: uni.$u.props.datetimePicker.maxMinute + }, + // 选项过滤函数 + filter: { + type: [Function, null], + default: uni.$u.props.datetimePicker.filter + }, + // 选项格式化函数 + formatter: { + type: [Function, null], + default: uni.$u.props.datetimePicker.formatter + }, + // 是否显示加载中状态 + loading: { + type: Boolean, + default: uni.$u.props.datetimePicker.loading + }, + // 各列中,单个选项的高度 + itemHeight: { + type: [String, Number], + default: uni.$u.props.datetimePicker.itemHeight + }, + // 取消按钮的文字 + cancelText: { + type: String, + default: uni.$u.props.datetimePicker.cancelText + }, + // 确认按钮的文字 + confirmText: { + type: String, + default: uni.$u.props.datetimePicker.confirmText + }, + // 取消按钮的颜色 + cancelColor: { + type: String, + default: uni.$u.props.datetimePicker.cancelColor + }, + // 确认按钮的颜色 + confirmColor: { + type: String, + default: uni.$u.props.datetimePicker.confirmColor + }, + // 每列中可见选项的数量 + visibleItemCount: { + type: [String, Number], + default: uni.$u.props.datetimePicker.visibleItemCount + }, + // 是否允许点击遮罩关闭选择器 + closeOnClickOverlay: { + type: Boolean, + default: uni.$u.props.datetimePicker.closeOnClickOverlay + }, + // 各列的默认索引 + defaultIndex: { + type: Array, + default: uni.$u.props.datetimePicker.defaultIndex + } + } +} diff --git a/uni_modules/uview-ui/components/u-datetime-picker/u-datetime-picker.vue b/uni_modules/uview-ui/components/u-datetime-picker/u-datetime-picker.vue new file mode 100644 index 0000000..18d8dcc --- /dev/null +++ b/uni_modules/uview-ui/components/u-datetime-picker/u-datetime-picker.vue @@ -0,0 +1,360 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-divider/props.js b/uni_modules/uview-ui/components/u-divider/props.js new file mode 100644 index 0000000..1fa8359 --- /dev/null +++ b/uni_modules/uview-ui/components/u-divider/props.js @@ -0,0 +1,44 @@ +export default { + props: { + // 是否虚线 + dashed: { + type: Boolean, + default: uni.$u.props.divider.dashed + }, + // 是否细线 + hairline: { + type: Boolean, + default: uni.$u.props.divider.hairline + }, + // 是否以点替代文字,优先于text字段起作用 + dot: { + type: Boolean, + default: uni.$u.props.divider.dot + }, + // 内容文本的位置,left-左边,center-中间,right-右边 + textPosition: { + type: String, + default: uni.$u.props.divider.textPosition + }, + // 文本内容 + text: { + type: [String, Number], + default: uni.$u.props.divider.text + }, + // 文本大小 + textSize: { + type: [String, Number], + default: uni.$u.props.divider.textSize + }, + // 文本颜色 + textColor: { + type: String, + default: uni.$u.props.divider.textColor + }, + // 线条颜色 + lineColor: { + type: String, + default: uni.$u.props.divider.lineColor + } + } +} diff --git a/uni_modules/uview-ui/components/u-divider/u-divider.vue b/uni_modules/uview-ui/components/u-divider/u-divider.vue new file mode 100644 index 0000000..b629da6 --- /dev/null +++ b/uni_modules/uview-ui/components/u-divider/u-divider.vue @@ -0,0 +1,116 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-dropdown-item/props.js b/uni_modules/uview-ui/components/u-dropdown-item/props.js new file mode 100644 index 0000000..501a1f0 --- /dev/null +++ b/uni_modules/uview-ui/components/u-dropdown-item/props.js @@ -0,0 +1,36 @@ +export default { + props: { + // 当前选中项的value值 + value: { + type: [Number, String, Array], + default: '' + }, + // 菜单项标题 + title: { + type: [String, Number], + default: '' + }, + // 选项数据,如果传入了默认slot,此参数无效 + options: { + type: Array, + default() { + return [] + } + }, + // 是否禁用此菜单项 + disabled: { + type: Boolean, + default: false + }, + // 下拉弹窗的高度 + height: { + type: [Number, String], + default: 'auto' + }, + // 点击遮罩是否可以收起弹窗 + closeOnClickOverlay: { + type: Boolean, + default: true + } + } +} diff --git a/uni_modules/uview-ui/components/u-dropdown-item/u-dropdown-item.vue b/uni_modules/uview-ui/components/u-dropdown-item/u-dropdown-item.vue new file mode 100644 index 0000000..f830291 --- /dev/null +++ b/uni_modules/uview-ui/components/u-dropdown-item/u-dropdown-item.vue @@ -0,0 +1,127 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-dropdown/props.js b/uni_modules/uview-ui/components/u-dropdown/props.js new file mode 100644 index 0000000..5f8465e --- /dev/null +++ b/uni_modules/uview-ui/components/u-dropdown/props.js @@ -0,0 +1,65 @@ +export default { + props: { + // 标题选中时的样式 + activeStyle: { + type: [String, Object], + default: () => ({ + color: '#2979ff', + fontSize: '14px' + }) + }, + // 标题未选中时的样式 + inactiveStyle: { + type: [String, Object], + default: () => ({ + color: '#606266', + fontSize: '14px' + }) + }, + // 点击遮罩是否关闭菜单 + closeOnClickMask: { + type: Boolean, + default: true + }, + // 点击当前激活项标题是否关闭菜单 + closeOnClickSelf: { + type: Boolean, + default: true + }, + // 过渡时间 + duration: { + type: [Number, String], + default: 300 + }, + // 标题菜单的高度 + height: { + type: [Number, String], + default: 40 + }, + // 是否显示下边框 + borderBottom: { + type: Boolean, + default: false + }, + // 标题的字体大小 + titleSize: { + type: [Number, String], + default: 14 + }, + // 下拉出来的内容部分的圆角值 + borderRadius: { + type: [Number, String], + default: 0 + }, + // 菜单右侧的icon图标 + menuIcon: { + type: String, + default: 'arrow-down' + }, + // 菜单右侧图标的大小 + menuIconSize: { + type: [Number, String], + default: 14 + } + } +} diff --git a/uni_modules/uview-ui/components/u-dropdown/u-dropdown.vue b/uni_modules/uview-ui/components/u-dropdown/u-dropdown.vue new file mode 100644 index 0000000..f830291 --- /dev/null +++ b/uni_modules/uview-ui/components/u-dropdown/u-dropdown.vue @@ -0,0 +1,127 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-empty/props.js b/uni_modules/uview-ui/components/u-empty/props.js new file mode 100644 index 0000000..78662f8 --- /dev/null +++ b/uni_modules/uview-ui/components/u-empty/props.js @@ -0,0 +1,59 @@ +export default { + props: { + // 内置图标名称,或图片路径,建议绝对路径 + icon: { + type: String, + default: uni.$u.props.empty.icon + }, + // 提示文字 + text: { + type: String, + default: uni.$u.props.empty.text + }, + // 文字颜色 + textColor: { + type: String, + default: uni.$u.props.empty.textColor + }, + // 文字大小 + textSize: { + type: [String, Number], + default: uni.$u.props.empty.textSize + }, + // 图标的颜色 + iconColor: { + type: String, + default: uni.$u.props.empty.iconColor + }, + // 图标的大小 + iconSize: { + type: [String, Number], + default: uni.$u.props.empty.iconSize + }, + // 选择预置的图标类型 + mode: { + type: String, + default: uni.$u.props.empty.mode + }, + // 图标宽度,单位px + width: { + type: [String, Number], + default: uni.$u.props.empty.width + }, + // 图标高度,单位px + height: { + type: [String, Number], + default: uni.$u.props.empty.height + }, + // 是否显示组件 + show: { + type: Boolean, + default: uni.$u.props.empty.show + }, + // 组件距离上一个元素之间的距离,默认px单位 + marginTop: { + type: [String, Number], + default: uni.$u.props.empty.marginTop + } + } +} diff --git a/uni_modules/uview-ui/components/u-empty/u-empty.vue b/uni_modules/uview-ui/components/u-empty/u-empty.vue new file mode 100644 index 0000000..03d6a27 --- /dev/null +++ b/uni_modules/uview-ui/components/u-empty/u-empty.vue @@ -0,0 +1,128 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-form-item/props.js b/uni_modules/uview-ui/components/u-form-item/props.js new file mode 100644 index 0000000..7b16655 --- /dev/null +++ b/uni_modules/uview-ui/components/u-form-item/props.js @@ -0,0 +1,48 @@ +export default { + props: { + // input的label提示语 + label: { + type: String, + default: uni.$u.props.formItem.label + }, + // 绑定的值 + prop: { + type: String, + default: uni.$u.props.formItem.prop + }, + // 是否显示表单域的下划线边框 + borderBottom: { + type: [String, Boolean], + default: uni.$u.props.formItem.borderBottom + }, + // label的位置,left-左边,top-上边 + labelPosition: { + type: String, + default: uni.$u.props.formItem.labelPosition + }, + // label的宽度,单位px + labelWidth: { + type: [String, Number], + default: uni.$u.props.formItem.labelWidth + }, + // 右侧图标 + rightIcon: { + type: String, + default: uni.$u.props.formItem.rightIcon + }, + // 左侧图标 + leftIcon: { + type: String, + default: uni.$u.props.formItem.leftIcon + }, + // 是否显示左边的必填星号,只作显示用,具体校验必填的逻辑,请在rules中配置 + required: { + type: Boolean, + default: uni.$u.props.formItem.required + }, + leftIconStyle: { + type: [String, Object], + default: uni.$u.props.formItem.leftIconStyle, + } + } +} diff --git a/uni_modules/uview-ui/components/u-form-item/u-form-item.vue b/uni_modules/uview-ui/components/u-form-item/u-form-item.vue new file mode 100644 index 0000000..6aa8d69 --- /dev/null +++ b/uni_modules/uview-ui/components/u-form-item/u-form-item.vue @@ -0,0 +1,235 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-form/props.js b/uni_modules/uview-ui/components/u-form/props.js new file mode 100644 index 0000000..f2a629c --- /dev/null +++ b/uni_modules/uview-ui/components/u-form/props.js @@ -0,0 +1,45 @@ +export default { + props: { + // 当前form的需要验证字段的集合 + model: { + type: Object, + default: uni.$u.props.form.model + }, + // 验证规则 + rules: { + type: [Object, Function, Array], + default: uni.$u.props.form.rules + }, + // 有错误时的提示方式,message-提示信息,toast-进行toast提示 + // border-bottom-下边框呈现红色,none-无提示 + errorType: { + type: String, + default: uni.$u.props.form.errorType + }, + // 是否显示表单域的下划线边框 + borderBottom: { + type: Boolean, + default: uni.$u.props.form.borderBottom + }, + // label的位置,left-左边,top-上边 + labelPosition: { + type: String, + default: uni.$u.props.form.labelPosition + }, + // label的宽度,单位px + labelWidth: { + type: [String, Number], + default: uni.$u.props.form.labelWidth + }, + // lable字体的对齐方式 + labelAlign: { + type: String, + default: uni.$u.props.form.labelAlign + }, + // lable的样式,对象形式 + labelStyle: { + type: Object, + default: uni.$u.props.form.labelStyle + } + } +} diff --git a/uni_modules/uview-ui/components/u-form/u-form.vue b/uni_modules/uview-ui/components/u-form/u-form.vue new file mode 100644 index 0000000..fe2dde2 --- /dev/null +++ b/uni_modules/uview-ui/components/u-form/u-form.vue @@ -0,0 +1,214 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-gap/props.js b/uni_modules/uview-ui/components/u-gap/props.js new file mode 100644 index 0000000..89953e3 --- /dev/null +++ b/uni_modules/uview-ui/components/u-gap/props.js @@ -0,0 +1,24 @@ +export default { + props: { + // 背景颜色(默认transparent) + bgColor: { + type: String, + default: uni.$u.props.gap.bgColor + }, + // 分割槽高度,单位px(默认30) + height: { + type: [String, Number], + default: uni.$u.props.gap.height + }, + // 与上一个组件的距离 + marginTop: { + type: [String, Number], + default: uni.$u.props.gap.marginTop + }, + // 与下一个组件的距离 + marginBottom: { + type: [String, Number], + default: uni.$u.props.gap.marginBottom + } + } +} diff --git a/uni_modules/uview-ui/components/u-gap/u-gap.vue b/uni_modules/uview-ui/components/u-gap/u-gap.vue new file mode 100644 index 0000000..e4429f0 --- /dev/null +++ b/uni_modules/uview-ui/components/u-gap/u-gap.vue @@ -0,0 +1,38 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-grid-item/props.js b/uni_modules/uview-ui/components/u-grid-item/props.js new file mode 100644 index 0000000..06c3c66 --- /dev/null +++ b/uni_modules/uview-ui/components/u-grid-item/props.js @@ -0,0 +1,14 @@ +export default { + props: { + // 宫格的name + name: { + type: [String, Number, null], + default: uni.$u.props.gridItem.name + }, + // 背景颜色 + bgColor: { + type: String, + default: uni.$u.props.gridItem.bgColor + } + } +} diff --git a/uni_modules/uview-ui/components/u-grid-item/u-grid-item.vue b/uni_modules/uview-ui/components/u-grid-item/u-grid-item.vue new file mode 100644 index 0000000..fc0c7cf --- /dev/null +++ b/uni_modules/uview-ui/components/u-grid-item/u-grid-item.vue @@ -0,0 +1,209 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-grid/props.js b/uni_modules/uview-ui/components/u-grid/props.js new file mode 100644 index 0000000..87b0f6a --- /dev/null +++ b/uni_modules/uview-ui/components/u-grid/props.js @@ -0,0 +1,19 @@ +export default { + props: { + // 分成几列 + col: { + type: [String, Number], + default: uni.$u.props.grid.col + }, + // 是否显示边框 + border: { + type: Boolean, + default: uni.$u.props.grid.border + }, + // 宫格对齐方式,表现为数量少的时候,靠左,居中,还是靠右 + align: { + type: String, + default: uni.$u.props.grid.align + } + } +} diff --git a/uni_modules/uview-ui/components/u-grid/u-grid.vue b/uni_modules/uview-ui/components/u-grid/u-grid.vue new file mode 100644 index 0000000..b43cc27 --- /dev/null +++ b/uni_modules/uview-ui/components/u-grid/u-grid.vue @@ -0,0 +1,97 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-icon/icons.js b/uni_modules/uview-ui/components/u-icon/icons.js new file mode 100644 index 0000000..f4d0fe2 --- /dev/null +++ b/uni_modules/uview-ui/components/u-icon/icons.js @@ -0,0 +1,214 @@ +export default { + 'uicon-level': '\ue693', + 'uicon-column-line': '\ue68e', + 'uicon-checkbox-mark': '\ue807', + 'uicon-folder': '\ue7f5', + 'uicon-movie': '\ue7f6', + 'uicon-star-fill': '\ue669', + 'uicon-star': '\ue65f', + 'uicon-phone-fill': '\ue64f', + 'uicon-phone': '\ue622', + 'uicon-apple-fill': '\ue881', + 'uicon-chrome-circle-fill': '\ue885', + 'uicon-backspace': '\ue67b', + 'uicon-attach': '\ue632', + 'uicon-cut': '\ue948', + 'uicon-empty-car': '\ue602', + 'uicon-empty-coupon': '\ue682', + 'uicon-empty-address': '\ue646', + 'uicon-empty-favor': '\ue67c', + 'uicon-empty-permission': '\ue686', + 'uicon-empty-news': '\ue687', + 'uicon-empty-search': '\ue664', + 'uicon-github-circle-fill': '\ue887', + 'uicon-rmb': '\ue608', + 'uicon-person-delete-fill': '\ue66a', + 'uicon-reload': '\ue788', + 'uicon-order': '\ue68f', + 'uicon-server-man': '\ue6bc', + 'uicon-search': '\ue62a', + 'uicon-fingerprint': '\ue955', + 'uicon-more-dot-fill': '\ue630', + 'uicon-scan': '\ue662', + 'uicon-share-square': '\ue60b', + 'uicon-map': '\ue61d', + 'uicon-map-fill': '\ue64e', + 'uicon-tags': '\ue629', + 'uicon-tags-fill': '\ue651', + 'uicon-bookmark-fill': '\ue63b', + 'uicon-bookmark': '\ue60a', + 'uicon-eye': '\ue613', + 'uicon-eye-fill': '\ue641', + 'uicon-mic': '\ue64a', + 'uicon-mic-off': '\ue649', + 'uicon-calendar': '\ue66e', + 'uicon-calendar-fill': '\ue634', + 'uicon-trash': '\ue623', + 'uicon-trash-fill': '\ue658', + 'uicon-play-left': '\ue66d', + 'uicon-play-right': '\ue610', + 'uicon-minus': '\ue618', + 'uicon-plus': '\ue62d', + 'uicon-info': '\ue653', + 'uicon-info-circle': '\ue7d2', + 'uicon-info-circle-fill': '\ue64b', + 'uicon-question': '\ue715', + 'uicon-error': '\ue6d3', + 'uicon-close': '\ue685', + 'uicon-checkmark': '\ue6a8', + 'uicon-android-circle-fill': '\ue67e', + 'uicon-android-fill': '\ue67d', + 'uicon-ie': '\ue87b', + 'uicon-IE-circle-fill': '\ue889', + 'uicon-google': '\ue87a', + 'uicon-google-circle-fill': '\ue88a', + 'uicon-setting-fill': '\ue872', + 'uicon-setting': '\ue61f', + 'uicon-minus-square-fill': '\ue855', + 'uicon-plus-square-fill': '\ue856', + 'uicon-heart': '\ue7df', + 'uicon-heart-fill': '\ue851', + 'uicon-camera': '\ue7d7', + 'uicon-camera-fill': '\ue870', + 'uicon-more-circle': '\ue63e', + 'uicon-more-circle-fill': '\ue645', + 'uicon-chat': '\ue620', + 'uicon-chat-fill': '\ue61e', + 'uicon-bag-fill': '\ue617', + 'uicon-bag': '\ue619', + 'uicon-error-circle-fill': '\ue62c', + 'uicon-error-circle': '\ue624', + 'uicon-close-circle': '\ue63f', + 'uicon-close-circle-fill': '\ue637', + 'uicon-checkmark-circle': '\ue63d', + 'uicon-checkmark-circle-fill': '\ue635', + 'uicon-question-circle-fill': '\ue666', + 'uicon-question-circle': '\ue625', + 'uicon-share': '\ue631', + 'uicon-share-fill': '\ue65e', + 'uicon-shopping-cart': '\ue621', + 'uicon-shopping-cart-fill': '\ue65d', + 'uicon-bell': '\ue609', + 'uicon-bell-fill': '\ue640', + 'uicon-list': '\ue650', + 'uicon-list-dot': '\ue616', + 'uicon-zhihu': '\ue6ba', + 'uicon-zhihu-circle-fill': '\ue709', + 'uicon-zhifubao': '\ue6b9', + 'uicon-zhifubao-circle-fill': '\ue6b8', + 'uicon-weixin-circle-fill': '\ue6b1', + 'uicon-weixin-fill': '\ue6b2', + 'uicon-twitter-circle-fill': '\ue6ab', + 'uicon-twitter': '\ue6aa', + 'uicon-taobao-circle-fill': '\ue6a7', + 'uicon-taobao': '\ue6a6', + 'uicon-weibo-circle-fill': '\ue6a5', + 'uicon-weibo': '\ue6a4', + 'uicon-qq-fill': '\ue6a1', + 'uicon-qq-circle-fill': '\ue6a0', + 'uicon-moments-circel-fill': '\ue69a', + 'uicon-moments': '\ue69b', + 'uicon-qzone': '\ue695', + 'uicon-qzone-circle-fill': '\ue696', + 'uicon-baidu-circle-fill': '\ue680', + 'uicon-baidu': '\ue681', + 'uicon-facebook-circle-fill': '\ue68a', + 'uicon-facebook': '\ue689', + 'uicon-car': '\ue60c', + 'uicon-car-fill': '\ue636', + 'uicon-warning-fill': '\ue64d', + 'uicon-warning': '\ue694', + 'uicon-clock-fill': '\ue638', + 'uicon-clock': '\ue60f', + 'uicon-edit-pen': '\ue612', + 'uicon-edit-pen-fill': '\ue66b', + 'uicon-email': '\ue611', + 'uicon-email-fill': '\ue642', + 'uicon-minus-circle': '\ue61b', + 'uicon-minus-circle-fill': '\ue652', + 'uicon-plus-circle': '\ue62e', + 'uicon-plus-circle-fill': '\ue661', + 'uicon-file-text': '\ue663', + 'uicon-file-text-fill': '\ue665', + 'uicon-pushpin': '\ue7e3', + 'uicon-pushpin-fill': '\ue86e', + 'uicon-grid': '\ue673', + 'uicon-grid-fill': '\ue678', + 'uicon-play-circle': '\ue647', + 'uicon-play-circle-fill': '\ue655', + 'uicon-pause-circle-fill': '\ue654', + 'uicon-pause': '\ue8fa', + 'uicon-pause-circle': '\ue643', + 'uicon-eye-off': '\ue648', + 'uicon-eye-off-outline': '\ue62b', + 'uicon-gift-fill': '\ue65c', + 'uicon-gift': '\ue65b', + 'uicon-rmb-circle-fill': '\ue657', + 'uicon-rmb-circle': '\ue677', + 'uicon-kefu-ermai': '\ue656', + 'uicon-server-fill': '\ue751', + 'uicon-coupon-fill': '\ue8c4', + 'uicon-coupon': '\ue8ae', + 'uicon-integral': '\ue704', + 'uicon-integral-fill': '\ue703', + 'uicon-home-fill': '\ue964', + 'uicon-home': '\ue965', + 'uicon-hourglass-half-fill': '\ue966', + 'uicon-hourglass': '\ue967', + 'uicon-account': '\ue628', + 'uicon-plus-people-fill': '\ue626', + 'uicon-minus-people-fill': '\ue615', + 'uicon-account-fill': '\ue614', + 'uicon-thumb-down-fill': '\ue726', + 'uicon-thumb-down': '\ue727', + 'uicon-thumb-up': '\ue733', + 'uicon-thumb-up-fill': '\ue72f', + 'uicon-lock-fill': '\ue979', + 'uicon-lock-open': '\ue973', + 'uicon-lock-opened-fill': '\ue974', + 'uicon-lock': '\ue97a', + 'uicon-red-packet-fill': '\ue690', + 'uicon-photo-fill': '\ue98b', + 'uicon-photo': '\ue98d', + 'uicon-volume-off-fill': '\ue659', + 'uicon-volume-off': '\ue644', + 'uicon-volume-fill': '\ue670', + 'uicon-volume': '\ue633', + 'uicon-red-packet': '\ue691', + 'uicon-download': '\ue63c', + 'uicon-arrow-up-fill': '\ue6b0', + 'uicon-arrow-down-fill': '\ue600', + 'uicon-play-left-fill': '\ue675', + 'uicon-play-right-fill': '\ue676', + 'uicon-rewind-left-fill': '\ue679', + 'uicon-rewind-right-fill': '\ue67a', + 'uicon-arrow-downward': '\ue604', + 'uicon-arrow-leftward': '\ue601', + 'uicon-arrow-rightward': '\ue603', + 'uicon-arrow-upward': '\ue607', + 'uicon-arrow-down': '\ue60d', + 'uicon-arrow-right': '\ue605', + 'uicon-arrow-left': '\ue60e', + 'uicon-arrow-up': '\ue606', + 'uicon-skip-back-left': '\ue674', + 'uicon-skip-forward-right': '\ue672', + 'uicon-rewind-right': '\ue66f', + 'uicon-rewind-left': '\ue671', + 'uicon-arrow-right-double': '\ue68d', + 'uicon-arrow-left-double': '\ue68c', + 'uicon-wifi-off': '\ue668', + 'uicon-wifi': '\ue667', + 'uicon-empty-data': '\ue62f', + 'uicon-empty-history': '\ue684', + 'uicon-empty-list': '\ue68b', + 'uicon-empty-page': '\ue627', + 'uicon-empty-order': '\ue639', + 'uicon-man': '\ue697', + 'uicon-woman': '\ue69c', + 'uicon-man-add': '\ue61c', + 'uicon-man-add-fill': '\ue64c', + 'uicon-man-delete': '\ue61a', + 'uicon-man-delete-fill': '\ue66a', + 'uicon-zh': '\ue70a', + 'uicon-en': '\ue692' +} diff --git a/uni_modules/uview-ui/components/u-icon/props.js b/uni_modules/uview-ui/components/u-icon/props.js new file mode 100644 index 0000000..71845b7 --- /dev/null +++ b/uni_modules/uview-ui/components/u-icon/props.js @@ -0,0 +1,89 @@ +export default { + props: { + // 图标类名 + name: { + type: String, + default: uni.$u.props.icon.name + }, + // 图标颜色,可接受主题色 + color: { + type: String, + default: uni.$u.props.icon.color + }, + // 字体大小,单位px + size: { + type: [String, Number], + default: uni.$u.props.icon.size + }, + // 是否显示粗体 + bold: { + type: Boolean, + default: uni.$u.props.icon.bold + }, + // 点击图标的时候传递事件出去的index(用于区分点击了哪一个) + index: { + type: [String, Number], + default: uni.$u.props.icon.index + }, + // 触摸图标时的类名 + hoverClass: { + type: String, + default: uni.$u.props.icon.hoverClass + }, + // 自定义扩展前缀,方便用户扩展自己的图标库 + customPrefix: { + type: String, + default: uni.$u.props.icon.customPrefix + }, + // 图标右边或者下面的文字 + label: { + type: [String, Number], + default: uni.$u.props.icon.label + }, + // label的位置,只能右边或者下边 + labelPos: { + type: String, + default: uni.$u.props.icon.labelPos + }, + // label的大小 + labelSize: { + type: [String, Number], + default: uni.$u.props.icon.labelSize + }, + // label的颜色 + labelColor: { + type: String, + default: uni.$u.props.icon.labelColor + }, + // label与图标的距离 + space: { + type: [String, Number], + default: uni.$u.props.icon.space + }, + // 图片的mode + imgMode: { + type: String, + default: uni.$u.props.icon.imgMode + }, + // 用于显示图片小图标时,图片的宽度 + width: { + type: [String, Number], + default: uni.$u.props.icon.width + }, + // 用于显示图片小图标时,图片的高度 + height: { + type: [String, Number], + default: uni.$u.props.icon.height + }, + // 用于解决某些情况下,让图标垂直居中的用途 + top: { + type: [String, Number], + default: uni.$u.props.icon.top + }, + // 是否阻止事件传播 + stop: { + type: Boolean, + default: uni.$u.props.icon.stop + } + } +} diff --git a/uni_modules/uview-ui/components/u-icon/u-icon.vue b/uni_modules/uview-ui/components/u-icon/u-icon.vue new file mode 100644 index 0000000..9340328 --- /dev/null +++ b/uni_modules/uview-ui/components/u-icon/u-icon.vue @@ -0,0 +1,234 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-image/props.js b/uni_modules/uview-ui/components/u-image/props.js new file mode 100644 index 0000000..2eabb74 --- /dev/null +++ b/uni_modules/uview-ui/components/u-image/props.js @@ -0,0 +1,84 @@ +export default { + props: { + // 图片地址 + src: { + type: String, + default: uni.$u.props.image.src + }, + // 裁剪模式 + mode: { + type: String, + default: uni.$u.props.image.mode + }, + // 宽度,单位任意 + width: { + type: [String, Number], + default: uni.$u.props.image.width + }, + // 高度,单位任意 + height: { + type: [String, Number], + default: uni.$u.props.image.height + }, + // 图片形状,circle-圆形,square-方形 + shape: { + type: String, + default: uni.$u.props.image.shape + }, + // 圆角,单位任意 + radius: { + type: [String, Number], + default: uni.$u.props.image.radius + }, + // 是否懒加载,微信小程序、App、百度小程序、字节跳动小程序 + lazyLoad: { + type: Boolean, + default: uni.$u.props.image.lazyLoad + }, + // 开启长按图片显示识别微信小程序码菜单 + showMenuByLongpress: { + type: Boolean, + default: uni.$u.props.image.showMenuByLongpress + }, + // 加载中的图标,或者小图片 + loadingIcon: { + type: String, + default: uni.$u.props.image.loadingIcon + }, + // 加载失败的图标,或者小图片 + errorIcon: { + type: String, + default: uni.$u.props.image.errorIcon + }, + // 是否显示加载中的图标或者自定义的slot + showLoading: { + type: Boolean, + default: uni.$u.props.image.showLoading + }, + // 是否显示加载错误的图标或者自定义的slot + showError: { + type: Boolean, + default: uni.$u.props.image.showError + }, + // 是否需要淡入效果 + fade: { + type: Boolean, + default: uni.$u.props.image.fade + }, + // 只支持网络资源,只对微信小程序有效 + webp: { + type: Boolean, + default: uni.$u.props.image.webp + }, + // 过渡时间,单位ms + duration: { + type: [String, Number], + default: uni.$u.props.image.duration + }, + // 背景颜色,用于深色页面加载图片时,为了和背景色融合 + bgColor: { + type: String, + default: uni.$u.props.image.bgColor + } + } +} diff --git a/uni_modules/uview-ui/components/u-image/u-image.vue b/uni_modules/uview-ui/components/u-image/u-image.vue new file mode 100644 index 0000000..473e35b --- /dev/null +++ b/uni_modules/uview-ui/components/u-image/u-image.vue @@ -0,0 +1,232 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-index-anchor/props.js b/uni_modules/uview-ui/components/u-index-anchor/props.js new file mode 100644 index 0000000..6d8b59a --- /dev/null +++ b/uni_modules/uview-ui/components/u-index-anchor/props.js @@ -0,0 +1,29 @@ +export default { + props: { + // 列表锚点文本内容 + text: { + type: [String, Number], + default: uni.$u.props.indexAnchor.text + }, + // 列表锚点文字颜色 + color: { + type: String, + default: uni.$u.props.indexAnchor.color + }, + // 列表锚点文字大小,单位默认px + size: { + type: [String, Number], + default: uni.$u.props.indexAnchor.size + }, + // 列表锚点背景颜色 + bgColor: { + type: String, + default: uni.$u.props.indexAnchor.bgColor + }, + // 列表锚点高度,单位默认px + height: { + type: [String, Number], + default: uni.$u.props.indexAnchor.height + } + } +} diff --git a/uni_modules/uview-ui/components/u-index-anchor/u-index-anchor.vue b/uni_modules/uview-ui/components/u-index-anchor/u-index-anchor.vue new file mode 100644 index 0000000..b95ddef --- /dev/null +++ b/uni_modules/uview-ui/components/u-index-anchor/u-index-anchor.vue @@ -0,0 +1,91 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-index-item/props.js b/uni_modules/uview-ui/components/u-index-item/props.js new file mode 100644 index 0000000..7c11331 --- /dev/null +++ b/uni_modules/uview-ui/components/u-index-item/props.js @@ -0,0 +1,5 @@ +export default { + props: { + + } +} diff --git a/uni_modules/uview-ui/components/u-index-item/u-index-item.vue b/uni_modules/uview-ui/components/u-index-item/u-index-item.vue new file mode 100644 index 0000000..0bc7fb3 --- /dev/null +++ b/uni_modules/uview-ui/components/u-index-item/u-index-item.vue @@ -0,0 +1,87 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-index-list/props.js b/uni_modules/uview-ui/components/u-index-list/props.js new file mode 100644 index 0000000..354d459 --- /dev/null +++ b/uni_modules/uview-ui/components/u-index-list/props.js @@ -0,0 +1,29 @@ +export default { + props: { + // 右边锚点非激活的颜色 + inactiveColor: { + type: String, + default: uni.$u.props.indexList.inactiveColor + }, + // 右边锚点激活的颜色 + activeColor: { + type: String, + default: uni.$u.props.indexList.activeColor + }, + // 索引字符列表,数组形式 + indexList: { + type: Array, + default: uni.$u.props.indexList.indexList + }, + // 是否开启锚点自动吸顶 + sticky: { + type: Boolean, + default: uni.$u.props.indexList.sticky + }, + // 自定义导航栏的高度 + customNavHeight: { + type: [String, Number], + default: uni.$u.props.indexList.customNavHeight + } + } +} diff --git a/uni_modules/uview-ui/components/u-index-list/u-index-list.vue b/uni_modules/uview-ui/components/u-index-list/u-index-list.vue new file mode 100644 index 0000000..d712618 --- /dev/null +++ b/uni_modules/uview-ui/components/u-index-list/u-index-list.vue @@ -0,0 +1,440 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-input/props.js b/uni_modules/uview-ui/components/u-input/props.js new file mode 100644 index 0000000..2c50870 --- /dev/null +++ b/uni_modules/uview-ui/components/u-input/props.js @@ -0,0 +1,187 @@ +export default { + props: { + // 输入的值 + value: { + type: [String, Number], + default: uni.$u.props.input.value + }, + // 输入框类型 + // number-数字输入键盘,app-vue下可以输入浮点数,app-nvue和小程序平台下只能输入整数 + // idcard-身份证输入键盘,微信、支付宝、百度、QQ小程序 + // digit-带小数点的数字键盘,App的nvue页面、微信、支付宝、百度、头条、QQ小程序 + // text-文本输入键盘 + type: { + type: String, + default: uni.$u.props.input.type + }, + // 如果 textarea 是在一个 position:fixed 的区域,需要显示指定属性 fixed 为 true, + // 兼容性:微信小程序、百度小程序、字节跳动小程序、QQ小程序 + fixed: { + type: Boolean, + default: uni.$u.props.input.fixed + }, + // 是否禁用输入框 + disabled: { + type: Boolean, + default: uni.$u.props.input.disabled + }, + // 禁用状态时的背景色 + disabledColor: { + type: String, + default: uni.$u.props.input.disabledColor + }, + // 是否显示清除控件 + clearable: { + type: Boolean, + default: uni.$u.props.input.clearable + }, + // 是否密码类型 + password: { + type: Boolean, + default: uni.$u.props.input.password + }, + // 最大输入长度,设置为 -1 的时候不限制最大长度 + maxlength: { + type: [String, Number], + default: uni.$u.props.input.maxlength + }, + // 输入框为空时的占位符 + placeholder: { + type: String, + default: uni.$u.props.input.placeholder + }, + // 指定placeholder的样式类,注意页面或组件的style中写了scoped时,需要在类名前写/deep/ + placeholderClass: { + type: String, + default: uni.$u.props.input.placeholderClass + }, + // 指定placeholder的样式 + placeholderStyle: { + type: [String, Object], + default: uni.$u.props.input.placeholderStyle + }, + // 是否显示输入字数统计,只在 type ="text"或type ="textarea"时有效 + showWordLimit: { + type: Boolean, + default: uni.$u.props.input.showWordLimit + }, + // 设置右下角按钮的文字,有效值:send|search|next|go|done,兼容性详见uni-app文档 + // https://uniapp.dcloud.io/component/input + // https://uniapp.dcloud.io/component/textarea + confirmType: { + type: String, + default: uni.$u.props.input.confirmType + }, + // 点击键盘右下角按钮时是否保持键盘不收起,H5无效 + confirmHold: { + type: Boolean, + default: uni.$u.props.input.confirmHold + }, + // focus时,点击页面的时候不收起键盘,微信小程序有效 + holdKeyboard: { + type: Boolean, + default: uni.$u.props.input.holdKeyboard + }, + // 自动获取焦点 + // 在 H5 平台能否聚焦以及软键盘是否跟随弹出,取决于当前浏览器本身的实现。nvue 页面不支持,需使用组件的 focus()、blur() 方法控制焦点 + focus: { + type: Boolean, + default: uni.$u.props.input.focus + }, + // 键盘收起时,是否自动失去焦点,目前仅App3.0.0+有效 + autoBlur: { + type: Boolean, + default: uni.$u.props.input.autoBlur + }, + // 是否去掉 iOS 下的默认内边距,仅微信小程序,且type=textarea时有效 + disableDefaultPadding: { + type: Boolean, + default: uni.$u.props.input.disableDefaultPadding + }, + // 指定focus时光标的位置 + cursor: { + type: [String, Number], + default: uni.$u.props.input.cursor + }, + // 输入框聚焦时底部与键盘的距离 + cursorSpacing: { + type: [String, Number], + default: uni.$u.props.input.cursorSpacing + }, + // 光标起始位置,自动聚集时有效,需与selection-end搭配使用 + selectionStart: { + type: [String, Number], + default: uni.$u.props.input.selectionStart + }, + // 光标结束位置,自动聚集时有效,需与selection-start搭配使用 + selectionEnd: { + type: [String, Number], + default: uni.$u.props.input.selectionEnd + }, + // 键盘弹起时,是否自动上推页面 + adjustPosition: { + type: Boolean, + default: uni.$u.props.input.adjustPosition + }, + // 输入框内容对齐方式,可选值为:left|center|right + inputAlign: { + type: String, + default: uni.$u.props.input.inputAlign + }, + // 输入框字体的大小 + fontSize: { + type: [String, Number], + default: uni.$u.props.input.fontSize + }, + // 输入框字体颜色 + color: { + type: String, + default: uni.$u.props.input.color + }, + // 输入框前置图标 + prefixIcon: { + type: String, + default: uni.$u.props.input.prefixIcon + }, + // 前置图标样式,对象或字符串 + prefixIconStyle: { + type: [String, Object], + default: uni.$u.props.input.prefixIconStyle + }, + // 输入框后置图标 + suffixIcon: { + type: String, + default: uni.$u.props.input.suffixIcon + }, + // 后置图标样式,对象或字符串 + suffixIconStyle: { + type: [String, Object], + default: uni.$u.props.input.suffixIconStyle + }, + // 边框类型,surround-四周边框,bottom-底部边框,none-无边框 + border: { + type: String, + default: uni.$u.props.input.border + }, + // 是否只读,与disabled不同之处在于disabled会置灰组件,而readonly则不会 + readonly: { + type: Boolean, + default: uni.$u.props.input.readonly + }, + // 输入框形状,circle-圆形,square-方形 + shape: { + type: String, + default: uni.$u.props.input.shape + }, + // 用于处理或者过滤输入框内容的方法 + formatter: { + type: [Function, null], + default: uni.$u.props.input.formatter + }, + // 是否忽略组件内对文本合成系统事件的处理 + ignoreCompositionEvent: { + type: Boolean, + default: true + } + } +} diff --git a/uni_modules/uview-ui/components/u-input/u-input.vue b/uni_modules/uview-ui/components/u-input/u-input.vue new file mode 100644 index 0000000..30073eb --- /dev/null +++ b/uni_modules/uview-ui/components/u-input/u-input.vue @@ -0,0 +1,354 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-keyboard/props.js b/uni_modules/uview-ui/components/u-keyboard/props.js new file mode 100644 index 0000000..cfdb00a --- /dev/null +++ b/uni_modules/uview-ui/components/u-keyboard/props.js @@ -0,0 +1,84 @@ +export default { + props: { + // 键盘的类型,number-数字键盘,card-身份证键盘,car-车牌号键盘 + mode: { + type: String, + default: uni.$u.props.keyboard.mode + }, + // 是否显示键盘的"."符号 + dotDisabled: { + type: Boolean, + default: uni.$u.props.keyboard.dotDisabled + }, + // 是否显示顶部工具条 + tooltip: { + type: Boolean, + default: uni.$u.props.keyboard.tooltip + }, + // 是否显示工具条中间的提示 + showTips: { + type: Boolean, + default: uni.$u.props.keyboard.showTips + }, + // 工具条中间的提示文字 + tips: { + type: String, + default: uni.$u.props.keyboard.tips + }, + // 是否显示工具条左边的"取消"按钮 + showCancel: { + type: Boolean, + default: uni.$u.props.keyboard.showCancel + }, + // 是否显示工具条右边的"完成"按钮 + showConfirm: { + type: Boolean, + default: uni.$u.props.keyboard.showConfirm + }, + // 是否打乱键盘按键的顺序 + random: { + type: Boolean, + default: uni.$u.props.keyboard.random + }, + // 是否开启底部安全区适配,开启的话,会在iPhoneX机型底部添加一定的内边距 + safeAreaInsetBottom: { + type: Boolean, + default: uni.$u.props.keyboard.safeAreaInsetBottom + }, + // 是否允许通过点击遮罩关闭键盘 + closeOnClickOverlay: { + type: Boolean, + default: uni.$u.props.keyboard.closeOnClickOverlay + }, + // 控制键盘的弹出与收起 + show: { + type: Boolean, + default: uni.$u.props.keyboard.show + }, + // 是否显示遮罩,某些时候数字键盘时,用户希望看到自己的数值,所以可能不想要遮罩 + overlay: { + type: Boolean, + default: uni.$u.props.keyboard.overlay + }, + // z-index值 + zIndex: { + type: [String, Number], + default: uni.$u.props.keyboard.zIndex + }, + // 取消按钮的文字 + cancelText: { + type: String, + default: uni.$u.props.keyboard.cancelText + }, + // 确认按钮的文字 + confirmText: { + type: String, + default: uni.$u.props.keyboard.confirmText + }, + // 输入一个中文后,是否自动切换到英文 + autoChange: { + type: Boolean, + default: uni.$u.props.keyboard.autoChange + } + } +} diff --git a/uni_modules/uview-ui/components/u-keyboard/u-keyboard.vue b/uni_modules/uview-ui/components/u-keyboard/u-keyboard.vue new file mode 100644 index 0000000..14228cb --- /dev/null +++ b/uni_modules/uview-ui/components/u-keyboard/u-keyboard.vue @@ -0,0 +1,164 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-line-progress/props.js b/uni_modules/uview-ui/components/u-line-progress/props.js new file mode 100644 index 0000000..a4210bd --- /dev/null +++ b/uni_modules/uview-ui/components/u-line-progress/props.js @@ -0,0 +1,28 @@ +export default { + props: { + // 激活部分的颜色 + activeColor: { + type: String, + default: uni.$u.props.lineProgress.activeColor + }, + inactiveColor: { + type: String, + default: uni.$u.props.lineProgress.color + }, + // 进度百分比,数值 + percentage: { + type: [String, Number], + default: uni.$u.props.lineProgress.inactiveColor + }, + // 是否在进度条内部显示百分比的值 + showText: { + type: Boolean, + default: uni.$u.props.lineProgress.showText + }, + // 进度条的高度,单位px + height: { + type: [String, Number], + default: uni.$u.props.lineProgress.height + } + } +} diff --git a/uni_modules/uview-ui/components/u-line-progress/u-line-progress.vue b/uni_modules/uview-ui/components/u-line-progress/u-line-progress.vue new file mode 100644 index 0000000..4e27931 --- /dev/null +++ b/uni_modules/uview-ui/components/u-line-progress/u-line-progress.vue @@ -0,0 +1,144 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-line/props.js b/uni_modules/uview-ui/components/u-line/props.js new file mode 100644 index 0000000..2308cc3 --- /dev/null +++ b/uni_modules/uview-ui/components/u-line/props.js @@ -0,0 +1,33 @@ +export default { + props: { + color: { + type: String, + default: uni.$u.props.line.color + }, + // 长度,竖向时表现为高度,横向时表现为长度,可以为百分比,带px单位的值等 + length: { + type: [String, Number], + default: uni.$u.props.line.length + }, + // 线条方向,col-竖向,row-横向 + direction: { + type: String, + default: uni.$u.props.line.direction + }, + // 是否显示细边框 + hairline: { + type: Boolean, + default: uni.$u.props.line.hairline + }, + // 线条与上下左右元素的间距,字符串形式,如"30px"、"20px 30px" + margin: { + type: [String, Number], + default: uni.$u.props.line.margin + }, + // 是否虚线,true-虚线,false-实线 + dashed: { + type: Boolean, + default: uni.$u.props.line.dashed + } + } +} diff --git a/uni_modules/uview-ui/components/u-line/u-line.vue b/uni_modules/uview-ui/components/u-line/u-line.vue new file mode 100644 index 0000000..e0a6d92 --- /dev/null +++ b/uni_modules/uview-ui/components/u-line/u-line.vue @@ -0,0 +1,62 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-link/props.js b/uni_modules/uview-ui/components/u-link/props.js new file mode 100644 index 0000000..d39353f --- /dev/null +++ b/uni_modules/uview-ui/components/u-link/props.js @@ -0,0 +1,39 @@ +export default { + props: { + // 文字颜色 + color: { + type: String, + default: uni.$u.props.link.color + }, + // 字体大小,单位px + fontSize: { + type: [String, Number], + default: uni.$u.props.link.fontSize + }, + // 是否显示下划线 + underLine: { + type: Boolean, + default: uni.$u.props.link.underLine + }, + // 要跳转的链接 + href: { + type: String, + default: uni.$u.props.link.href + }, + // 小程序中复制到粘贴板的提示语 + mpTips: { + type: String, + default: uni.$u.props.link.mpTips + }, + // 下划线颜色 + lineColor: { + type: String, + default: uni.$u.props.link.lineColor + }, + // 超链接的问题,不使用slot形式传入,是因为nvue下无法修改颜色 + text: { + type: String, + default: uni.$u.props.link.text + } + } +} diff --git a/uni_modules/uview-ui/components/u-link/u-link.vue b/uni_modules/uview-ui/components/u-link/u-link.vue new file mode 100644 index 0000000..c6802a5 --- /dev/null +++ b/uni_modules/uview-ui/components/u-link/u-link.vue @@ -0,0 +1,83 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-list-item/props.js b/uni_modules/uview-ui/components/u-list-item/props.js new file mode 100644 index 0000000..58ddc49 --- /dev/null +++ b/uni_modules/uview-ui/components/u-list-item/props.js @@ -0,0 +1,9 @@ +export default { + props: { + // 用于滚动到指定item + anchor: { + type: [String, Number], + default: uni.$u.props.listItem.anchor + } + } +} diff --git a/uni_modules/uview-ui/components/u-list-item/u-list-item.vue b/uni_modules/uview-ui/components/u-list-item/u-list-item.vue new file mode 100644 index 0000000..1a25db6 --- /dev/null +++ b/uni_modules/uview-ui/components/u-list-item/u-list-item.vue @@ -0,0 +1,116 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-list/props.js b/uni_modules/uview-ui/components/u-list/props.js new file mode 100644 index 0000000..25406f4 --- /dev/null +++ b/uni_modules/uview-ui/components/u-list/props.js @@ -0,0 +1,76 @@ +export default { + props: { + // 控制是否出现滚动条,仅nvue有效 + showScrollbar: { + type: Boolean, + default: uni.$u.props.list.showScrollbar + }, + // 距底部多少时触发scrolltolower事件 + lowerThreshold: { + type: [String, Number], + default: uni.$u.props.list.lowerThreshold + }, + // 距顶部多少时触发scrolltoupper事件,非nvue有效 + upperThreshold: { + type: [String, Number], + default: uni.$u.props.list.upperThreshold + }, + // 设置竖向滚动条位置 + scrollTop: { + type: [String, Number], + default: uni.$u.props.list.scrollTop + }, + // 控制 onscroll 事件触发的频率,仅nvue有效 + offsetAccuracy: { + type: [String, Number], + default: uni.$u.props.list.offsetAccuracy + }, + // 启用 flexbox 布局。开启后,当前节点声明了display: flex就会成为flex container,并作用于其孩子节点,仅微信小程序有效 + enableFlex: { + type: Boolean, + default: uni.$u.props.list.enableFlex + }, + // 是否按分页模式显示List,默认值false + pagingEnabled: { + type: Boolean, + default: uni.$u.props.list.pagingEnabled + }, + // 是否允许List滚动 + scrollable: { + type: Boolean, + default: uni.$u.props.list.scrollable + }, + // 值应为某子元素id(id不能以数字开头) + scrollIntoView: { + type: String, + default: uni.$u.props.list.scrollIntoView + }, + // 在设置滚动条位置时使用动画过渡 + scrollWithAnimation: { + type: Boolean, + default: uni.$u.props.list.scrollWithAnimation + }, + // iOS点击顶部状态栏、安卓双击标题栏时,滚动条返回顶部,只对微信小程序有效 + enableBackToTop: { + type: Boolean, + default: uni.$u.props.list.enableBackToTop + }, + // 列表的高度 + height: { + type: [String, Number], + default: uni.$u.props.list.height + }, + // 列表宽度 + width: { + type: [String, Number], + default: uni.$u.props.list.width + }, + // 列表前后预渲染的屏数,1代表一个屏幕的高度,1.5代表1个半屏幕高度 + preLoadScreen: { + type: [String, Number], + default: uni.$u.props.list.preLoadScreen + } + // vue下,是否开启虚拟列表 + + } +} diff --git a/uni_modules/uview-ui/components/u-list/u-list.vue b/uni_modules/uview-ui/components/u-list/u-list.vue new file mode 100644 index 0000000..4447cab --- /dev/null +++ b/uni_modules/uview-ui/components/u-list/u-list.vue @@ -0,0 +1,157 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-loading-icon/props.js b/uni_modules/uview-ui/components/u-loading-icon/props.js new file mode 100644 index 0000000..c35524e --- /dev/null +++ b/uni_modules/uview-ui/components/u-loading-icon/props.js @@ -0,0 +1,59 @@ +export default { + props: { + // 是否显示组件 + show: { + type: Boolean, + default: uni.$u.props.loadingIcon.show + }, + // 颜色 + color: { + type: String, + default: uni.$u.props.loadingIcon.color + }, + // 提示文字颜色 + textColor: { + type: String, + default: uni.$u.props.loadingIcon.textColor + }, + // 文字和图标是否垂直排列 + vertical: { + type: Boolean, + default: uni.$u.props.loadingIcon.vertical + }, + // 模式选择,circle-圆形,spinner-花朵形,semicircle-半圆形 + mode: { + type: String, + default: uni.$u.props.loadingIcon.mode + }, + // 图标大小,单位默认px + size: { + type: [String, Number], + default: uni.$u.props.loadingIcon.size + }, + // 文字大小 + textSize: { + type: [String, Number], + default: uni.$u.props.loadingIcon.textSize + }, + // 文字内容 + text: { + type: [String, Number], + default: uni.$u.props.loadingIcon.text + }, + // 动画模式 + timingFunction: { + type: String, + default: uni.$u.props.loadingIcon.timingFunction + }, + // 动画执行周期时间 + duration: { + type: [String, Number], + default: uni.$u.props.loadingIcon.duration + }, + // mode=circle时的暗边颜色 + inactiveColor: { + type: String, + default: uni.$u.props.loadingIcon.inactiveColor + } + } +} diff --git a/uni_modules/uview-ui/components/u-loading-icon/u-loading-icon.vue b/uni_modules/uview-ui/components/u-loading-icon/u-loading-icon.vue new file mode 100644 index 0000000..2ede5c3 --- /dev/null +++ b/uni_modules/uview-ui/components/u-loading-icon/u-loading-icon.vue @@ -0,0 +1,343 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-loading-page/props.js b/uni_modules/uview-ui/components/u-loading-page/props.js new file mode 100644 index 0000000..e239b61 --- /dev/null +++ b/uni_modules/uview-ui/components/u-loading-page/props.js @@ -0,0 +1,49 @@ +export default { + props: { + // 提示内容 + loadingText: { + type: [String, Number], + default: uni.$u.props.loadingPage.loadingText + }, + // 文字上方用于替换loading动画的图片 + image: { + type: String, + default: uni.$u.props.loadingPage.image + }, + // 加载动画的模式,circle-圆形,spinner-花朵形,semicircle-半圆形 + loadingMode: { + type: String, + default: uni.$u.props.loadingPage.loadingMode + }, + // 是否加载中 + loading: { + type: Boolean, + default: uni.$u.props.loadingPage.loading + }, + // 背景色 + bgColor: { + type: String, + default: uni.$u.props.loadingPage.bgColor + }, + // 文字颜色 + color: { + type: String, + default: uni.$u.props.loadingPage.color + }, + // 文字大小 + fontSize: { + type: [String, Number], + default: uni.$u.props.loadingPage.fontSize + }, + // 图标大小 + iconSize: { + type: [String, Number], + default: uni.$u.props.loadingPage.fontSize + }, + // 加载中图标的颜色,只能rgb或者十六进制颜色值 + loadingColor: { + type: String, + default: uni.$u.props.loadingPage.loadingColor + } + } +} diff --git a/uni_modules/uview-ui/components/u-loading-page/u-loading-page.vue b/uni_modules/uview-ui/components/u-loading-page/u-loading-page.vue new file mode 100644 index 0000000..03a78ad --- /dev/null +++ b/uni_modules/uview-ui/components/u-loading-page/u-loading-page.vue @@ -0,0 +1,115 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-loadmore/props.js b/uni_modules/uview-ui/components/u-loadmore/props.js new file mode 100644 index 0000000..1e67d89 --- /dev/null +++ b/uni_modules/uview-ui/components/u-loadmore/props.js @@ -0,0 +1,94 @@ +export default { + props: { + // 组件状态,loadmore-加载前的状态,loading-加载中的状态,nomore-没有更多的状态 + status: { + type: String, + default: uni.$u.props.loadmore.status + }, + // 组件背景色 + bgColor: { + type: String, + default: uni.$u.props.loadmore.bgColor + }, + // 是否显示加载中的图标 + icon: { + type: Boolean, + default: uni.$u.props.loadmore.icon + }, + // 字体大小 + fontSize: { + type: [String, Number], + default: uni.$u.props.loadmore.fontSize + }, + // 图标大小 + iconSize: { + type: [String, Number], + default: uni.$u.props.loadmore.iconSize + }, + // 字体颜色 + color: { + type: String, + default: uni.$u.props.loadmore.color + }, + // 加载中状态的图标,spinner-花朵状图标,circle-圆圈状,semicircle-半圆 + loadingIcon: { + type: String, + default: uni.$u.props.loadmore.loadingIcon + }, + // 加载前的提示语 + loadmoreText: { + type: String, + default: uni.$u.props.loadmore.loadmoreText + }, + // 加载中提示语 + loadingText: { + type: String, + default: uni.$u.props.loadmore.loadingText + }, + // 没有更多的提示语 + nomoreText: { + type: String, + default: uni.$u.props.loadmore.nomoreText + }, + // 在“没有更多”状态下,是否显示粗点 + isDot: { + type: Boolean, + default: uni.$u.props.loadmore.isDot + }, + // 加载中图标的颜色 + iconColor: { + type: String, + default: uni.$u.props.loadmore.iconColor + }, + // 上边距 + marginTop: { + type: [String, Number], + default: uni.$u.props.loadmore.marginTop + }, + // 下边距 + marginBottom: { + type: [String, Number], + default: uni.$u.props.loadmore.marginBottom + }, + // 高度,单位px + height: { + type: [String, Number], + default: uni.$u.props.loadmore.height + }, + // 是否显示左边分割线 + line: { + type: Boolean, + default: uni.$u.props.loadmore.line + }, + // 线条颜色 + lineColor: { + type: String, + default: uni.$u.props.loadmore.lineColor + }, + // 是否虚线,true-虚线,false-实线 + dashed: { + type: Boolean, + default: uni.$u.props.loadmore.dashed + } + } +} diff --git a/uni_modules/uview-ui/components/u-loadmore/u-loadmore.vue b/uni_modules/uview-ui/components/u-loadmore/u-loadmore.vue new file mode 100644 index 0000000..73c79fe --- /dev/null +++ b/uni_modules/uview-ui/components/u-loadmore/u-loadmore.vue @@ -0,0 +1,150 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-modal/props.js b/uni_modules/uview-ui/components/u-modal/props.js new file mode 100644 index 0000000..f76672c --- /dev/null +++ b/uni_modules/uview-ui/components/u-modal/props.js @@ -0,0 +1,84 @@ +export default { + props: { + // 是否展示modal + show: { + type: Boolean, + default: uni.$u.props.modal.show + }, + // 标题 + title: { + type: [String], + default: uni.$u.props.modal.title + }, + // 弹窗内容 + content: { + type: String, + default: uni.$u.props.modal.content + }, + // 确认文案 + confirmText: { + type: String, + default: uni.$u.props.modal.confirmText + }, + // 取消文案 + cancelText: { + type: String, + default: uni.$u.props.modal.cancelText + }, + // 是否显示确认按钮 + showConfirmButton: { + type: Boolean, + default: uni.$u.props.modal.showConfirmButton + }, + // 是否显示取消按钮 + showCancelButton: { + type: Boolean, + default: uni.$u.props.modal.showCancelButton + }, + // 确认按钮颜色 + confirmColor: { + type: String, + default: uni.$u.props.modal.confirmColor + }, + // 取消文字颜色 + cancelColor: { + type: String, + default: uni.$u.props.modal.cancelColor + }, + // 对调确认和取消的位置 + buttonReverse: { + type: Boolean, + default: uni.$u.props.modal.buttonReverse + }, + // 是否开启缩放效果 + zoom: { + type: Boolean, + default: uni.$u.props.modal.zoom + }, + // 是否异步关闭,只对确定按钮有效 + asyncClose: { + type: Boolean, + default: uni.$u.props.modal.asyncClose + }, + // 是否允许点击遮罩关闭modal + closeOnClickOverlay: { + type: Boolean, + default: uni.$u.props.modal.closeOnClickOverlay + }, + // 给一个负的margin-top,往上偏移,避免和键盘重合的情况 + negativeTop: { + type: [String, Number], + default: uni.$u.props.modal.negativeTop + }, + // modal宽度,不支持百分比,可以数值,px,rpx单位 + width: { + type: [String, Number], + default: uni.$u.props.modal.width + }, + // 确认按钮的样式,circle-圆形,square-方形,如设置,将不会显示取消按钮 + confirmButtonShape: { + type: String, + default: uni.$u.props.modal.confirmButtonShape + } + } +} diff --git a/uni_modules/uview-ui/components/u-modal/u-modal.vue b/uni_modules/uview-ui/components/u-modal/u-modal.vue new file mode 100644 index 0000000..2cbc737 --- /dev/null +++ b/uni_modules/uview-ui/components/u-modal/u-modal.vue @@ -0,0 +1,227 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-navbar/props.js b/uni_modules/uview-ui/components/u-navbar/props.js new file mode 100644 index 0000000..5398de2 --- /dev/null +++ b/uni_modules/uview-ui/components/u-navbar/props.js @@ -0,0 +1,84 @@ +export default { + props: { + // 是否开启顶部安全区适配 + safeAreaInsetTop: { + type: Boolean, + default: uni.$u.props.navbar.safeAreaInsetTop + }, + // 固定在顶部时,是否生成一个等高元素,以防止塌陷 + placeholder: { + type: Boolean, + default: uni.$u.props.navbar.placeholder + }, + // 是否固定在顶部 + fixed: { + type: Boolean, + default: uni.$u.props.navbar.fixed + }, + // 是否显示下边框 + border: { + type: Boolean, + default: uni.$u.props.navbar.border + }, + // 左边的图标 + leftIcon: { + type: String, + default: uni.$u.props.navbar.leftIcon + }, + // 左边的提示文字 + leftText: { + type: String, + default: uni.$u.props.navbar.leftText + }, + // 左右的提示文字 + rightText: { + type: String, + default: uni.$u.props.navbar.rightText + }, + // 右边的图标 + rightIcon: { + type: String, + default: uni.$u.props.navbar.rightIcon + }, + // 标题 + title: { + type: [String, Number], + default: uni.$u.props.navbar.title + }, + // 背景颜色 + bgColor: { + type: String, + default: uni.$u.props.navbar.bgColor + }, + // 标题的宽度 + titleWidth: { + type: [String, Number], + default: uni.$u.props.navbar.titleWidth + }, + // 导航栏高度 + height: { + type: [String, Number], + default: uni.$u.props.navbar.height + }, + // 左侧返回图标的大小 + leftIconSize: { + type: [String, Number], + default: uni.$u.props.navbar.leftIconSize + }, + // 左侧返回图标的颜色 + leftIconColor: { + type: String, + default: uni.$u.props.navbar.leftIconColor + }, + // 点击左侧区域(返回图标),是否自动返回上一页 + autoBack: { + type: Boolean, + default: uni.$u.props.navbar.autoBack + }, + // 标题的样式,对象或字符串 + titleStyle: { + type: [String, Object], + default: uni.$u.props.navbar.titleStyle + } + } +} diff --git a/uni_modules/uview-ui/components/u-navbar/u-navbar.vue b/uni_modules/uview-ui/components/u-navbar/u-navbar.vue new file mode 100644 index 0000000..2b206b7 --- /dev/null +++ b/uni_modules/uview-ui/components/u-navbar/u-navbar.vue @@ -0,0 +1,186 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-no-network/props.js b/uni_modules/uview-ui/components/u-no-network/props.js new file mode 100644 index 0000000..9f3af62 --- /dev/null +++ b/uni_modules/uview-ui/components/u-no-network/props.js @@ -0,0 +1,19 @@ +export default { + props: { + // 页面文字提示 + tips: { + type: String, + default: uni.$u.props.noNetwork.tips + }, + // 一个z-index值,用于设置没有网络这个组件的层次,因为页面可能会有其他定位的元素层级过高,导致此组件被覆盖 + zIndex: { + type: [String, Number], + default: uni.$u.props.noNetwork.zIndex + }, + // image 没有网络的图片提示 + image: { + type: String, + default: uni.$u.props.noNetwork.image + } + } +} diff --git a/uni_modules/uview-ui/components/u-no-network/u-no-network.vue b/uni_modules/uview-ui/components/u-no-network/u-no-network.vue new file mode 100644 index 0000000..9710729 --- /dev/null +++ b/uni_modules/uview-ui/components/u-no-network/u-no-network.vue @@ -0,0 +1,220 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-notice-bar/props.js b/uni_modules/uview-ui/components/u-notice-bar/props.js new file mode 100644 index 0000000..7040c29 --- /dev/null +++ b/uni_modules/uview-ui/components/u-notice-bar/props.js @@ -0,0 +1,70 @@ +export default { + props: { + // 显示的内容,数组 + text: { + type: [Array, String], + default: uni.$u.props.noticeBar.text + }, + // 通告滚动模式,row-横向滚动,column-竖向滚动 + direction: { + type: String, + default: uni.$u.props.noticeBar.direction + }, + // direction = row时,是否使用步进形式滚动 + step: { + type: Boolean, + default: uni.$u.props.noticeBar.step + }, + // 是否显示左侧的音量图标 + icon: { + type: String, + default: uni.$u.props.noticeBar.icon + }, + // 通告模式,link-显示右箭头,closable-显示右侧关闭图标 + mode: { + type: String, + default: uni.$u.props.noticeBar.mode + }, + // 文字颜色,各图标也会使用文字颜色 + color: { + type: String, + default: uni.$u.props.noticeBar.color + }, + // 背景颜色 + bgColor: { + type: String, + default: uni.$u.props.noticeBar.bgColor + }, + // 水平滚动时的滚动速度,即每秒滚动多少px(px),这有利于控制文字无论多少时,都能有一个恒定的速度 + speed: { + type: [String, Number], + default: uni.$u.props.noticeBar.speed + }, + // 字体大小 + fontSize: { + type: [String, Number], + default: uni.$u.props.noticeBar.fontSize + }, + // 滚动一个周期的时间长,单位ms + duration: { + type: [String, Number], + default: uni.$u.props.noticeBar.duration + }, + // 是否禁止用手滑动切换 + // 目前HX2.6.11,只支持App 2.5.5+、H5 2.5.5+、支付宝小程序、字节跳动小程序 + disableTouch: { + type: Boolean, + default: uni.$u.props.noticeBar.disableTouch + }, + // 跳转的页面路径 + url: { + type: String, + default: uni.$u.props.noticeBar.url + }, + // 页面跳转的类型 + linkType: { + type: String, + default: uni.$u.props.noticeBar.linkType + } + } +} diff --git a/uni_modules/uview-ui/components/u-notice-bar/u-notice-bar.vue b/uni_modules/uview-ui/components/u-notice-bar/u-notice-bar.vue new file mode 100644 index 0000000..a06eb39 --- /dev/null +++ b/uni_modules/uview-ui/components/u-notice-bar/u-notice-bar.vue @@ -0,0 +1,101 @@ + + + + diff --git a/uni_modules/uview-ui/components/u-notify/props.js b/uni_modules/uview-ui/components/u-notify/props.js new file mode 100644 index 0000000..57a9d71 --- /dev/null +++ b/uni_modules/uview-ui/components/u-notify/props.js @@ -0,0 +1,49 @@ +export default { + props: { + // 到顶部的距离 + top: { + type: [String, Number], + default: uni.$u.props.notify.top + }, + // 是否展示组件 + // show: { + // type: Boolean, + // default: uni.$u.props.notify.show + // }, + // type主题,primary,success,warning,error + type: { + type: String, + default: uni.$u.props.notify.type + }, + // 字体颜色 + color: { + type: String, + default: uni.$u.props.notify.color + }, + // 背景颜色 + bgColor: { + type: String, + default: uni.$u.props.notify.bgColor + }, + // 展示的文字内容 + message: { + type: String, + default: uni.$u.props.notify.message + }, + // 展示时长,为0时不消失,单位ms + duration: { + type: [String, Number], + default: uni.$u.props.notify.duration + }, + // 字体大小 + fontSize: { + type: [String, Number], + default: uni.$u.props.notify.fontSize + }, + // 是否留出顶部安全距离(状态栏高度) + safeAreaInsetTop: { + type: Boolean, + default: uni.$u.props.notify.safeAreaInsetTop + } + } +} diff --git a/uni_modules/uview-ui/components/u-notify/u-notify.vue b/uni_modules/uview-ui/components/u-notify/u-notify.vue new file mode 100644 index 0000000..30adb72 --- /dev/null +++ b/uni_modules/uview-ui/components/u-notify/u-notify.vue @@ -0,0 +1,211 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-number-box/props.js b/uni_modules/uview-ui/components/u-number-box/props.js new file mode 100644 index 0000000..fb0fa94 --- /dev/null +++ b/uni_modules/uview-ui/components/u-number-box/props.js @@ -0,0 +1,109 @@ +export default { + props: { + // 步进器标识符,在change回调返回 + name: { + type: [String, Number], + default: uni.$u.props.numberBox.name + }, + // 用于双向绑定的值,初始化时设置设为默认min值(最小值) + value: { + type: [String, Number], + default: uni.$u.props.numberBox.value + }, + // 最小值 + min: { + type: [String, Number], + default: uni.$u.props.numberBox.min + }, + // 最大值 + max: { + type: [String, Number], + default: uni.$u.props.numberBox.max + }, + // 加减的步长,可为小数 + step: { + type: [String, Number], + default: uni.$u.props.numberBox.step + }, + // 是否只允许输入整数 + integer: { + type: Boolean, + default: uni.$u.props.numberBox.integer + }, + // 是否禁用,包括输入框,加减按钮 + disabled: { + type: Boolean, + default: uni.$u.props.numberBox.disabled + }, + // 是否禁用输入框 + disabledInput: { + type: Boolean, + default: uni.$u.props.numberBox.disabledInput + }, + // 是否开启异步变更,开启后需要手动控制输入值 + asyncChange: { + type: Boolean, + default: uni.$u.props.numberBox.asyncChange + }, + // 输入框宽度,单位为px + inputWidth: { + type: [String, Number], + default: uni.$u.props.numberBox.inputWidth + }, + // 是否显示减少按钮 + showMinus: { + type: Boolean, + default: uni.$u.props.numberBox.showMinus + }, + // 是否显示增加按钮 + showPlus: { + type: Boolean, + default: uni.$u.props.numberBox.showPlus + }, + // 显示的小数位数 + decimalLength: { + type: [String, Number, null], + default: uni.$u.props.numberBox.decimalLength + }, + // 是否开启长按加减手势 + longPress: { + type: Boolean, + default: uni.$u.props.numberBox.longPress + }, + // 输入框文字和加减按钮图标的颜色 + color: { + type: String, + default: uni.$u.props.numberBox.color + }, + // 按钮大小,宽高等于此值,单位px,输入框高度和此值保持一致 + buttonSize: { + type: [String, Number], + default: uni.$u.props.numberBox.buttonSize + }, + // 输入框和按钮的背景颜色 + bgColor: { + type: String, + default: uni.$u.props.numberBox.bgColor + }, + // 指定光标于键盘的距离,避免键盘遮挡输入框,单位px + cursorSpacing: { + type: [String, Number], + default: uni.$u.props.numberBox.cursorSpacing + }, + // 是否禁用增加按钮 + disablePlus: { + type: Boolean, + default: uni.$u.props.numberBox.disablePlus + }, + // 是否禁用减少按钮 + disableMinus: { + type: Boolean, + default: uni.$u.props.numberBox.disableMinus + }, + // 加减按钮图标的样式 + iconStyle: { + type: [Object, String], + default: uni.$u.props.numberBox.iconStyle + } + } +} diff --git a/uni_modules/uview-ui/components/u-number-box/u-number-box.vue b/uni_modules/uview-ui/components/u-number-box/u-number-box.vue new file mode 100644 index 0000000..69211c5 --- /dev/null +++ b/uni_modules/uview-ui/components/u-number-box/u-number-box.vue @@ -0,0 +1,416 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-number-keyboard/props.js b/uni_modules/uview-ui/components/u-number-keyboard/props.js new file mode 100644 index 0000000..5e3bf55 --- /dev/null +++ b/uni_modules/uview-ui/components/u-number-keyboard/props.js @@ -0,0 +1,19 @@ +export default { + props: { + // 键盘的类型,number-数字键盘,card-身份证键盘 + mode: { + type: String, + default: uni.$u.props.numberKeyboard.value + }, + // 是否显示键盘的"."符号 + dotDisabled: { + type: Boolean, + default: uni.$u.props.numberKeyboard.dotDisabled + }, + // 是否打乱键盘按键的顺序 + random: { + type: Boolean, + default: uni.$u.props.numberKeyboard.random + } + } +} diff --git a/uni_modules/uview-ui/components/u-number-keyboard/u-number-keyboard.vue b/uni_modules/uview-ui/components/u-number-keyboard/u-number-keyboard.vue new file mode 100644 index 0000000..4f505c6 --- /dev/null +++ b/uni_modules/uview-ui/components/u-number-keyboard/u-number-keyboard.vue @@ -0,0 +1,196 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-overlay/props.js b/uni_modules/uview-ui/components/u-overlay/props.js new file mode 100644 index 0000000..e6974df --- /dev/null +++ b/uni_modules/uview-ui/components/u-overlay/props.js @@ -0,0 +1,24 @@ +export default { + props: { + // 是否显示遮罩 + show: { + type: Boolean, + default: uni.$u.props.overlay.show + }, + // 层级z-index + zIndex: { + type: [String, Number], + default: uni.$u.props.overlay.zIndex + }, + // 遮罩的过渡时间,单位为ms + duration: { + type: [String, Number], + default: uni.$u.props.overlay.duration + }, + // 不透明度值,当做rgba的第四个参数 + opacity: { + type: [String, Number], + default: uni.$u.props.overlay.opacity + } + } +} diff --git a/uni_modules/uview-ui/components/u-overlay/u-overlay.vue b/uni_modules/uview-ui/components/u-overlay/u-overlay.vue new file mode 100644 index 0000000..92de4e9 --- /dev/null +++ b/uni_modules/uview-ui/components/u-overlay/u-overlay.vue @@ -0,0 +1,68 @@ + + + + + diff --git a/uni_modules/uview-ui/components/u-parse/node/node.vue b/uni_modules/uview-ui/components/u-parse/node/node.vue new file mode 100644 index 0000000..73e30fd --- /dev/null +++ b/uni_modules/uview-ui/components/u-parse/node/node.vue @@ -0,0 +1,499 @@ +