mabaoyi 8 meses atrás
pai
commit
a85dc648e2
100 arquivos alterados com 6811 adições e 56 exclusões
  1. 4 2
      commont/messages.js
  2. 1 1
      manifest.json
  3. 1 1
      pageA/counter.vue
  4. 11 4
      pageA/payorder.vue
  5. 155 37
      pageA/productdetails.vue
  6. 3 1
      pageB/delivery.vue
  7. 14 2
      pages/express/express.vue
  8. 223 0
      uni_modules/lime-painter/changelog.md
  9. 150 0
      uni_modules/lime-painter/components/common/relation.js
  10. 28 0
      uni_modules/lime-painter/components/l-painter-image/l-painter-image.vue
  11. 27 0
      uni_modules/lime-painter/components/l-painter-qrcode/l-painter-qrcode.vue
  12. 33 0
      uni_modules/lime-painter/components/l-painter-text/l-painter-text.vue
  13. 34 0
      uni_modules/lime-painter/components/l-painter-view/l-painter-view.vue
  14. 461 0
      uni_modules/lime-painter/components/l-painter/l-painter.vue
  15. 214 0
      uni_modules/lime-painter/components/l-painter/nvue.js
  16. 0 0
      uni_modules/lime-painter/components/l-painter/painter.js
  17. 56 0
      uni_modules/lime-painter/components/l-painter/props.js
  18. 0 0
      uni_modules/lime-painter/components/l-painter/single.js
  19. 368 0
      uni_modules/lime-painter/components/l-painter/utils.js
  20. 166 0
      uni_modules/lime-painter/components/lime-painter/lime-painter.vue
  21. 119 0
      uni_modules/lime-painter/hybrid/html/index.html
  22. 0 0
      uni_modules/lime-painter/hybrid/html/painter.js
  23. 0 0
      uni_modules/lime-painter/hybrid/html/uni.webview.1.5.3.js
  24. 92 0
      uni_modules/lime-painter/package.json
  25. 388 0
      uni_modules/lime-painter/parser.js
  26. 963 0
      uni_modules/lime-painter/readme.md
  27. 18 0
      uni_modules/mu-canvas/changelog.md
  28. 7 0
      uni_modules/mu-canvas/components/mu-canvas/mu-canvas.vue
  29. 241 0
      uni_modules/mu-canvas/js_sdk/gcanvas/bridge/bridge-weex.js
  30. 18 0
      uni_modules/mu-canvas/js_sdk/gcanvas/context-2d/FillStyleLinearGradient.js
  31. 8 0
      uni_modules/mu-canvas/js_sdk/gcanvas/context-2d/FillStylePattern.js
  32. 17 0
      uni_modules/mu-canvas/js_sdk/gcanvas/context-2d/FillStyleRadialGradient.js
  33. 666 0
      uni_modules/mu-canvas/js_sdk/gcanvas/context-2d/RenderingContext.js
  34. 11 0
      uni_modules/mu-canvas/js_sdk/gcanvas/context-webgl/ActiveInfo.js
  35. 21 0
      uni_modules/mu-canvas/js_sdk/gcanvas/context-webgl/Buffer.js
  36. 21 0
      uni_modules/mu-canvas/js_sdk/gcanvas/context-webgl/Framebuffer.js
  37. 298 0
      uni_modules/mu-canvas/js_sdk/gcanvas/context-webgl/GLenum.js
  38. 142 0
      uni_modules/mu-canvas/js_sdk/gcanvas/context-webgl/GLmethod.js
  39. 23 0
      uni_modules/mu-canvas/js_sdk/gcanvas/context-webgl/GLtype.js
  40. 21 0
      uni_modules/mu-canvas/js_sdk/gcanvas/context-webgl/Program.js
  41. 21 0
      uni_modules/mu-canvas/js_sdk/gcanvas/context-webgl/Renderbuffer.js
  42. 1191 0
      uni_modules/mu-canvas/js_sdk/gcanvas/context-webgl/RenderingContext.js
  43. 22 0
      uni_modules/mu-canvas/js_sdk/gcanvas/context-webgl/Shader.js
  44. 11 0
      uni_modules/mu-canvas/js_sdk/gcanvas/context-webgl/ShaderPrecisionFormat.js
  45. 22 0
      uni_modules/mu-canvas/js_sdk/gcanvas/context-webgl/Texture.js
  46. 22 0
      uni_modules/mu-canvas/js_sdk/gcanvas/context-webgl/UniformLocation.js
  47. 3 0
      uni_modules/mu-canvas/js_sdk/gcanvas/context-webgl/classUtils.js
  48. 74 0
      uni_modules/mu-canvas/js_sdk/gcanvas/env/canvas.js
  49. 96 0
      uni_modules/mu-canvas/js_sdk/gcanvas/env/image.js
  50. 24 0
      uni_modules/mu-canvas/js_sdk/gcanvas/env/tool.js
  51. 39 0
      uni_modules/mu-canvas/js_sdk/gcanvas/index.js
  52. 33 0
      uni_modules/mu-canvas/js_sdk/uqrcode/uqrcode.js
  53. 81 0
      uni_modules/mu-canvas/package.json
  54. 137 0
      uni_modules/mu-canvas/readme.md
  55. 0 0
      unpackage/dist/build/mp-weixin/common/main.js
  56. 0 0
      unpackage/dist/build/mp-weixin/common/runtime.js
  57. 0 0
      unpackage/dist/build/mp-weixin/common/vendor.js
  58. 0 0
      unpackage/dist/build/mp-weixin/components/kj-flow/kj-flow.js
  59. 0 0
      unpackage/dist/build/mp-weixin/components/kj-tabbar/kj-tabbar.js
  60. 0 0
      unpackage/dist/build/mp-weixin/components/zh-slidingMenu/zhSlidingMenu/zhSlidingMenu.js
  61. 1 1
      unpackage/dist/build/mp-weixin/pageA/balance.js
  62. 0 0
      unpackage/dist/build/mp-weixin/pageA/changelange.js
  63. 0 0
      unpackage/dist/build/mp-weixin/pageA/chat/chat.js
  64. 0 0
      unpackage/dist/build/mp-weixin/pageA/chat/chat.wxml
  65. 0 0
      unpackage/dist/build/mp-weixin/pageA/chat/news.js
  66. 0 0
      unpackage/dist/build/mp-weixin/pageA/chat/news.wxml
  67. 0 0
      unpackage/dist/build/mp-weixin/pageA/comment.js
  68. 1 1
      unpackage/dist/build/mp-weixin/pageA/confirm.js
  69. 0 0
      unpackage/dist/build/mp-weixin/pageA/counter.js
  70. 0 0
      unpackage/dist/build/mp-weixin/pageA/counter.wxml
  71. 1 1
      unpackage/dist/build/mp-weixin/pageA/index.js
  72. 0 0
      unpackage/dist/build/mp-weixin/pageA/logisticsinfo.js
  73. 0 0
      unpackage/dist/build/mp-weixin/pageA/order.js
  74. 0 0
      unpackage/dist/build/mp-weixin/pageA/order.wxml
  75. 0 0
      unpackage/dist/build/mp-weixin/pageA/payorder.js
  76. 0 0
      unpackage/dist/build/mp-weixin/pageA/payorder.wxml
  77. 5 1
      unpackage/dist/build/mp-weixin/pageA/payorder.wxss
  78. 0 0
      unpackage/dist/build/mp-weixin/pageA/productdetails.js
  79. 0 0
      unpackage/dist/build/mp-weixin/pageA/rule/rule.js
  80. 1 1
      unpackage/dist/build/mp-weixin/pageA/service/service.js
  81. 0 0
      unpackage/dist/build/mp-weixin/pageA/shoplist.js
  82. 0 0
      unpackage/dist/build/mp-weixin/pageA/shoplist.wxml
  83. 0 0
      unpackage/dist/build/mp-weixin/pageA/shoptype.js
  84. 0 0
      unpackage/dist/build/mp-weixin/pageA/subsidy.js
  85. 0 0
      unpackage/dist/build/mp-weixin/pageA/subsidy.wxml
  86. 0 0
      unpackage/dist/build/mp-weixin/pageB/ParcelExpress.js
  87. 0 0
      unpackage/dist/build/mp-weixin/pageB/ParcelExpress.wxml
  88. 1 1
      unpackage/dist/build/mp-weixin/pageB/Senderinfor.js
  89. 1 1
      unpackage/dist/build/mp-weixin/pageB/Senderinfor.wxml
  90. 0 0
      unpackage/dist/build/mp-weixin/pageB/account.js
  91. 0 0
      unpackage/dist/build/mp-weixin/pageB/account.wxml
  92. 0 0
      unpackage/dist/build/mp-weixin/pageB/citychange.js
  93. 0 0
      unpackage/dist/build/mp-weixin/pageB/delivery.js
  94. 0 0
      unpackage/dist/build/mp-weixin/pageB/delivery.wxml
  95. 0 0
      unpackage/dist/build/mp-weixin/pageB/end.js
  96. 0 0
      unpackage/dist/build/mp-weixin/pageB/end.wxml
  97. 0 0
      unpackage/dist/build/mp-weixin/pageB/expresstype.js
  98. 0 0
      unpackage/dist/build/mp-weixin/pageB/goods.js
  99. 0 0
      unpackage/dist/build/mp-weixin/pageB/goods.wxml
  100. 1 1
      unpackage/dist/build/mp-weixin/pageB/index.js

+ 4 - 2
commont/messages.js

@@ -293,14 +293,16 @@ export default {
 
 			Please: '请输入物品名称',
 			Filling: '填写准确的寄送物品可帮助您推荐更合适的产品',
-			Note: '注:实际重量体积以收派员确定为准,物品在包装后重量可能会增加,重量小体积大时会按体积重量收费'
+			Note: '注:实际重量体积以收派员确定为准,物品在包装后重量可能会增加,重量小体积大时会按体积重量收费',
+			
+			window:'请点击右上角浮窗进行复制'
 		},
 	},
 	//英语
 	"en-US": {
 		index: {
 			homepage: "Homepage",
-			switchLanguage: "Switch Language",
+			switchLanguage: "Switch Language",  
 			address: "Address Management",
 			addAndEdit: "add/modify Address",
 			account: "Account and Security",

+ 1 - 1
manifest.json

@@ -1,6 +1,6 @@
 {
     "name" : "kjds",
-    "appid" : "__UNI__F715804",
+    "appid" : "__UNI__AF78173",
     "description" : "",
     "versionName" : "1.0.0",
     "versionCode" : "100",

+ 1 - 1
pageA/counter.vue

@@ -237,7 +237,7 @@ color: rgba(34, 34, 34, 0.5);">{{i18n.accurately}}</text>
 			//物流详情
 			logistics() {
 				uni.navigateTo({
-					url: '/pageA/logisticsinfo?weight=' + this.value + '$money=' + this.money
+					url: '/pageA/logisticsinfo?weight=' + this.value + '&money=' + this.money
 				})
 			},
 			//获取价格

+ 11 - 4
pageA/payorder.vue

@@ -407,9 +407,9 @@ export default {
                   this.$u.toast(this.i18n.Paymentsuccess);
                   console.log("success:" + JSON.stringify(res));
                   setTimeout(() => {
-                    uni.navigateTo({
-                      url: "confirm",
-                    });
+              			uni.navigateTo({
+										url: "/pageA/confirm",
+									});
                   }, 800);
                 },
                 fail: function (err) {
@@ -424,7 +424,14 @@ export default {
                 // 	console.log(error);
                 // },
               });
-            }
+            }else{
+								this.$u.toast(this.i18n.Paymentsuccess)
+								setTimeout(() => {
+									uni.navigateTo({
+										url: "/pageA/confirm",
+									});
+								}, 800);
+							}
 
             uni.showToast({
               title: "支付成功",

+ 155 - 37
pageA/productdetails.vue

@@ -170,7 +170,8 @@
 							<swiper-item v-for="(parent, index) in swiptlist" :key="index">
 								<view class="u-flex swiper-item u-row-between">
 									<view class="" v-for="(child, idx) in parent" @click="detail(child.id)" :key="idx">
-										<image :src="child.image" style="width: 214rpx; height: 214rpx;border-radius: 10rpx;" mode="">
+										<image :src="child.image"
+											style="width: 214rpx; height: 214rpx;border-radius: 10rpx;" mode="">
 										</image>
 										<view class="over" style="
                         width: 214rpx;
@@ -279,7 +280,8 @@
 					<view class="" style="margin-left: 20rpx">
 						<view class="">
 							<text class="read">¥</text>
-							<text class="read" style="font-size: 40rpx;font-weight: 600;" v-if="goodinfo.is_discount == 0">{{
+							<text class="read" style="font-size: 40rpx;font-weight: 600;"
+								v-if="goodinfo.is_discount == 0">{{
                   (Number(sku_info.discount_price * 100) *
                     Number(value * 100)) /
                     10000 ||
@@ -288,7 +290,8 @@
                     10000
                 }}</text>
 							<!-- <text class="read" v-if="goodinfo.is_discount==0">{{(goodinfo.discount_price * value).slice(-3)}}</text> -->
-							<text class="read" style="font-size: 40rpx;font-weight: 600;" v-if="goodinfo.is_discount == 1">{{
+							<text class="read" style="font-size: 40rpx;font-weight: 600;"
+								v-if="goodinfo.is_discount == 1">{{
                   (Number(sku_info.price * 100) * Number(value * 100)) /
                     10000 ||
                   (Number(goodinfo.price * 100) * Number(value * 100)) / 10000
@@ -382,7 +385,7 @@
 					
 				</view> -->
 				<view class="u-flex u-row-between" style="margin-top: 82rpx; padding: 0 140rpx">
-					<view class="">
+					<view class="" @click="copylink">
 						<image src="../static/images/index/link.png" style="width: 108rpx; height: 108rpx" mode="">
 						</image>
 						<view class="link">{{ i18n.Copylink }}</view>
@@ -398,40 +401,28 @@
 				</view>
 			</view>
 		</u-popup>
+
 		<u-popup :show="imagea" bgColor=" rgba(244, 244, 244, 0);" mode="center"
 			:customStyle="{ alignItems: 'center' }">
 			<view class="u-fle" style="display: flex; justify-content: flex-end; width: 100%">
-				<u-icon name="close" @click="imagea == false" color="#fff" size="28"></u-icon>
-			</view>
-			<view style="
-          padding: 48rpx 24rpx;
-          box-sizing: border-box;
-          background-color: rgba(255, 255, 255, 1);
-          border-radius: 16rpx;
-          width: 538rpx;
-        ">
-				<view class="" style="">
-					<image src="../static/images/index/bottom2.png" style="width: 490rpx; height: 490rpx"></image>
-				</view>
-				<view class="money">
-					<span>¥</span>
-					<span style="font-size: 36rpx">258</span>
-					<span>00</span>
-				</view>
-				<view class="title">布兰德低温烘焙猫粮全价通用高端鲜肉成猫幼</view>
-				<view class="" style="
-            display: flex;
-            flex-direction: column;
-            align-items: center;
-            justify-content: center;
-            margin-top: 44rpx;
-          ">
-					<image src="../static/images/logo.png" style="width: 132rpx; height: 132rpx" mode=""></image>
-					<view class="view">长按识别查看</view>
-				</view>
+				<u-icon name="close" @click="imagea = false" color="#fff" size="28"></u-icon>
 			</view>
-			<view class="button" style="width: 658rpx">保存到相册</view>
+			<image :src="picture2" mode="widthFix"></image>
+			<view class="button" style="width: 658rpx" @click="saveImage">保存到相册</view>
 		</u-popup>
+		<l-painter custom-style="position: fixed; left: 200%" ref="poster"
+			css="width: 538rpx; height:900rpx; background: #fff;padding:24rpx">
+			<l-painter-image
+				src="https://m.360buyimg.com/babel/jfs/t1/196317/32/13733/288158/60f4ea39E6fb378ed/d69205b1a8ed3c97.jpg"
+				css="width: 490rpx; height: 490rpx" />
+			<l-painter-text text="¥" css=" padding-top: 20rpx;color:#F83224;" />
+			<l-painter-text :text="goodinfoyuan"
+				css="text-align:center; padding-top: 20rpx;color:#F83224; font-size: 26rpx" />
+			<l-painter-text :text="goodinfoname" css=" padding-top: 20rpx;" />
+			<l-painter-qrcode text="limeui.qcoon.cn"
+				css="width: 132rpx; height: 132rpx;margin-top:44rpx;margin-left:174rpx" />
+			<l-painter-text text="长按识别查看" css=" padding-top: 20rpx;text-align:center;display:block;color:#777777" />
+		</l-painter>
 	</view>
 </template>
 
@@ -439,6 +430,74 @@
 	export default {
 		data() {
 			return {
+				elementList: {
+					// images: [ //图片对象
+					// 	{
+					// 		path: "https://img2.baidu.com/it/u=1028011339,1319212411&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=313", //图片路径[必填]
+					// 		dx: 15, //左上角x轴[必填]
+					// 		dy: 15, //左上角y轴[必填]
+					// 		dWidth: 270, //宽度[必填]
+					// 		dHeight: 270, //高度[必填]
+					// 		sx: 0, //绘画的宽度[选填]
+					// 		sy: 0, //绘画的高度[选填]
+					// 	}
+					// ],
+					images: [ //图片对象
+						{
+							path: "https://wxls-cms.oss-cn-hangzhou.aliyuncs.com/online/2024-04-18/218da022-f4bf-456a-99af-5cb8e157f7b8.jpg", //图片路径[必填]
+							dx: 15, //左上角x轴[必填]
+							dy: 15, //左上角y轴[必填]
+							dWidth: 270, //宽度[必填]
+							dHeight: 270, //高度[必填]
+							sx: 0, //绘画的宽度[选填]
+							sy: 0, //绘画的高度[选填]
+						}
+					],
+					text: [ //渲染文字
+						{
+							value: "邀请码:", //渲染的文字
+							color: "#333333", //文字颜色[选填]
+							size: "18", //大小[选填]
+							font: "PingFang SC-Regular, PingFang SC;", //字体[选填]
+							x: 13, //左上角x轴[必填]
+							y: 330, //左上角y轴[必填]
+							// backgroundColor: "#ffffff", //背景色
+							maxWidth: "270", //字体最大宽度
+							maxHeight: "", //字体最大高度
+						}, {
+							value: "邀请码:", //渲染的文字
+							color: "#F83224", //文字颜色[选填]
+							size: "18", //大小[选填]
+							font: "PingFang SC-Regular, PingFang SC;", //字体[选填]
+							x: 13, //左上角x轴[必填]
+							y: 310, //左上角y轴[必填]
+							// backgroundColor: "#ffffff", //背景色
+							maxWidth: "", //字体最大宽度
+							maxHeight: "", //字体最大高度
+						}, {
+							value: "长按识别查看", //渲染的文字
+							color: "#777777", //文字颜色[选填]
+							size: "10", //大小[选填]
+							font: "PingFang SC-Regular, PingFang SC;", //字体[选填]
+							x: 13, //左上角x轴[必填]
+							y: 480, //左上角y轴[必填]
+							// backgroundColor: "#ffffff", //背景色
+							maxWidth: "", //字体最大宽度
+							maxHeight: "", //字体最大高度
+						}
+					],
+					qr: [ //渲染的二维码
+						{
+							url: "limeui.qcoon.cn", //二维码文字[必填]
+							dx: 100, //左上角x轴[必填]
+							dy: 380, //左上角y轴[必填]
+							size: 71, //二维码大小
+							color: "#333333", //二维码前景色
+							backgroundColor: "#ffffff" //二维码背景色
+						}
+					]
+
+				},
 				toView: "",
 				imagea: false,
 				list1: [{
@@ -451,6 +510,8 @@
 						name: "详情",
 					},
 				],
+				goodinfoname: '',
+				goodinfoyuan: '',
 				current: 0,
 				// 购物车
 				show: false,
@@ -474,11 +535,13 @@
 				total: "",
 				rate: 5,
 				content: {},
-				bao: ''
+				bao: '',
+				picture2: ''
 			};
 		},
 		computed: {
 			i18n() {
+
 				return this.$t("index");
 			},
 		},
@@ -494,19 +557,67 @@
 			this.recommend();
 			this.guarantee()
 		},
+		mounted() {
+			this.$refs.poster.canvasToTempFilePathSync({
+				fileType: 'jpg',
+				quality: 1,
+				success: (res) => {
+					console.log(`mounted`, res.tempFilePath)
+					this.picture2 = res.tempFilePath
+					console.log('picture2', this.picture2);
+				}
+			})
+		},
 		methods: {
-			openfu(){
+			//保存到手机相册
+			saveImage() {
+				var that = this
+				console.log('this.picture2.slice,-1)',this.picture2.slice(23));
+				var fileManager = uni.getFileSystemManager();
+				fileManager.writeFile({
+					filePath: wx.env.USER_DATA_PATH + '/img.jpg', // 指定图片的临时路径
+					data:this.picture2.slice(23), // 要写入的文本或二进制数据
+					encoding: 'base64', // 指定写入文件的字符编码
+					success: res => {
+						console.log('写入文件成功', res)
+						console.log(wx.env.USER_DATA_PATH + '/img.jpg')
+						uni.saveImageToPhotosAlbum({ // 保存图片到相册
+							filePath: wx.env.USER_DATA_PATH + '/img.jpg',
+							success: function(res) { 
+								uni.showToast({
+									title: '保存成功'
+								})
+								that.imagea = false
+							},
+							fail: function(err) {
+								console.log('保存失败', err)
+								that.imagea = false
+							},
+							
+						})
+					},
+					file: err => {
+						console.log('写入文件失败', err)
+					}
+				})
+			},
+			// 将页面转换成图片的方法
+			copylink() {
+				this.$u.toast(this.i18n.window)
+			},
+			openfu() {
 				this.serve = true
 			},
 			returnindex() {
 				uni.switchTab({
-					url:'/pages/index/index'
+					url: '/pages/index/index'
 				})
 			},
 			chat() {
 				uni.navigateTo({
 					url: '/pageA/chat/chat?user_other=' + encodeURIComponent(JSON.stringify(this.goodinfo
-						.merchant)) + '&user_other_no=' + this.goodinfo.merchant.member.easemob_username
+							.merchant)) + '&user_other_no=' + this.goodinfo.merchant.member
+						.easemob_username
 				})
 			},
 			sharea() {
@@ -610,6 +721,13 @@
 					.then((res) => {
 						console.log(res);
 						this.goodinfo = res;
+						this.goodinfoname = this.goodinfo.name_cn
+						this.goodinfoyuan = this.goodinfo.is_discount == 0 ?
+							this.goodinfo.discount_price :
+							this.goodinfo.price
+
+
+
 						console.log('goodinfo.discount_price', this.goodinfo.discount_price);
 						this.comment();
 						this.rate = res.merchant.score;

+ 3 - 1
pageB/delivery.vue

@@ -402,7 +402,7 @@
 		}
 
 		.mast {
-			width: 62rpx;
+			// width: 62rpx;
 			height: 30rpx;
 			border-radius: 16rpx;
 			border: 1rpx solid #F83224;
@@ -414,6 +414,8 @@
 			text-align: center;
 			font-style: normal;
 			margin-left: 12rpx;
+			padding: 4rpx 10rpx;
+			box-sizing: border-box;
 		}
 	}
 

+ 14 - 2
pages/express/express.vue

@@ -112,10 +112,10 @@
 					</view>
 				</view>
 				<view class="bottom u-flex u-row-between">
-					<view class="u-flex">
+					<button style="background-color: transparent;padding-left: 0 !important;padding-right: 0 !important;margin: 0 !important;" open-type="share" class="u-flex" >
 						<image src="../../static/express/share.png" style="width: 36rpx;height: 36rpx;" mode=""></image>
 						<text class="friend">{{i18n.share}}</text>
-					</view>
+					</button>
 					<view class="friend">|</view>
 					<view class="u-flex" @click="counter">
 						<image src="/static/images/index/compile.png" style="width: 36rpx;height: 36rpx;" mode="">
@@ -285,6 +285,15 @@
 			}
 		},
 		methods: {
+			onShareAppMessage(res) {
+				if (res.from === 'button') { // 来自页面内分享按钮
+					console.log(res.target)
+				}
+				return {
+					title: this.i18n.border,
+					path: '/pages/express/express'
+				}
+			},
 			callphone() {
 				uni.$u.http.get('/api/config', {
 					params: {
@@ -503,6 +512,9 @@
 </script>
 
 <style lang="scss" scoped>
+	button{
+		border:0rpx solid rgba(0, 0, 0, 1) !important;
+	}
 	page {
 		background-color: rgba(0, 0, 0, 0)
 	}

+ 223 - 0
uni_modules/lime-painter/changelog.md

@@ -0,0 +1,223 @@
+## 1.9.6.5(2024-04-14)
+- fix: 修复`nvue`无法生图的问题
+## 1.9.6.4(2024-03-10)
+- fix: 修复代理ctx导致H5不能使用ctx.save
+## 1.9.6.3(2024-03-08)
+- fix: 修复支付宝真机无法使用的问题
+## 1.9.6.2(2024-02-22)
+- fix: 修复使用render函数报错的问题
+## 1.9.6.1(2023-12-22)
+- fix: 修复字节小程序非2d字体偏移
+- fix: 修复`canvasToTempFilePathSync`会触发两次的问题
+- fix: 修复`parser`图片没有宽度的问题
+## 1.9.6(2023-12-06)
+- fix: 修复背景图受padding影响
+- fix: 修复因字节报错改了代理实现导致微信报错
+- 1.9.5.8(2023-11-16)
+- fix: 修复margin问题
+- fix: 修复borderWidth问题
+- fix: 修复textBox问题
+- fix: 修复字节开发工具报`could not be cloned.`问题
+## 1.9.5.7(2023-07-27)
+- fix: 去掉多余的方法
+- chore: 更新文档,增加自定义字体说明
+## 1.9.5.6(2023-07-21)
+- feat: 有限的支持富文本
+- feat: H5和APP 增加 `hidpi` prop,主要用于大尺寸无法生成图片时用
+- fix: 修复 钉钉小程序 缺少 `measureText` 方法
+- chore: 由于微信小程序 pc 端的 canvas 2d 时不时抽风,故不使用canvas 2d
+## 1.9.5.5(2023-06-27)
+- fix: 修复把`emoji`表情字符拆分成多个字符的情况
+## 1.9.5.4(2023-06-05)
+- fix: 修复因`canvasToTempFilePathSync`监听导致重复调用
+## 1.9.5.3(2023-05-23)
+- fix: 因isPc错写成了isPC导致小程序PC不能生成图片
+## 1.9.5.2(2023-05-22)
+- feat: 删除多余文件
+## 1.9.5.1(2023-05-22)
+- fix: 修复 文字行数与`line-clamp`相同但不满一行时也加了省略号的问题
+## 1.9.5(2023-05-14)
+- feat: 增加 `text-indent` 和 `calc` 方法
+- feat: 优化 布局时间
+## 1.9.4.4(2023-04-15)
+- fix: 修复无法匹配负值
+- fix: 修复 Nvue IOS getImageInfo `useCORS` 为 undefined
+## 1.9.4.3(2023-04-01)
+- feat: 增加支持文字描边 `text-stroke: '5rpx #fff'`
+## 1.9.4.2(2023-03-30)
+- fix: 修复 支付宝小程序 isPC 在手机也为true的问题
+- feat: 由 微信开发工具 3060 版 无法获取图片尺寸,现 微信开发工具 3220 版 修复该问题,故还原上一版的获取图片方式。
+## 1.9.4.1(2023-03-28)
+- fix: 修复固定高度不正确问题
+## 1.9.4(2023-03-17)
+- fix: nvue ios getImageInfo缺少this报错
+- fix: pathType 非2d无效问题
+- fix: 修复 小米9se 可能会存在多次init 导致画面多次放大
+- fix: 修复 border 分开写 width style无效问题
+- fix: 修复 支付宝小程序IOS 再次进入不渲染的问题
+- fix: 修复 支付宝小程序安卓Zindex排序错乱问题
+- fix: 修复 微信开发工具 3060 版 无法获取图片的问题
+- feat: 把 for in 改为 forEach
+- feat: 增加 hidden
+- feat: 根节点 box-sizing 默认 `border-box`
+- feat: 增加支持 `vw` `wh`
+- chore: pathType 取消 默认值,因为字节开发工具不能显示
+- chore: 支付宝小程序开发工具不支持 生成图片 请以真机调试为准
+- bug: 企业微信 2.20.3无法使用
+## 1.9.3.5(2022-06-29)
+- feat: justifyContent 增加 `space-around`、`space-between`
+- feat: canvas 2d 也使用`getImageInfo`
+- fix: 修复 `text`的 `text-decoration`错位
+## 1.9.3.4(2022-06-20)
+- fix: 修复 因创建节点速度问题导致顺序出错。 
+- fix: 修复 微信小程序 PC 无法显示本地图片 
+- fix: 修复 flex-box 对齐问题 
+- feat: 增加 `text-shadow`
+- feat: 重写 `text` 对齐方式
+- chore: 更新文档
+## 1.9.3.3(2022-06-17)
+- fix: 修复 支付宝小程序 canvas 2d 存在ctx.draw问题导致报错
+- fix: 修复 支付宝小程序 toDataURL 存在权限问题改用 `toTempFilePath`
+- fix: 修复 支付宝小程序 image size 问题导致 `objectFit` 无效
+## 1.9.3.2(2022-06-14)
+- fix: 修复 image 设置背景色不生效问题
+- fix: 修复 nvue 环境判断缺少参数问题
+## 1.9.3.1(2022-06-14)
+- fix: 修复 bottom 定位不对问题
+- fix: 修复 因小数导致计算出错换行问题
+- feat: 增加 `useCORS` h5端图片跨域 在设置请求头无效果后试一下设置这个值
+- chore: 更新文档
+## 1.9.3(2022-06-13)
+- feat: 增加 `zIndex`
+- feat: 增加 `flex-box` 该功能处于原始阶段,非常简陋。
+- tips: QQ小程序 vue3 不支持, 为 uni 官方BUG
+## 1.9.2.9(2022-06-10)
+- fix: 修复`text-align`及`margin`居中问题
+## 1.9.2.8(2022-06-10)
+- fix: 修复 Nvue `canvasToTempFilePathSync` 不生效问题
+## 1.9.2.7(2022-06-10)
+- fix: 修复 margin及padding的bug
+- fix: 修复 Nvue `isCanvasToTempFilePath` 不生效问题
+## 1.9.2.6(2022-06-09)
+- fix: 修复 Nvue 不显示
+- feat: 增加支持字体渐变
+```html
+<l-painter-text 
+	text="水调歌头\n明月几时有?把酒问青天。不知天上宫阙,今夕是何年。我欲乘风归去,又恐琼楼玉宇,高处不胜寒。起舞弄清影,何似在人间。"
+	css="background: linear-gradient(,#ff971b 0%, #1989fa 100%); background-clip: text" />
+```
+## 1.9.2.5(2022-06-09)
+- chore: 更变获取父级宽度的设定
+- chore: `pathType` 在canvas 2d 默认为 `url`
+## 1.9.2.4(2022-06-08)
+- fix: 修复 `pathType` 不生效问题
+## 1.9.2.3(2022-06-08)
+- fix: 修复 `canvasToTempFilePath` 漏写 `success` 参数
+## 1.9.2.2(2022-06-07)
+- chore: 更新文档
+## 1.9.2.1(2022-06-07)
+- fix: 修复 vue3 赋值给this再传入导致image无法绘制
+- fix: 修复 `canvasToTempFilePathSync` 时机问题
+- feat: canvas 2d 更改图片生成方式 `toDataURL` 
+## 1.9.2(2022-05-30)
+- fix: 修复 `canvasToTempFilePathSync` 在 vue3 下只生成一次
+## 1.9.1.7(2022-05-28)
+- fix: 修复 `qrcode`显示不全问题
+## 1.9.1.6(2022-05-28)
+- fix: 修复 `canvasToTempFilePathSync` 会重复多次问题
+- fix: 修复 `view` css `backgroundImage` 图片下载失败导致 子节点不渲染
+## 1.9.1.5(2022-05-27)
+- fix: 修正支付宝小程序 canvas 2d版本号 2.7.15
+## 1.9.1.4(2022-05-22)
+- fix: 修复字节小程序无法使用xml方式
+- fix: 修复字节小程序无法使用base64(非2D情况下工具上无法显示)
+- fix: 修复支付宝小程序 `canvasToTempFilePath` 报错
+## 1.9.1.3(2022-04-29)
+- fix: 修复vue3打包后uni对象为空后的报错
+## 1.9.1.2(2022-04-25)
+- fix: 删除多余文件
+## 1.9.1.1(2022-04-25)
+- fix: 修复图片不显示问题
+## 1.9.1(2022-04-12)
+- fix: 因四舍五入导致有些机型错位
+- fix: 修复无views报错 
+- chore: nvue下因ios无法读取插件内static文件,改由下载方式
+## 1.9.0(2022-03-20)
+- fix: 因无法固定尺寸导致生成图片不全
+- fix: 特定情况下text判断无效
+- chore: 本地化APP Nvue webview
+## 1.8.9(2022-02-20)
+- fix: 修复 小程序下载最多10次并发的问题
+- fix: 修复 APP端无法获取本地图片
+- fix: 修复 APP Nvue端不执行问题
+- chore: 增加图片缓存机制
+## 1.8.8.8(2022-01-27)
+- fix: 修复 主动调用尺寸问题
+## 1.8.8.6(2022-01-26)
+- fix: 修复 nvue 下无宽度时获取父级宽度 
+- fix: 修复 ios app 无法渲染问题
+## 1.8.8(2022-01-23)
+- fix: 修复 主动调用时无节点问题
+- fix: 修复 `box-shadow` 颜色问题
+- fix: 修复 `transform:rotate` 角度位置问题
+- feat: 增加 `overflow:hidden`
+## 1.8.7(2022-01-07)
+- fix: 修复 image 方向为 `right` 时原始宽高问题
+- feat: 支持 view 设置背景图 `background-image: url(xxx)`
+- chore: 去掉可选链
+## 1.8.6(2021-11-28)
+- feat: 支持`view`对`inline-block`的子集使用`text-align`
+## 1.8.5.5(2021-08-17)
+- chore: 更新文档,删除 replace
+- fix: 修复 text 值为 number时报错
+## 1.8.5.4(2021-08-16)
+- fix: 字节小程序兼容
+## 1.8.5.3(2021-08-15)
+- fix: 修复线性渐变与css现实效果不一致的问题
+- chore: 更新文档
+## 1.8.5.2(2021-08-13)
+- chore: 增加`background-image`、`background-repeat` 能力,主要用于背景纹理的绘制,并不是代替`image`。例如:大面积的重复平铺的水印
+- 注意:这个功能H5暂时无法使用,因为[官方的API有BUG](https://ask.dcloud.net.cn/question/128793),待官方修复!!!
+## 1.8.5.1(2021-08-10)
+- fix: 修复因`margin`报错问题
+## 1.8.5(2021-08-09)
+- chore: 增加margin支持`auto`,以达到居中效果
+## 1.8.4(2021-08-06)
+- chore: 增加判断缓存文件条件
+- fix: 修复css 多余空格报错问题
+## 1.8.3(2021-08-04)
+- tips: 1.6.x 以下的版本升级到1.8.x后要为每个元素都加上定位:position: 'absolute'
+- fix: 修复只有一个view子元素时不计算高度的问题
+## 1.8.2(2021-08-03)
+- fix: 修复 path-type 为 `url` 无效问题
+- fix: 修复 qrcode `text` 为空时报错问题
+- fix: 修复 image `src` 动态设置时不生效问题
+- feat: 增加 css 属性 `min-width` `max-width`
+## 1.8.1(2021-08-02)
+- fix: 修复无法加载本地图片
+## 1.8.0(2021-08-02)
+- chore 文档更新
+- 使用旧版的同学不要升级!
+## 1.8.0-beta(2021-07-30)
+- ## 全新布局方式 不兼容旧版!
+- chore: 布局方式变更
+- tips: 微信canvas 2d 不支持真机调试
+## 1.6.6(2021-07-09)
+- chore: 统一命名规范,无须主动引入组件
+## 1.6.5(2021-06-08)
+- chore: 去掉console
+## 1.6.4(2021-06-07)
+- fix: 修复 数字 为纯字符串时不转换的BUG
+## 1.6.3(2021-06-06)
+- fix: 修复 PC 端放大的BUG
+## 1.6.2(2021-05-31)
+- fix: 修复 报`adaptor is not a function`错误
+- fix: 修复 text 多行高度
+- fix: 优化 默认文字的基准线
+- feat: `@progress`事件,监听绘制进度
+## 1.6.1(2021-02-28)
+- 删除多余节点
+## 1.6.0(2021-02-26)
+- 调整为uni_modules目录规范
+- 修复:transform的rotate不能为负数问题
+- 新增:`pathType` 指定生成图片返回的路径类型,可选值有 `base64`、`url`

+ 150 - 0
uni_modules/lime-painter/components/common/relation.js

@@ -0,0 +1,150 @@
+const styles = (v ='') =>  v.split(';').filter(v => v && !/^[\n\s]+$/.test(v)).map(v => {
+						const key = v.slice(0, v.indexOf(':'))
+						const value = v.slice(v.indexOf(':')+1)
+						return {
+							[key
+								.replace(/-([a-z])/g, function() { return arguments[1].toUpperCase()})
+								.replace(/\s+/g, '')
+							]: value.replace(/^\s+/, '').replace(/\s+$/, '') || ''
+						}
+					})
+export function parent(parent) {
+	return {
+		provide() {
+			return {
+				[parent]: this
+			}
+		},
+		data() {
+			return {
+				el: {
+					id: null,
+					css: {},
+					views: []
+				},
+			}
+		},
+		watch: {
+			css: { 
+				handler(v) {
+					if(this.canvasId) {
+						this.el.css = (typeof v == 'object' ? v : v && Object.assign(...styles(v))) || {}
+						this.canvasWidth = this.el.css && this.el.css.width || this.canvasWidth
+						this.canvasHeight = this.el.css && this.el.css.height || this.canvasHeight
+					}
+				},
+				immediate: true
+			}
+		}
+	}
+}
+export function children(parent, options = {}) {
+	const indexKey = options.indexKey || 'index'
+	return {
+		inject: {
+			[parent]: {
+				default: null
+			}
+		},
+		watch: {
+			el: {
+				handler(v, o) {
+					if(JSON.stringify(v) != JSON.stringify(o))
+						this.bindRelation()
+				},
+				deep: true,
+				immediate: true
+			},
+			src: {
+				handler(v, o) {
+					if(v != o)
+						this.bindRelation()
+				},
+				immediate: true
+			},
+			text: {
+				handler(v, o) {
+					if(v != o) this.bindRelation()
+				},
+				immediate: true
+			},
+			css: {
+				handler(v, o) {
+					if(v != o)
+						this.el.css = (typeof v == 'object' ? v : v && Object.assign(...styles(v))) || {}
+				},
+				immediate: true
+			},
+			replace: {
+				handler(v, o) {
+					if(JSON.stringify(v) != JSON.stringify(o))
+						this.bindRelation()
+				},
+				deep: true,
+				immediate: true
+			}
+		},
+		created() {
+			if(!this._uid) {
+				this._uid = this._.uid
+			}
+			Object.defineProperty(this, 'parent', {
+				get: () => this[parent] || [],
+			})
+			Object.defineProperty(this, 'index', {
+				get: () =>  {
+					this.bindRelation();
+					const {parent: {el: {views=[]}={}}={}} = this
+					return views.indexOf(this.el)
+				},
+			});
+			this.el.type = this.type
+			if(this.uid) {
+				this.el.uid = this.uid
+			}
+			this.bindRelation()
+		},
+		// #ifdef VUE3
+		beforeUnmount() {
+			this.removeEl()
+		},
+		// #endif
+		// #ifdef VUE2
+		beforeDestroy() {
+			this.removeEl()
+		},
+		// #endif
+		methods: {
+			removeEl() {
+				if (this.parent) {
+					this.parent.el.views = this.parent.el.views.filter(
+						(item) => item._uid !== this._uid
+					);
+				}
+			},
+			bindRelation() {
+				if(!this.el._uid) {
+					this.el._uid = this._uid 
+				}
+				if(['text','qrcode'].includes(this.type)) {
+					this.el.text = this.$slots && this.$slots.default && this.$slots.default[0].text || `${this.text || ''}`.replace(/\\n/g, '\n')
+				}
+				if(this.type == 'image') {
+					this.el.src = this.src
+				}
+				if (!this.parent) {
+					return;
+				}
+				let views = this.parent.el.views || [];
+				if(views.indexOf(this.el) !== -1) {
+					this.parent.el.views = views.map(v => v._uid == this._uid ? this.el : v)
+				} else {
+					this.parent.el.views = [...views, this.el];
+				}
+			}
+		},
+		mounted() {
+			// this.bindRelation()
+		},
+	}
+}

+ 28 - 0
uni_modules/lime-painter/components/l-painter-image/l-painter-image.vue

@@ -0,0 +1,28 @@
+<template>
+	
+</template>
+
+<script>
+	import {parent, children} from '../common/relation';
+	export default {
+		name: 'lime-painter-image',
+		mixins:[children('painter')],
+		props: {
+			id: String,
+			css: [String, Object],
+			src: String
+		},
+		data() {
+			return {
+				type: 'image',
+				el: {
+					css: {},
+					src: null
+				},
+			}
+		}
+	}
+</script>
+
+<style>
+</style>

+ 27 - 0
uni_modules/lime-painter/components/l-painter-qrcode/l-painter-qrcode.vue

@@ -0,0 +1,27 @@
+<template>
+</template>
+
+<script>
+	import {parent, children} from '../common/relation';
+	export default {
+		name: 'lime-painter-qrcode',
+		mixins:[children('painter')],
+		props: {
+			id: String,
+			css: [String, Object],
+			text: String
+		},
+		data() {
+			return {
+				type: 'qrcode',
+				el: {
+					css: {},
+					text: null
+				},
+			}
+		}
+	}
+</script>
+
+<style>
+</style>

+ 33 - 0
uni_modules/lime-painter/components/l-painter-text/l-painter-text.vue

@@ -0,0 +1,33 @@
+<template>
+	<text style="opacity: 0;height: 0;"><slot/></text>
+</template>
+
+<script>
+	import {parent, children} from '../common/relation';
+	export default {
+		name: 'lime-painter-text',
+		mixins:[children('painter')],
+		props: {
+			type: {
+				type: String,
+				default: 'text'
+			},
+			uid: String,
+			css: [String, Object],
+			text: [String, Number],
+			replace: Object,
+		},
+		data() {
+			return {
+				// type: 'text',
+				el: {
+					css: {},
+					text: null
+				},
+			}
+		}
+	}
+</script>
+
+<style>
+</style>

+ 34 - 0
uni_modules/lime-painter/components/l-painter-view/l-painter-view.vue

@@ -0,0 +1,34 @@
+<template>
+	<view><slot/></view>
+</template>
+
+<script>
+	import {parent, children} from '../common/relation';
+	export default {
+		name: 'lime-painter-view',
+		mixins:[children('painter'), parent('painter')],
+		props: {
+			id: String,
+			type: {
+				type: String,
+				default: 'view'
+			},
+			css: [String, Object],
+		},
+		data() {
+			return {
+				// type: 'view',
+				el: {
+					css: {},
+					views:[]
+				},
+			}
+		},
+		mounted() {
+			
+		}
+	}
+</script>
+
+<style>
+</style>

+ 461 - 0
uni_modules/lime-painter/components/l-painter/l-painter.vue

@@ -0,0 +1,461 @@
+<template>
+	<view class="lime-painter" ref="limepainter">
+		<view v-if="canvasId && size" :style="styles">
+			<!-- #ifndef APP-NVUE -->
+			<canvas class="lime-painter__canvas" v-if="use2dCanvas" :id="canvasId" type="2d" :style="size"></canvas>
+			<canvas class="lime-painter__canvas" v-else :id="canvasId" :canvas-id="canvasId" :style="size"
+				:width="boardWidth * dpr" :height="boardHeight * dpr" :hidpi="hidpi"></canvas>
+
+			<!-- #endif -->
+			<!-- #ifdef APP-NVUE -->
+			<web-view :style="size" ref="webview"
+				src="/uni_modules/lime-painter/hybrid/html/index.html"
+				class="lime-painter__canvas" @pagefinish="onPageFinish" @error="onError" @onPostMessage="onMessage">
+			</web-view>
+			<!-- #endif -->
+		</view>
+		<slot />
+	</view>
+</template>
+
+<script>
+	import { parent } from '../common/relation'
+	import props from './props'
+	import {toPx, base64ToPath, pathToBase64, isBase64, sleep, getImageInfo }from './utils';
+	//  #ifndef APP-NVUE
+	import { canIUseCanvas2d, isPC} from './utils';
+	import Painter from './painter';
+	// import Painter from '@painter'
+	const nvue = {}
+	//  #endif
+	//  #ifdef APP-NVUE
+	import nvue from './nvue'
+	//  #endif
+	export default {
+		name: 'lime-painter',
+		mixins: [props, parent('painter'), nvue],
+		data() {
+			return {
+				use2dCanvas: false,
+				canvasHeight: 150,
+				canvasWidth: null,
+				parentWidth: 0,
+				inited: false,
+				progress: 0,
+				firstRender: 0,
+				done: false,
+				tasks: []
+			};
+		},
+		computed: {
+			styles() {
+				return `${this.size}${this.customStyle||''};` + (this.hidden && 'position: fixed; left: 1500rpx;')
+			},
+			canvasId() {
+				return `l-painter${this._ && this._.uid || this._uid}`
+			},
+			size() {
+				if (this.boardWidth && this.boardHeight) {
+					return `width:${this.boardWidth}px; height: ${this.boardHeight}px;`;
+				}
+			},
+			dpr() {
+				return this.pixelRatio || uni.getSystemInfoSync().pixelRatio;
+			},
+			boardWidth() {
+				const {width = 0} = (this.elements && this.elements.css) || this.elements || this
+				const w = toPx(width||this.width)
+				return w || Math.max(w, toPx(this.canvasWidth));
+			},
+			boardHeight() {
+				const {height = 0} = (this.elements && this.elements.css) || this.elements || this
+				const h = toPx(height||this.height)
+				return h || Math.max(h, toPx(this.canvasHeight));
+			},
+			hasBoard() {
+				return this.board && Object.keys(this.board).length
+			},
+			elements() {
+				return this.hasBoard ? this.board : JSON.parse(JSON.stringify(this.el))
+			}
+		},
+		created() {
+			this.use2dCanvas = this.type === '2d' && canIUseCanvas2d() && !isPC
+		},
+		async mounted() {
+			await sleep(30)
+			await this.getParentWeith()
+			this.$nextTick(() => {
+				setTimeout(() => {
+					this.$watch('elements', this.watchRender, {
+						deep: true,
+						immediate: true
+					});
+				}, 30)
+			})
+		},
+		// #ifdef VUE3
+		unmounted() {
+			this.done = false
+			this.inited = false
+			this.firstRender = 0
+			this.progress = 0
+			this.painter = null
+			clearTimeout(this.rendertimer)
+		},
+		// #endif
+		// #ifdef VUE2
+		destroyed() {
+			this.done = false
+			this.inited = false
+			this.firstRender = 0
+			this.progress = 0
+			this.painter = null
+			clearTimeout(this.rendertimer)
+		},
+		// #endif
+		methods: {
+			async watchRender(val, old) {
+				if (!val || !val.views || (!this.firstRender ? !val.views.length : !this.firstRender) || !Object.keys(val).length || JSON.stringify(val) == JSON.stringify(old)) return;
+				this.firstRender = 1
+				this.progress = 0
+				this.done = false
+				clearTimeout(this.rendertimer)
+				this.rendertimer = setTimeout(() => {
+					this.render(val);
+				}, this.beforeDelay)
+			},
+			async setFilePath(path, param) {
+				let filePath = path
+				const {pathType = this.pathType} =  param || this
+				if (pathType == 'base64' && !isBase64(path)) {
+					filePath = await pathToBase64(path)
+				} else if (pathType == 'url' && isBase64(path)) {
+					filePath = await base64ToPath(path)
+				}
+				if (param && param.isEmit) {
+					this.$emit('success', filePath);
+				}
+				return filePath
+			},
+			async getSize(args) {
+				const {width} = args.css || args
+				const {height} = args.css || args
+				if (!this.size) {
+					if (width || height) {
+						this.canvasWidth = width || this.canvasWidth
+						this.canvasHeight = height || this.canvasHeight
+						await sleep(30);
+					} else {
+						await this.getParentWeith()
+					}
+				}
+			},
+			canvasToTempFilePathSync(args) {
+				// this.stopWatch && this.stopWatch()
+				// this.stopWatch = this.$watch('done', (v) => {
+				// 	if (v) {
+				// 		this.canvasToTempFilePath(args)
+				// 		this.stopWatch && this.stopWatch()
+				// 	}
+				// }, {
+				// 	immediate: true
+				// })
+				this.tasks.push(args)
+				if(this.done){
+					this.runTask()
+				}
+			},
+			runTask(){
+				while(this.tasks.length){
+					const task = this.tasks.shift()	
+					 this.canvasToTempFilePath(task)
+				}
+			},
+			// #ifndef APP-NVUE
+			getParentWeith() {
+				return new Promise(resolve => {
+					uni.createSelectorQuery()
+						.in(this)
+						.select(`.lime-painter`)
+						.boundingClientRect()
+						.exec(res => {
+							const {width, height} = res[0]||{}
+							this.parentWidth = Math.ceil(width||0)
+							this.canvasWidth = this.parentWidth || 300
+							this.canvasHeight = height || this.canvasHeight||150
+							resolve(res[0])
+						})
+				})
+			},
+			async render(args = {}) {
+				if(!Object.keys(args).length) {
+					return console.error('空对象')
+				}
+				this.progress = 0
+				this.done = false
+				// #ifdef APP-NVUE
+				this.tempFilePath.length = 0
+				// #endif
+				await this.getSize(args)
+				const ctx = await this.getContext();
+				
+				let {
+					use2dCanvas,
+					boardWidth,
+					boardHeight,
+					canvas,
+					afterDelay
+				} = this;
+				if (use2dCanvas && !canvas) {
+					return Promise.reject(new Error('canvas 没创建'));
+				}
+				this.boundary = {
+					top: 0,
+					left: 0,
+					width: boardWidth,
+					height: boardHeight
+				};
+				this.painter = null
+				if (!this.painter) {
+					const {width} = args.css || args
+					const {height} = args.css || args
+					if(!width && this.parentWidth) {
+						Object.assign(args, {width: this.parentWidth})
+					}
+					const param = {
+						context: ctx,
+						canvas,
+						width: boardWidth,
+						height: boardHeight,
+						pixelRatio: this.dpr,
+						useCORS: this.useCORS,
+						createImage: getImageInfo.bind(this),
+						performance: this.performance,
+						listen: {
+							onProgress: (v) => {
+								this.progress = v
+								this.$emit('progress', v)
+							},
+							onEffectFail: (err) => {
+								this.$emit('faill', err)
+							}
+						}
+					}
+					this.painter = new Painter(param)
+				} 
+				try{
+					// vue3 赋值给data会引起图片无法绘制
+					const { width, height } = await this.painter.source(JSON.parse(JSON.stringify(args)))
+					this.boundary.height = this.canvasHeight = height
+					this.boundary.width = this.canvasWidth = width
+					await sleep(this.sleep);
+					await this.painter.render()
+					await new Promise(resolve => this.$nextTick(resolve));
+					if (!use2dCanvas) {
+						await this.canvasDraw();
+					}
+					if (afterDelay && use2dCanvas) {
+						await sleep(afterDelay);
+					}
+					this.$emit('done');
+					this.done = true
+					if (this.isCanvasToTempFilePath) {
+						this.canvasToTempFilePath()
+							.then(res => {
+								this.$emit('success', res.tempFilePath)
+							})
+							.catch(err => {
+								this.$emit('fail', new Error(JSON.stringify(err)));
+							});
+					}
+					this.runTask()
+					return Promise.resolve({
+						ctx,
+						draw: this.painter,
+						node: this.node
+					});
+				}catch(e){
+					//TODO handle the exception
+				}
+				
+			},
+			canvasDraw(flag = false) {
+				return new Promise((resolve, reject) => this.ctx.draw(flag, () => setTimeout(() => resolve(), this
+					.afterDelay)));
+			},
+			async getContext() {
+				if (!this.canvasWidth) {
+					this.$emit('fail', 'painter no size')
+					console.error('[lime-painter]: 给画板或父级设置尺寸')
+					return Promise.reject();
+				}
+				if (this.ctx && this.inited) {
+					return Promise.resolve(this.ctx);
+				}
+				const { type, use2dCanvas, dpr, boardWidth, boardHeight } = this;
+				const _getContext = () => {
+					return new Promise(resolve => {
+						uni.createSelectorQuery()
+							.in(this)
+							.select(`#${this.canvasId}`)
+							.boundingClientRect()
+							.exec(res => {
+								if (res) {
+									const ctx = uni.createCanvasContext(this.canvasId, this);
+									if (!this.inited) {
+										this.inited = true;
+										this.use2dCanvas = false;
+										this.canvas = res;
+									}
+									
+									// 钉钉小程序框架不支持 measureText 方法,用此方法 mock
+									if (!ctx.measureText) {
+										function strLen(str) {
+											let len = 0;
+											for (let i = 0; i < str.length; i++) {
+												if (str.charCodeAt(i) > 0 && str.charCodeAt(i) < 128) {
+													len++;
+												} else {
+													len += 2;
+												}
+											}
+											return len;
+										}
+										ctx.measureText = text => {
+											let fontSize = ctx.state && ctx.state.fontSize || 12;
+											const font = ctx.__font
+											if (font && fontSize == 12) {
+												fontSize = parseInt(font.split(' ')[3], 10);
+											}
+											fontSize /= 2;
+											return {
+												width: strLen(text) * fontSize
+											};
+										}
+									}
+									
+									// #ifdef MP-ALIPAY
+									ctx.scale(dpr, dpr);
+									// #endif
+									this.ctx = ctx
+									resolve(this.ctx);
+								} else {
+									console.error('[lime-painter] no node')
+								}
+							});
+					});
+				};
+				if (!use2dCanvas) {
+					return _getContext();
+				}
+				return new Promise(resolve => {
+					uni.createSelectorQuery()
+						.in(this)
+						.select(`#${this.canvasId}`)
+						.node()
+						.exec(res => {
+							let {node: canvas} = res && res[0]||{};
+							if(canvas) {
+								const ctx = canvas.getContext(type);
+								if (!this.inited) {
+									this.inited = true;
+									this.use2dCanvas = true;
+									this.canvas = canvas;
+								}
+								this.ctx = ctx
+								resolve(this.ctx);
+							} else {
+								console.error('[lime-painter]: no size')
+							}
+						});
+				});
+			},
+			canvasToTempFilePath(args = {}) {
+				return new Promise(async (resolve, reject) => {
+					const { use2dCanvas, canvasId, dpr, fileType, quality } = this;
+					const success = async (res) => {
+						try {
+							const tempFilePath = await this.setFilePath(res.tempFilePath || res, args)
+							const result = Object.assign(res, {tempFilePath})
+							args.success && args.success(result)
+							resolve(result)
+						} catch (e) {
+							this.$emit('fail', e)
+						}
+					}
+					
+					let { top: y = 0, left: x = 0, width, height } = this.boundary || this;
+					// let destWidth = width * dpr;
+					// let destHeight = height * dpr;
+					// #ifdef MP-ALIPAY
+					// width = destWidth;
+					// height = destHeight;
+					// #endif
+					
+					const copyArgs = Object.assign({
+						// x,
+						// y,
+						// width,
+						// height,
+						// destWidth,
+						// destHeight,
+						canvasId,
+						id: canvasId,
+						fileType,
+						quality,
+					}, args, {success});
+					// if(this.isPC || use2dCanvas) {
+					// 	copyArgs.canvas = this.canvas
+					// }
+					if (use2dCanvas) {
+						copyArgs.canvas = this.canvas
+						try{
+							// #ifndef MP-ALIPAY
+							const oFilePath = this.canvas.toDataURL(`image/${args.fileType||fileType}`.replace(/pg/, 'peg'), args.quality||quality)
+							if(/data:,/.test(oFilePath)) {
+								uni.canvasToTempFilePath(copyArgs, this);
+							} else {
+								const tempFilePath = await this.setFilePath(oFilePath, args)
+								args.success && args.success({tempFilePath})
+								resolve({tempFilePath})
+							}
+							// #endif
+							// #ifdef MP-ALIPAY
+							this.canvas.toTempFilePath(copyArgs)
+							// #endif
+						}catch(e){
+							args.fail && args.fail(e)
+							reject(e)
+						}
+					} else {
+						// #ifdef MP-ALIPAY
+						if(this.ctx.toTempFilePath) {
+							// 钉钉
+							const ctx = uni.createCanvasContext(canvasId);
+							ctx.toTempFilePath(copyArgs);
+						} else {
+							my.canvasToTempFilePath(copyArgs);
+						}
+						// #endif
+						// #ifndef MP-ALIPAY
+						uni.canvasToTempFilePath(copyArgs, this);
+						// #endif
+					}
+				})
+			}
+			// #endif
+		}
+	};
+</script>
+<style>
+	.lime-painter,
+	.lime-painter__canvas {
+		// #ifndef APP-NVUE
+		width: 100%;
+		// #endif
+		// #ifdef APP-NVUE
+		flex: 1;
+		// #endif
+	}
+</style>

+ 214 - 0
uni_modules/lime-painter/components/l-painter/nvue.js

@@ -0,0 +1,214 @@
+// #ifdef APP-NVUE
+import {
+	sleep,
+	getImageInfo,
+	isBase64,
+	networkReg
+} from './utils';
+const dom = weex.requireModule('dom')
+import {
+	version
+} from '../../package.json'
+
+export default {
+	data() {
+		return {
+			tempFilePath: [],
+			isInitFile: false,
+			osName: uni.getSystemInfoSync().osName
+		}
+	},
+	methods: {
+		getParentWeith() {
+			return new Promise(resolve => {
+				dom.getComponentRect(this.$refs.limepainter, (res) => {
+					this.parentWidth = Math.ceil(res.size.width)
+					this.canvasWidth = this.canvasWidth || this.parentWidth || 300
+					this.canvasHeight = res.size.height || this.canvasHeight || 150
+					resolve(res.size)
+				})
+			})
+		},
+		onPageFinish() {
+			this.webview = this.$refs.webview
+			this.webview.evalJS(`init(${this.dpr})`)
+		},
+		onMessage(e) {
+			const res = e.detail.data[0] || null;
+			if (res.event) {
+				if (res.event == 'inited') {
+					this.inited = true
+				}
+				if (res.event == 'fail') {
+					this.$emit('fail', res)
+				}
+				if (res.event == 'layoutChange') {
+					const data = typeof res.data == 'string' ? JSON.parse(res.data) : res.data
+					this.canvasWidth = Math.ceil(data.width);
+					this.canvasHeight = Math.ceil(data.height);
+				}
+				if (res.event == 'progressChange') {
+					this.progress = res.data * 1
+				}
+				if (res.event == 'file') {
+					this.tempFilePath.push(res.data)
+					if (this.tempFilePath.length > 7) {
+						this.tempFilePath.shift()
+					}
+					return
+				}
+				if (res.event == 'success') {
+					if (res.data) {
+						this.tempFilePath.push(res.data)
+						if (this.tempFilePath.length > 8) {
+							this.tempFilePath.shift()
+						}
+						if (this.isCanvasToTempFilePath) {
+							this.setFilePath(this.tempFilePath.join(''), {
+								isEmit: true
+							})
+						}
+					} else {
+						this.$emit('fail', 'canvas no data')
+					}
+					return
+				}
+				this.$emit(res.event, JSON.parse(res.data));
+			} else if (res.file) {
+				this.file = res.data;
+			} else {
+				console.info(res[0])
+			}
+		},
+		getWebViewInited() {
+			if (this.inited) return Promise.resolve(this.inited);
+			return new Promise((resolve) => {
+				this.$watch(
+					'inited',
+					async val => {
+						if (val) {
+							resolve(val)
+						}
+					}, {
+						immediate: true
+					}
+				);
+			})
+		},
+		getTempFilePath() {
+			if (this.tempFilePath.length == 8) return Promise.resolve(this.tempFilePath)
+			return new Promise((resolve) => {
+				this.$watch(
+					'tempFilePath',
+					async val => {
+						if (val.length == 8) {
+							resolve(val.join(''))
+						}
+					}, {
+						deep: true
+					}
+				);
+			})
+		},
+		getWebViewDone() {
+			if (this.progress == 1) return Promise.resolve(this.progress);
+			return new Promise((resolve) => {
+				this.$watch(
+					'progress',
+					async val => {
+						if (val == 1) {
+							this.$emit('done')
+							this.done = true
+							this.runTask()
+							resolve(val)
+						}
+					}, {
+						immediate: true
+					}
+				);
+			})
+		},
+		async render(args) {
+			try {
+				await this.getSize(args)
+				const {
+					width
+				} = args.css || args
+				if (!width && this.parentWidth) {
+					Object.assign(args, {
+						width: this.parentWidth
+					})
+				}
+				const newNode = await this.calcImage(args);
+				await this.getWebViewInited()
+				this.webview.evalJS(`source(${JSON.stringify(newNode)})`)
+				await this.getWebViewDone()
+				await sleep(this.afterDelay)
+				if (this.isCanvasToTempFilePath) {
+					const params = {
+						fileType: this.fileType,
+						quality: this.quality
+					}
+					this.webview.evalJS(`save(${JSON.stringify(params)})`)
+				}
+				return Promise.resolve()
+			} catch (e) {
+				this.$emit('fail', e)
+			}
+		},
+		async calcImage(args) {
+			let node = JSON.parse(JSON.stringify(args))
+			const urlReg = /url\((.+)\)/
+			const {
+				backgroundImage
+			} = node.css || {}
+			const isBG = backgroundImage && urlReg.exec(backgroundImage)[1]
+			const url = node.url || node.src || isBG
+			if (['text', 'qrcode'].includes(node.type)) {
+				return node
+			}
+			if ((node.type === "image" || isBG) && url && !isBase64(url) && (this.osName == 'ios' || !networkReg
+					.test(url))) {
+				let {
+					path
+				} = await getImageInfo(url, true)
+				if (isBG) {
+					node.css.backgroundImage = `url(${path})`
+				} else {
+					node.src = path
+				}
+			} else if (node.views && node.views.length) {
+				for (let i = 0; i < node.views.length; i++) {
+					node.views[i] = await this.calcImage(node.views[i])
+				}
+			}
+			return node
+		},
+		async canvasToTempFilePath(args = {}) {
+			if (!this.inited) {
+				return this.$emit('fail', 'no init')
+			}
+			this.tempFilePath = []
+			if (args.fileType == 'jpg') {
+				args.fileType = 'jpeg'
+			}
+
+			this.webview.evalJS(`save(${JSON.stringify(args)})`)
+			try {
+				let tempFilePath = await this.getTempFilePath()
+
+				tempFilePath = await this.setFilePath(tempFilePath, args)
+				args.success({
+					errMsg: "canvasToTempFilePath:ok",
+					tempFilePath
+				})
+			} catch (e) {
+				console.log('e', e)
+				args.fail({
+					error: e
+				})
+			}
+		}
+	}
+}
+// #endif

Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
uni_modules/lime-painter/components/l-painter/painter.js


+ 56 - 0
uni_modules/lime-painter/components/l-painter/props.js

@@ -0,0 +1,56 @@
+export default {
+	props: {
+		board: Object,
+		pathType: String, // 'base64'、'url'
+		fileType: {
+			type: String,
+			default: 'png'
+		},
+		hidden: Boolean,
+		quality: {
+			type: Number,
+			default: 1
+		},
+		css: [String, Object],
+		// styles: [String, Object],
+		width: [Number, String],
+		height: [Number, String],
+		pixelRatio: Number,
+		customStyle: String,
+		isCanvasToTempFilePath: Boolean,
+		// useCanvasToTempFilePath: Boolean,
+		sleep: {
+			type: Number,
+			default: 1000 / 30
+		},
+		beforeDelay: {
+			type: Number,
+			default: 100
+		},
+		afterDelay: {
+			type: Number,
+			default: 100
+		},
+		performance: Boolean,
+		// #ifdef MP-WEIXIN || MP-TOUTIAO || MP-ALIPAY
+		type: {
+			type: String,
+			default: '2d'
+		},
+		// #endif
+		// #ifdef APP-NVUE
+		hybrid: Boolean,
+		timeout: {
+			type: Number,
+			default: 2000
+		},
+		// #endif
+		// #ifdef H5 || APP-PLUS
+		useCORS: Boolean,
+		hidpi: {
+			type: Boolean,
+			default: true
+		}
+		// #endif
+	}
+}

Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
uni_modules/lime-painter/components/l-painter/single.js


+ 368 - 0
uni_modules/lime-painter/components/l-painter/utils.js

@@ -0,0 +1,368 @@
+export const networkReg = /^(http|\/\/)/;
+export const isBase64 = (path) => /^data:image\/(\w+);base64/.test(path);
+export function sleep(delay) {
+	return new Promise(resolve => setTimeout(resolve, delay))
+}
+let {platform, SDKVersion} = uni.getSystemInfoSync() 
+export const isPC = /windows|mac/.test(platform)
+// 缓存图片
+let cache = {}
+export function isNumber(value) {
+	return /^-?\d+(\.\d+)?$/.test(value);
+}
+export function toPx(value, baseSize, isDecimal = false) {
+	// 如果是数字
+	if (typeof value === 'number') {
+		return value
+	}
+	// 如果是字符串数字
+	if (isNumber(value)) {
+		return value * 1
+	}
+	// 如果有单位
+	if (typeof value === 'string') {
+		const reg = /^-?([0-9]+)?([.]{1}[0-9]+){0,1}(em|rpx|px|%)$/g
+		const results = reg.exec(value);
+		if (!value || !results) {
+			return 0;
+		}
+		const unit = results[3];
+		value = parseFloat(value);
+		let res = 0;
+		if (unit === 'rpx') {
+			res = uni.upx2px(value);
+		} else if (unit === 'px') {
+			res = value * 1;
+		} else if (unit === '%') {
+			res = value * toPx(baseSize) / 100;
+		} else if (unit === 'em') {
+			res = value * toPx(baseSize || 14);
+		}
+		return isDecimal ? res.toFixed(2) * 1 : Math.round(res);
+	}
+	return 0
+}
+
+// 计算版本
+export function compareVersion(v1, v2) {
+	v1 = v1.split('.')
+	v2 = v2.split('.')
+	const len = Math.max(v1.length, v2.length)
+	while (v1.length < len) {
+		v1.push('0')
+	}
+	while (v2.length < len) {
+		v2.push('0')
+	}
+	for (let i = 0; i < len; i++) {
+		const num1 = parseInt(v1[i], 10)
+		const num2 = parseInt(v2[i], 10)
+
+		if (num1 > num2) {
+			return 1
+		} else if (num1 < num2) {
+			return -1
+		}
+	}
+	return 0
+}
+
+function gte(version) {
+  // #ifdef MP-ALIPAY
+  SDKVersion = my.SDKVersion
+  // #endif
+  return compareVersion(SDKVersion, version) >= 0;
+}
+export function canIUseCanvas2d() {
+	// #ifdef MP-WEIXIN
+	return gte('2.9.2');
+	// #endif
+	// #ifdef MP-ALIPAY
+	return gte('2.7.15');
+	// #endif
+	// #ifdef MP-TOUTIAO
+	return gte('1.78.0');
+	// #endif
+	return false
+}
+
+// #ifdef MP
+export const prefix = () => {
+	// #ifdef MP-TOUTIAO
+	return tt
+	// #endif
+	// #ifdef MP-WEIXIN
+	return wx
+	// #endif
+	// #ifdef MP-BAIDU
+	return swan
+	// #endif
+	// #ifdef MP-ALIPAY
+	return my
+	// #endif
+	// #ifdef MP-QQ
+	return qq
+	// #endif
+	// #ifdef MP-360
+	return qh
+	// #endif
+}
+// #endif
+
+
+
+/**
+ * base64转路径
+ * @param {Object} base64
+ */
+export function base64ToPath(base64) {
+	const [, format] = /^data:image\/(\w+);base64,/.exec(base64) || [];
+
+	return new Promise((resolve, reject) => {
+		// #ifdef MP
+		const fs = uni.getFileSystemManager()
+		//自定义文件名
+		if (!format) {
+			reject(new Error('ERROR_BASE64SRC_PARSE'))
+		}
+		const time = new Date().getTime();
+		let pre = prefix()
+		// #ifdef MP-TOUTIAO
+		const filePath = `${pre.getEnvInfoSync().common.USER_DATA_PATH}/${time}.${format}`
+		// #endif
+		// #ifndef MP-TOUTIAO
+		const filePath = `${pre.env.USER_DATA_PATH}/${time}.${format}`
+		// #endif
+		fs.writeFile({
+			filePath,
+			data: base64.split(',')[1],
+			encoding: 'base64',
+			success() {
+				resolve(filePath)
+			},
+			fail(err) {
+				console.error(err)
+				reject(err)
+			}
+		})
+		// #endif
+
+		// #ifdef H5
+		// mime类型
+		let mimeString = base64.split(',')[0].split(':')[1].split(';')[0];
+		//base64 解码
+		let byteString = atob(base64.split(',')[1]);
+		//创建缓冲数组
+		let arrayBuffer = new ArrayBuffer(byteString.length);
+		//创建视图
+		let intArray = new Uint8Array(arrayBuffer);
+		for (let i = 0; i < byteString.length; i++) {
+			intArray[i] = byteString.charCodeAt(i);
+		}
+		resolve(URL.createObjectURL(new Blob([intArray], {
+			type: mimeString
+		})))
+		// #endif
+
+		// #ifdef APP-PLUS
+		const bitmap = new plus.nativeObj.Bitmap('bitmap' + Date.now())
+		bitmap.loadBase64Data(base64, () => {
+			if (!format) {
+				reject(new Error('ERROR_BASE64SRC_PARSE'))
+			}
+			const time = new Date().getTime();
+			const filePath = `_doc/uniapp_temp/${time}.${format}`
+			bitmap.save(filePath, {},
+				() => {
+					bitmap.clear()
+					resolve(filePath)
+				},
+				(error) => {
+					bitmap.clear()
+					reject(error)
+				})
+		}, (error) => {
+			bitmap.clear()
+			reject(error)
+		})
+		// #endif
+	})
+}
+
+/**
+ * 路径转base64
+ * @param {Object} string
+ */
+export function pathToBase64(path) {
+	if (/^data:/.test(path)) return path
+	return new Promise((resolve, reject) => {
+		// #ifdef H5
+		let image = new Image();
+		image.setAttribute("crossOrigin", 'Anonymous');
+		image.onload = function() {
+			let canvas = document.createElement('canvas');
+			canvas.width = this.naturalWidth;
+			canvas.height = this.naturalHeight;
+			canvas.getContext('2d').drawImage(image, 0, 0);
+			let result = canvas.toDataURL('image/png')
+			resolve(result);
+			canvas.height = canvas.width = 0
+		}
+		image.src = path + '?v=' + Math.random()
+		image.onerror = (error) => {
+			reject(error);
+		};
+		// #endif
+
+		// #ifdef MP
+		if (uni.canIUse('getFileSystemManager')) {
+			uni.getFileSystemManager().readFile({
+				filePath: path,
+				encoding: 'base64',
+				success: (res) => {
+					resolve('data:image/png;base64,' + res.data)
+				},
+				fail: (error) => {
+					console.error({error, path})
+					reject(error)
+				}
+			})
+		}
+		// #endif
+
+		// #ifdef APP-PLUS
+		plus.io.resolveLocalFileSystemURL(getLocalFilePath(path), (entry) => {
+			entry.file((file) => {
+				const fileReader = new plus.io.FileReader()
+				fileReader.onload = (data) => {
+					resolve(data.target.result)
+				}
+				fileReader.onerror = (error) => {
+					reject(error)
+				}
+				fileReader.readAsDataURL(file)
+			}, reject)
+		}, reject)
+		// #endif
+	})
+}
+
+
+
+export function getImageInfo(path, useCORS) {
+	const isCanvas2D = this && this.canvas && this.canvas.createImage
+	return new Promise(async (resolve, reject) => {
+		// let time = +new Date()
+		let src = path.replace(/^@\//,'/')
+		if (cache[path] && cache[path].errMsg) {
+			resolve(cache[path])
+		} else {
+			try {
+				// #ifdef MP || APP-PLUS
+				if (isBase64(path) && (isCanvas2D ? isPC : true)) {
+					src = await base64ToPath(path)
+				}
+				// #endif
+				// #ifdef H5
+				if(useCORS) {
+					src = await pathToBase64(path)
+				}
+				// #endif
+			} catch (error) {
+				reject({
+					...error,
+					src
+				})
+			}
+			// #ifndef APP-NVUE
+			if(isCanvas2D && !isPC) {
+				const img = this.canvas.createImage()
+				img.onload = function() {
+					const image = {
+						path: img,
+						width:  img.width,
+						height:  img.height
+					}
+					cache[path] = image
+					resolve(cache[path])
+				}
+				img.onerror = function(err) {
+					reject({err,path})
+				}
+				img.src = src
+				return
+			}
+			// #endif
+			uni.getImageInfo({
+				src,
+				success: (image) => {
+					const localReg = /^\.|^\/(?=[^\/])/;
+					// #ifdef MP-WEIXIN || MP-BAIDU || MP-QQ || MP-TOUTIAO
+					image.path = localReg.test(src) ?  `/${image.path}` : image.path;
+					// #endif
+					if(isCanvas2D) {
+						const img = this.canvas.createImage()
+						img.onload = function() {
+							image.path = img
+							cache[path] = image
+							resolve(cache[path])
+						}
+						img.onerror = function(err) {
+							reject({err,path})
+						}
+						img.src = src
+						return
+					}
+					// #ifdef APP-PLUS
+					// console.log('getImageInfo', +new Date() - time)
+					// ios 比较严格 可能需要设置跨域
+					if(uni.getSystemInfoSync().osName == 'ios' && useCORS) {
+						pathToBase64(image.path).then(base64 => {
+							image.path = base64
+							cache[path] = image
+							resolve(cache[path])
+						}).catch(err => {
+							console.error({err, path})
+							reject({err,path})
+						})
+						return
+					}
+					// #endif
+					cache[path] = image
+					resolve(cache[path])
+				},
+				fail(err) {
+					console.error({err, path})
+					reject({err,path})
+				}
+			})
+		}
+	})
+}
+
+
+// #ifdef APP-PLUS
+const getLocalFilePath = (path) => {
+	if (path.indexOf('_www') === 0 || path.indexOf('_doc') === 0 || path.indexOf('_documents') === 0 || path
+		.indexOf('_downloads') === 0) {
+		return path
+	}
+	if (path.indexOf('file://') === 0) {
+		return path
+	}
+	if (path.indexOf('/storage/emulated/0/') === 0) {
+		return path
+	}
+	if (path.indexOf('/') === 0) {
+		const localFilePath = plus.io.convertAbsoluteFileSystem(path)
+		if (localFilePath !== path) {
+			return localFilePath
+		} else {
+			path = path.substr(1)
+		}
+	}
+	return '_www/' + path
+}
+// #endif
+
+

Diferenças do arquivo suprimidas por serem muito extensas
+ 166 - 0
uni_modules/lime-painter/components/lime-painter/lime-painter.vue


+ 119 - 0
uni_modules/lime-painter/hybrid/html/index.html

@@ -0,0 +1,119 @@
+<!DOCTYPE html>
+<html lang="zh">
+
+<head>
+	<meta charset="UTF-8">
+	<meta name="viewport" content="width=device-width, initial-scale=1.0">
+	<meta http-equiv="X-UA-Compatible" content="ie=edge">
+	<title></title>
+	<style type="text/css">
+		html,
+		body,
+		canvas {
+			padding: 0;
+			margin: 0;
+			width: 100%;
+			height: 100%;
+			overflow-y: hidden;
+			background-color: transparent;
+		}
+	</style>
+</head>
+
+<body>
+	<canvas id="lime-painter"></canvas>
+	<script type="text/javascript" src="./uni.webview.1.5.3.js"></script>
+	<script type="text/javascript" src="./painter.js"></script>
+	<script> 
+		var cache = [];
+		var painter = null;
+		var canvas = null;
+		var context = null;
+		var timer = null;
+		var pixelRatio = 1;
+		console.log = function (...args) {
+			postMessage(args);
+		};
+		// function stringify(key, value) {
+		// 	if (typeof value === 'object' && value !== null) {
+		// 		if (cache.indexOf(value) !== -1) {
+		// 			return;
+		// 		}
+		// 		cache.push(value);
+		// 	}
+		// 	return value;
+		// };
+
+		function emit(event, data) {
+			postMessage({
+				event,
+				data: (typeof data !== 'object' && data !== null ? data : JSON.stringify(data)) 
+			});
+			cache = [];
+		};
+		function postMessage(data) {
+			uni.postMessage({
+				data
+			});
+		};
+		
+		function init(dpr) {
+			canvas = document.querySelector('#lime-painter');
+			context = canvas.getContext('2d');
+			pixelRatio = dpr || window.devicePixelRatio;
+			painter = new Painter({
+				id: 'lime-painter',
+				context,
+				canvas,
+				pixelRatio,
+				width: canvas.offsetWidth,
+				height: canvas.offsetHeight,
+				listen: {
+					onProgress(v) {
+						emit('progressChange', v);
+					},
+					onEffectFail(err) {
+						//console.error(err)
+						emit('fail', err);
+					}
+				}
+			});
+			emit('inited', true);
+		};
+		function save(args) {
+			delete args.success;
+			delete args.fail;
+			clearTimeout(timer);
+			timer = setTimeout(() => {
+				const path = painter.save(args);
+				if (typeof path == 'string') {
+					const index = Math.ceil(path.length / 8);
+					for (var i = 0; i < 8; i++) {
+						if (i == 7) {
+							emit('success', path.substr(i * index, index));
+						} else {
+							emit('file', path.substr(i * index, index));
+						}
+					};
+				} else {
+					// console.log('canvas no data')
+					emit('fail', 'canvas no data');
+				};
+			}, 30);
+		};
+		async function source(args) {
+			let size = await painter.source(args);
+			emit('layoutChange', size);
+			if(!canvas.height) {
+				console.log('canvas no size')
+				emit('fail', 'canvas no size');
+			}
+			painter.render().catch(err => {
+				// console.error(err)
+				emit('fail', err);
+			});
+		};
+	</script>
+</body>
+
+</html>

Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
uni_modules/lime-painter/hybrid/html/painter.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
uni_modules/lime-painter/hybrid/html/uni.webview.1.5.3.js


+ 92 - 0
uni_modules/lime-painter/package.json

@@ -0,0 +1,92 @@
+{
+  "id": "lime-painter",
+  "displayName": "海报画板",
+  "version": "1.9.6.5",
+  "description": "一款canvas海报组件,更优雅的海报生成方案,有限的支持富文本",
+  "keywords": [
+    "海报",
+    "富文本",
+    "生成海报",
+    "生成二维码",
+    "JSON"
+],
+  "repository": "https://gitee.com/liangei/lime-painter", 
+"engines": {
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": "305716444"
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": [],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y",
+        "alipay": "n"
+      },
+      "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": "u",
+          "Edge": "u",
+          "Firefox": "u",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+        "QQ": "y",
+        "钉钉": "u",
+        "快手": "u",
+        "飞书": "u",
+        "京东": "u"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  },
+  "name": "lime-painter",
+  "main": "index.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "author": "",
+  "license": "ISC"
+}

+ 388 - 0
uni_modules/lime-painter/parser.js

@@ -0,0 +1,388 @@
+/*
+ * HTML5 Parser By Sam Blowes
+ *
+ * Designed for HTML5 documents
+ *
+ * Original code by John Resig (ejohn.org)
+ * http://ejohn.org/blog/pure-javascript-html-parser/
+ * Original code by Erik Arvidsson, Mozilla Public License
+ * http://erik.eae.net/simplehtmlparser/simplehtmlparser.js
+ *
+ * ----------------------------------------------------------------------------
+ * License
+ * ----------------------------------------------------------------------------
+ *
+ * This code is triple licensed using Apache Software License 2.0,
+ * Mozilla Public License or GNU Public License
+ *
+ * ////////////////////////////////////////////////////////////////////////////
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * ////////////////////////////////////////////////////////////////////////////
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * The Original Code is Simple HTML Parser.
+ *
+ * The Initial Developer of the Original Code is Erik Arvidsson.
+ * Portions created by Erik Arvidssson are Copyright (C) 2004. All Rights
+ * Reserved.
+ *
+ * ////////////////////////////////////////////////////////////////////////////
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * ----------------------------------------------------------------------------
+ * Usage
+ * ----------------------------------------------------------------------------
+ *
+ * // Use like so:
+ * HTMLParser(htmlString, {
+ *     start: function(tag, attrs, unary) {},
+ *     end: function(tag) {},
+ *     chars: function(text) {},
+ *     comment: function(text) {}
+ * });
+ *
+ * // or to get an XML string:
+ * HTMLtoXML(htmlString);
+ *
+ * // or to get an XML DOM Document
+ * HTMLtoDOM(htmlString);
+ *
+ * // or to inject into an existing document/DOM node
+ * HTMLtoDOM(htmlString, document);
+ * HTMLtoDOM(htmlString, document.body);
+ *
+ */
+// Regular Expressions for parsing tags and attributes
+var startTag = /^<([-A-Za-z0-9_]+)((?:\s+[a-zA-Z_:][-a-zA-Z0-9_:.]*(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/;
+var endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/;
+var attr = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g; // Empty Elements - HTML 5
+
+var empty = makeMap('area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr'); // Block Elements - HTML 5
+// fixed by xxx 将 ins 标签从块级名单中移除
+
+var block = makeMap('a,address,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video'); // Inline Elements - HTML 5
+
+var inline = makeMap('abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var'); // Elements that you can, intentionally, leave open
+// (and which close themselves)
+
+var closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr'); // Attributes that have their values filled in disabled="disabled"
+
+var fillAttrs = makeMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected'); // Special Elements (can contain anything)
+
+var special = makeMap('script,style');
+function HTMLParser(html, handler) {
+  var index;
+  var chars;
+  var match;
+  var stack = [];
+  var last = html;
+
+  stack.last = function () {
+    return this[this.length - 1];
+  };
+
+  while (html) {
+    chars = true; // Make sure we're not in a script or style element
+
+    if (!stack.last() || !special[stack.last()]) {
+      // Comment
+      if (html.indexOf('<!--') == 0) {
+        index = html.indexOf('-->');
+
+        if (index >= 0) {
+          if (handler.comment) {
+            handler.comment(html.substring(4, index));
+          }
+
+          html = html.substring(index + 3);
+          chars = false;
+        } // end tag
+
+      } else if (html.indexOf('</') == 0) {
+        match = html.match(endTag);
+
+        if (match) {
+          html = html.substring(match[0].length);
+          match[0].replace(endTag, parseEndTag);
+          chars = false;
+        } // start tag
+
+      } else if (html.indexOf('<') == 0) {
+        match = html.match(startTag);
+
+        if (match) {
+          html = html.substring(match[0].length);
+          match[0].replace(startTag, parseStartTag);
+          chars = false;
+        }
+      }
+
+      if (chars) {
+        index = html.indexOf('<');
+        var text = index < 0 ? html : html.substring(0, index);
+        html = index < 0 ? '' : html.substring(index);
+
+        if (handler.chars) {
+          handler.chars(text);
+        }
+      }
+    } else {
+      html = html.replace(new RegExp('([\\s\\S]*?)<\/' + stack.last() + '[^>]*>'), function (all, text) {
+        text = text.replace(/<!--([\s\S]*?)-->|<!\[CDATA\[([\s\S]*?)]]>/g, '$1$2');
+
+        if (handler.chars) {
+          handler.chars(text);
+        }
+
+        return '';
+      });
+      parseEndTag('', stack.last());
+    }
+
+    if (html == last) {
+      throw 'Parse Error: ' + html;
+    }
+
+    last = html;
+  } // Clean up any remaining tags
+
+
+  parseEndTag();
+
+  function parseStartTag(tag, tagName, rest, unary) {
+    tagName = tagName.toLowerCase();
+    if (block[tagName]) {
+      while (stack.last() && inline[stack.last()]) {
+        parseEndTag('', stack.last());
+      }
+    }
+
+    if (closeSelf[tagName] && stack.last() == tagName) {
+      parseEndTag('', tagName);
+    }
+
+    unary = empty[tagName] || !!unary;
+
+    if (!unary) {
+      stack.push(tagName);
+    }
+
+    if (handler.start) {
+      var attrs = [];
+      rest.replace(attr, function (match, name) {
+        var value = arguments[2] ? arguments[2] : arguments[3] ? arguments[3] : arguments[4] ? arguments[4] : fillAttrs[name] ? name : '';
+        attrs.push({
+          name: name,
+          value: value,
+          escaped: value.replace(/(^|[^\\])"/g, '$1\\\"') // "
+
+        });
+      });
+
+      if (handler.start) {
+        handler.start(tagName, attrs, unary);
+      }
+    }
+  }
+
+  function parseEndTag(tag, tagName) {
+    // If no tag name is provided, clean shop
+    if (!tagName) {
+      var pos = 0;
+    } // Find the closest opened tag of the same type
+    else {
+        for (var pos = stack.length - 1; pos >= 0; pos--) {
+          if (stack[pos] == tagName) {
+            break;
+          }
+        }
+      }
+
+    if (pos >= 0) {
+      // Close all the open elements, up the stack
+      for (var i = stack.length - 1; i >= pos; i--) {
+        if (handler.end) {
+          handler.end(stack[i]);
+        }
+      } // Remove the open elements from the stack
+
+
+      stack.length = pos;
+    }
+  }
+}
+
+function makeMap(str) {
+  var obj = {};
+  var items = str.split(',');
+
+  for (var i = 0; i < items.length; i++) {
+    obj[items[i]] = true;
+  }
+
+  return obj;
+}
+
+function removeDOCTYPE(html) {
+  return html.replace(/<\?xml.*\?>\n/, '').replace(/<!doctype.*>\n/, '').replace(/<!DOCTYPE.*>\n/, '');
+}
+
+function parseAttrs(attrs) {
+  return attrs.reduce(function (pre, attr) {
+    var value = attr.value;
+    var name = attr.name;
+    if (pre[name]) {
+			pre[name] = pre[name] + " " + value;
+    } else {
+			pre[name] = value;
+    }
+
+    return pre;
+  }, {});
+}
+function convertStyleStringToJSON(styleString) {
+  var styles = styleString.split(";"); // 通过分号将样式字符串分割为多个样式声明
+  var result = {};
+
+  styles.forEach(function(style) {
+    var styleParts = style.split(":"); // 通过冒号将样式声明分割为属性和值
+    var property = styleParts[0].trim();
+    var value = styleParts[1] && styleParts[1].trim();
+
+    if (property && value) {
+      result[property] = value; // 将属性和值添加到结果对象中
+    }
+  });
+
+  return result;
+}
+function parseHtml(html) {
+  html = removeDOCTYPE(html);
+  var stacks = [];
+  var results = {
+    node: 'root',
+    children: []
+  };
+  HTMLParser(html, {
+    start: function start(tag, attrs, unary) {
+      var node = {
+        name: tag
+      };
+
+      if (attrs.length !== 0) {
+        node.attrs = parseAttrs(attrs);
+		node.styles = node.attrs.style ? convertStyleStringToJSON(node.attrs.style) : {}
+      }
+	
+	if(!node.type) {
+	  if(inline[node.name] && node.name !== 'img' ) {
+		node.type = 'text';
+		if(node.name == 'br') {
+			node.text = '\n'
+		} else if(node.name == 'strong'){
+			node.styles.fontWeight = 'bold'
+		}
+	  } else if(node.name == 'img'){
+		 node.type = 'image' 
+		 node.src =  node.attrs.src
+	  } else {
+		   node.type = 'view' 
+		   if(['h1','h2','h3','h4','h5','h6'].includes(node.name)) {
+			   node.styles.fontWeight = 'bold'
+		   }
+	  }
+	}		
+      if (unary) {
+        var parent = stacks[0] || results;
+
+        if (!parent.children) {
+          parent.children = [];
+        }
+
+        parent.children.push(node);
+      } else {
+        stacks.unshift(node);
+      }
+    },
+    end: function end(tag) {
+      var node = stacks.shift();
+      if (node.name !== tag) console.error('invalid state: mismatch end tag');
+      if (stacks.length === 0) {
+        results.children.push(node);
+      } else {
+        var parent = stacks[0];
+
+        if (!parent.children) {
+          parent.children = [];
+        }
+        parent.children.push(node);
+      }
+	  const isTextBox = node.children && node.children.length > 1 && node.children.every(child => {
+		  return ['text','image'].includes(child.type)
+	  })
+	  if(isTextBox) {
+		  node.type = 'textBox'
+	  }
+    },
+    chars: function chars(text) {
+      var node = {
+        type: 'text',
+        text: text
+      };
+
+      if (stacks.length === 0) {
+        results.children.push(node);
+      } else {
+        var parent = stacks[0];
+
+        if (!parent.children) {
+          parent.children = [];
+        }
+
+        parent.children.push(node);
+      }
+    },
+    comment: function comment(text) {
+      var node = {
+        node: 'comment',
+        text: text
+      };
+      var parent = stacks[0];
+
+      if (!parent.children) {
+        parent.children = [];
+      }
+
+      parent.children.push(node);
+    }
+  });
+  return results.children;
+}
+
+export default parseHtml;

+ 963 - 0
uni_modules/lime-painter/readme.md

@@ -0,0 +1,963 @@
+# Painter 画板 测试版
+
+> uniapp 海报画板,更优雅的海报生成方案  
+> [查看更多 站点 1](https://limeui.qcoon.cn/#/painter)  
+> [查看更多 站点 2](http://liangei.gitee.io/limeui/#/painter)  
+> Q 群:1169785031
+
+## 平台兼容
+
+| H5  | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ 小程序 | App |
+| --- | ---------- | ------------ | ---------- | ---------- | --------- | --- |
+| √   | √          | √            | 未测       | √          | √         | √   |
+
+## 安装
+在市场导入**[海报画板](https://ext.dcloud.net.cn/plugin?id=2389)uni_modules**版本的即可,无需`import`
+
+## 代码演示
+
+### 插件demo
+- lime-painter 为 demo
+- 位于 uni_modules/lime-painter/components/lime-painter
+- 导入插件后直接使用可查看demo
+```vue
+<lime-painter />
+```
+
+
+### 基本用法
+
+- 插件提供 JSON 及 Template 的方式绘制海报
+- 参考 css 块状流布局模拟 css schema。
+- 另外flex布局还不是成完善,请谨慎使用,普通的流布局我觉得已经够用了。
+
+#### 方式一 Template
+
+- 提供`l-painter-view`、`l-painter-text`、`l-painter-image`、`l-painter-qrcode`四种类型组件
+- 通过 `css` 属性绘制样式,与 style 使用方式保持一致。
+```html
+<l-painter>
+	//如果使用Template出现顺序错乱,可使用`template` 等所有变量完成再显示
+	<template v-if="show">
+		<l-painter-view
+			css="background: #07c160; height: 120rpx; width: 120rpx; display: inline-block"
+		></l-painter-view>
+		<l-painter-view
+			css="background: #1989fa; height: 120rpx; width: 120rpx; border-top-right-radius: 60rpx; border-bottom-left-radius: 60rpx; display: inline-block; margin: 0 30rpx;"
+		></l-painter-view>
+		<l-painter-view
+			css="background: #ff9d00; height: 120rpx; width: 120rpx; border-radius: 50%; display: inline-block"
+		></l-painter-view>
+	<template>
+</l-painter>
+```
+
+#### 方式二 JSON
+
+- 在 json 里四种类型组件的`type`为`view`、`text`、`image`、`qrcode`
+- 通过 `board` 设置海报所需的 JSON 数据进行绘制或`ref`获取组件实例调用组件内的`render(json)`
+- 所有类型的 schema 都具有`css`字段,css 的 key 值使用**驼峰**如:`lineHeight`
+
+```html
+<l-painter :board="poster"/>
+```
+
+```js
+data() {
+	return {
+		poster: {
+			css: {
+				// 根节点若无尺寸,自动获取父级节点
+				width: '750rpx'
+			},
+			views: [
+				{
+					css: {
+						background: "#07c160",
+						height: "120rpx",
+						width: "120rpx",
+						display: "inline-block"
+					},
+					type: "view"
+				},
+				{
+					css: {
+						background: "#1989fa",
+						height: "120rpx",
+						width: "120rpx",
+						borderTopRightRadius: "60rpx",
+						borderBottomLeftRadius: "60rpx",
+						display: "inline-block",
+						margin: "0 30rpx"
+					},
+					views: [],
+					type: "view"
+				},
+				{
+					css: {
+						background: "#ff9d00",
+						height: "120rpx",
+						width: "120rpx",
+						borderRadius: "50%",
+						display: "inline-block"
+					},
+					views: [],
+					type: "view"
+				},
+			]
+		}
+	}
+}
+```
+
+### View 容器
+
+- 类似于 `div` 可以嵌套承载更多的 view、text、image,qrcode 共同构建一颗完整的节点树
+- 在 JSON 里具有 `views` 的数组字段,用于嵌套承载节点。
+
+#### 方式一 Template
+
+```html
+<l-painter>
+  <l-painter-view css="background: #f0f0f0; padding-top: 100rpx;">
+    <l-painter-view
+      css="background: #d9d9d9; width: 33.33%; height: 100rpx; display: inline-block"
+    ></l-painter-view>
+    <l-painter-view
+      css="background: #bfbfbf; width: 66.66%; height: 100rpx; display: inline-block"
+    ></l-painter-view>
+  </l-painter-view>
+</l-painter>
+```
+
+#### 方式二 JSON
+
+```js
+{
+	css: {},
+	views: [
+		{
+			type: 'view',
+			css: {
+				background: '#f0f0f0',
+				paddingTop: '100rpx'
+			},
+			views: [
+				{
+					type: 'view',
+					css: {
+						background: '#d9d9d9',
+						width: '33.33%',
+						height: '100rpx',
+						display: 'inline-block'
+					}
+				},
+				{
+					type: 'view',
+					css: {
+						background: '#bfbfbf',
+						width: '66.66%',
+						height: '100rpx',
+						display: 'inline-block'
+					}
+				}
+			],
+
+		}
+	]
+}
+```
+
+### Text 文本
+
+- 通过 `text` 属性填写文本内容。
+- 支持`\n`换行符
+- 支持省略号,使用 css 的`line-clamp`设置行数,当文字内容超过会显示省略号。
+- 支持`text-decoration`
+
+#### 方式一 Template
+
+```html
+<l-painter>
+  <l-painter-view css="background: #e0e2db; padding: 30rpx; color: #222a29">
+    <l-painter-text
+      text="登鹳雀楼\n白日依山尽,黄河入海流\n欲穷千里目,更上一层楼"
+    />
+    <l-painter-text
+      text="登鹳雀楼\n白日依山尽,黄河入海流\n欲穷千里目,更上一层楼"
+      css="text-align:center; padding-top: 20rpx; text-decoration: line-through "
+    />
+    <l-painter-text
+      text="登鹳雀楼\n白日依山尽,黄河入海流\n欲穷千里目,更上一层楼"
+      css="text-align:right; padding-top: 20rpx"
+    />
+    <l-painter-text
+      text="水调歌头\n明月几时有?把酒问青天。不知天上宫阙,今夕是何年。我欲乘风归去,又恐琼楼玉宇,高处不胜寒。起舞弄清影,何似在人间。"
+      css="line-clamp: 3; padding-top: 20rpx; background: linear-gradient(,#ff971b 0%, #ff5000 100%); background-clip: text"
+    />
+  </l-painter-view>
+</l-painter>
+```
+
+#### 方式二 JSON
+
+```js
+// 基础用法
+{
+	type: 'text',
+	text: '登鹳雀楼\n白日依山尽,黄河入海流\n欲穷千里目,更上一层楼',
+},
+{
+	type: 'text',
+	text: '登鹳雀楼\n白日依山尽,黄河入海流\n欲穷千里目,更上一层楼',
+	css: {
+		// 设置居中对齐
+		textAlign: 'center',
+		// 设置中划线
+		textDecoration: 'line-through'
+	}
+},
+{
+	type: 'text',
+	text: '登鹳雀楼\n白日依山尽,黄河入海流\n欲穷千里目,更上一层楼',
+	css: {
+		// 设置右对齐
+		textAlign: 'right',
+	}
+},
+{
+	type: 'text',
+	text: '登鹳雀楼\n白日依山尽,黄河入海流\n欲穷千里目,更上一层楼',
+	css: {
+		// 设置行数,超出显示省略号
+		lineClamp: 3,
+		// 渐变文字
+		background: 'linear-gradient(,#ff971b 0%, #1989fa 100%)',
+		backgroundClip: 'text'
+	}
+}
+```
+
+### Image 图片
+
+- 通过 `src` 属性填写图片路径。
+- 图片路径支持:网络图片,本地 static 里的图片路径,缓存路径,**字节的static目录是写相对路径**
+- 通过 `css` 的 `object-fit`属性可以设置图片的填充方式,可选值见下方 CSS 表格。
+- 通过 `css` 的 `object-position`配合 `object-fit` 可以设置图片的对齐方式,类似于`background-position`,详情见下方 CSS 表格。
+- 使用网络图片时:小程序需要去公众平台配置 [downloadFile](https://mp.weixin.qq.com/) 域名
+- 使用网络图片时:**H5 和 Nvue 需要决跨域问题**
+
+#### 方式一 Template
+
+```html
+<l-painter>
+  <!-- 基础用法 -->
+  <l-painter-image
+    src="https://m.360buyimg.com/babel/jfs/t1/196317/32/13733/288158/60f4ea39E6fb378ed/d69205b1a8ed3c97.jpg"
+    css="width: 200rpx; height: 200rpx"
+  />
+  <!-- 填充方式 -->
+  <!-- css object-fit 设置 填充方式 见下方表格-->
+  <l-painter-image
+    src="https://m.360buyimg.com/babel/jfs/t1/196317/32/13733/288158/60f4ea39E6fb378ed/d69205b1a8ed3c97.jpg"
+    css="width: 200rpx; height: 200rpx; object-fit: contain; background: #eee"
+  />
+  <!-- css object-position 设置 图片的对齐方式-->
+  <l-painter-image
+    src="https://m.360buyimg.com/babel/jfs/t1/196317/32/13733/288158/60f4ea39E6fb378ed/d69205b1a8ed3c97.jpg"
+    css="width: 200rpx; height: 200rpx; object-fit: contain; object-position: 50% 50%; background: #eee"
+  />
+</l-painter>
+```
+
+#### 方式二 JSON
+
+```js
+// 基础用法
+{
+	type: 'image',
+	src: 'https://m.360buyimg.com/babel/jfs/t1/196317/32/13733/288158/60f4ea39E6fb378ed/d69205b1a8ed3c97.jpg',
+	css: {
+		width: '200rpx',
+		height: '200rpx'
+	}
+},
+// 填充方式
+// css objectFit 设置 填充方式 见下方表格
+{
+	type: 'image',
+	src: 'https://m.360buyimg.com/babel/jfs/t1/196317/32/13733/288158/60f4ea39E6fb378ed/d69205b1a8ed3c97.jpg',
+	css: {
+		width: '200rpx',
+		height: '200rpx',
+		objectFit: 'contain'
+	}
+},
+// css objectPosition 设置 图片的对齐方式
+{
+	type: 'image',
+	src: 'https://m.360buyimg.com/babel/jfs/t1/196317/32/13733/288158/60f4ea39E6fb378ed/d69205b1a8ed3c97.jpg',
+	css: {
+		width: '200rpx',
+		height: '200rpx',
+		objectFit: 'contain',
+		objectPosition: '50% 50%'
+	}
+}
+```
+
+### Qrcode 二维码
+
+- 通过`text`属性填写需要生成二维码的文本。
+- 通过 `css` 里的 `color` 可设置生成码点的颜色。
+- 通过 `css` 里的 `background`可设置背景色。
+- 通过 `css `里的 `width`、`height`设置尺寸。
+
+#### 方式一 Template
+
+```html
+<l-painter>
+  <l-painter-qrcode
+    text="limeui.qcoon.cn"
+    css="width: 200rpx; height: 200rpx"
+  />
+</l-painter>
+```
+
+#### 方式二 JSON
+
+```js
+{
+	type: 'qrcode',
+	text: 'limeui.qcoon.cn',
+	css: {
+		width: '200rpx',
+		height: '200rpx',
+	}
+}
+```
+
+### 富文本
+- 这是一个有限支持的测试能力,只能通过JSON方式,不要抱太大希望!
+- 首先需要把富文本转成JSON,这需要引入`parser`这个包,如果你不使用是不会进入主包
+
+```html
+<l-painter ref="painter"/>
+```
+```js
+import parseHtml from '@/uni_modules/lime-painter/parser'
+const json = parseHtml(`<p><span>测试测试</span><img src="/static/logo.png"/></p>`)
+this.$refs.painter.render(json)
+```
+
+### 生成图片
+
+- 方式1、通过设置`isCanvasToTempFilePath`自动生成图片并在 `@success` 事件里接收海报临时路径
+- 方式2、通过调用内部方法生成图片:
+
+```html
+<l-painter ref="painter">...code</l-painter>
+```
+
+```js
+this.$refs.painter.canvasToTempFilePathSync({
+  fileType: "jpg",
+  // 如果返回的是base64是无法使用 saveImageToPhotosAlbum,需要设置 pathType为url
+  pathType: 'url',
+  quality: 1,
+  success: (res) => {
+    console.log(res.tempFilePath);
+	// 非H5 保存到相册
+	// H5 提示用户长按图另存
+	uni.saveImageToPhotosAlbum({
+		filePath: res.tempFilePath,
+		success: function () {
+			console.log('save success');
+		}
+	});
+  },
+});
+```
+
+### 主动调用方式
+
+- 通过获取组件实例内部的`render`函数 传递`JSON`即可
+
+```html
+<l-painter ref="painter" />
+```
+
+```js
+// 渲染
+this.$refs.painter.render(jsonSchema);
+// 生成图片
+this.$refs.painter.canvasToTempFilePathSync({
+  fileType: "jpg",
+  // 如果返回的是base64是无法使用 saveImageToPhotosAlbum,需要设置 pathType为url
+  pathType: 'url',
+  quality: 1,
+  success: (res) => {
+    console.log(res.tempFilePath);
+	// 非H5 保存到相册
+	uni.saveImageToPhotosAlbum({
+		filePath: res.tempFilePath,
+		success: function () {
+			console.log('save success');
+		}
+	});
+  },
+});
+```
+
+
+### H5跨域
+- 一般是需要后端或管理OSS资源的大佬处理
+- 一般OSS的处理方式:
+
+1、设置来源
+```cmd
+*
+```
+
+2、允许Methods
+```html
+GET
+```
+
+3、允许Headers
+```html
+access-control-allow-origin:*
+```
+
+4、最后如果还是不行,可试下给插件设置`useCORS`
+```html
+<l-painter useCORS>
+```
+
+
+
+### 海报示例
+
+- 提供一份示例,只把插件当成生成图片的工具,非必要不要在弹窗里使用。
+- 通过设置`isCanvasToTempFilePath`主动生成图片,再由 `@success` 事件接收海报临时路径
+- 设置`hidden`隐藏画板。
+请注意,示例用到了图片,海报的渲染是包括下载图片的时间,也许在某天图片会失效或访问超级慢,请更换为你的图片再查看,另外如果你是小程序请在使用示例时把**不校验合法域名**勾上!!!!!不然不显示还以为是插件的锅,求求了大佬们!
+#### 方式一 Template
+
+```html
+<image :src="path" mode="widthFix"></image>
+<l-painter
+  isCanvasToTempFilePath
+  @success="path = $event"
+  hidden
+  css="width: 750rpx; padding-bottom: 40rpx; background: linear-gradient(,#ff971b 0%, #ff5000 100%)"
+>
+  <l-painter-image
+    src="https://m.360buyimg.com/babel/jfs/t1/196317/32/13733/288158/60f4ea39E6fb378ed/d69205b1a8ed3c97.jpg"
+    css="margin-left: 40rpx; margin-top: 40rpx; width: 84rpx;  height: 84rpx; border-radius: 50%;"
+  />
+  <l-painter-view
+    css="margin-top: 40rpx; padding-left: 20rpx; display: inline-block"
+  >
+    <l-painter-text
+      text="隔壁老王"
+      css="display: block; padding-bottom: 10rpx; color: #fff; font-size: 32rpx; fontWeight: bold"
+    />
+    <l-painter-text
+      text="为您挑选了一个好物"
+      css="color: rgba(255,255,255,.7); font-size: 24rpx"
+    />
+  </l-painter-view>
+  <l-painter-view
+    css="margin-left: 40rpx; margin-top: 30rpx; padding: 32rpx; box-sizing: border-box; background: #fff; border-radius: 16rpx; width: 670rpx; box-shadow: 0 20rpx 58rpx rgba(0,0,0,.15)"
+  >
+    <l-painter-image
+      src="https://m.360buyimg.com/babel/jfs/t1/196317/32/13733/288158/60f4ea39E6fb378ed/d69205b1a8ed3c97.jpg"
+      css="object-fit: cover; object-position: 50% 50%; width: 606rpx; height: 606rpx; border-radius: 12rpx;"
+    />
+    <l-painter-view
+      css="margin-top: 32rpx; color: #FF0000; font-weight: bold; font-size: 28rpx; line-height: 1em;"
+    >
+      <l-painter-text text="¥" css="vertical-align: bottom" />
+      <l-painter-text
+        text="39"
+        css="vertical-align: bottom; font-size: 58rpx"
+      />
+      <l-painter-text text=".39" css="vertical-align: bottom" />
+      <l-painter-text
+        text="¥59.99"
+        css="vertical-align: bottom; padding-left: 10rpx; font-weight: normal; text-decoration: line-through; color: #999999"
+      />
+    </l-painter-view>
+    <l-painter-view css="margin-top: 32rpx; font-size: 26rpx; color: #8c5400">
+      <l-painter-text text="自营" css="color: #212121; background: #ffb400;" />
+      <l-painter-text
+        text="30天最低价"
+        css="margin-left: 16rpx; background: #fff4d9; text-decoration: line-through;"
+      />
+      <l-painter-text
+        text="满减优惠"
+        css="margin-left: 16rpx; background: #fff4d9"
+      />
+      <l-painter-text
+        text="超高好评"
+        css="margin-left: 16rpx; background: #fff4d9"
+      />
+    </l-painter-view>
+    <l-painter-view css="margin-top: 30rpx">
+      <l-painter-text
+        css="line-clamp: 2; color: #333333; line-height: 1.8em; font-size: 36rpx; width: 478rpx; padding-right:32rpx; box-sizing: border-box"
+        text="360儿童电话手表9X 智能语音问答定位支付手表 4G全网通20米游泳级防水视频通话拍照手表男女孩星空蓝"
+      ></l-painter-text>
+      <l-painter-qrcode
+        css="width: 128rpx; height: 128rpx;"
+        text="limeui.qcoon.cn"
+      ></l-painter-qrcode>
+    </l-painter-view>
+  </l-painter-view>
+</l-painter>
+```
+
+```js
+data() {
+	return {
+		path: ''
+	}
+}
+```
+
+#### 方式二 JSON
+
+```html
+<image :src="path" mode="widthFix"></image>
+<l-painter
+  :board="poster"
+  isCanvasToTempFilePath
+  @success="path = $event"
+  hidden
+/>
+```
+
+```js
+data() {
+	return {
+		path: '',
+		poster: {
+		    css: {
+		        width: "750rpx",
+		        paddingBottom: "40rpx",
+		        background: "linear-gradient(,#000 0%, #ff5000 100%)"
+		    },
+		    views: [
+		        {
+		            src: "https://m.360buyimg.com/babel/jfs/t1/196317/32/13733/288158/60f4ea39E6fb378ed/d69205b1a8ed3c97.jpg",
+		            type: "image",
+		            css: {
+		                background: "#fff",
+		                objectFit: "cover",
+		                marginLeft: "40rpx",
+		                marginTop: "40rpx",
+		                width: "84rpx",
+		                border: "2rpx solid #fff",
+		                boxSizing: "border-box",
+		                height: "84rpx",
+		                borderRadius: "50%"
+		            }
+		        },
+		        {
+		            type: "view",
+		            css: {
+		                marginTop: "40rpx",
+		                paddingLeft: "20rpx",
+		                display: "inline-block"
+		            },
+		            views: [
+		                {
+		                    text: "隔壁老王",
+		                    type: "text",
+		                    css: {
+		                        display: "block",
+		                        paddingBottom: "10rpx",
+		                        color: "#fff",
+		                        fontSize: "32rpx",
+		                        fontWeight: "bold"
+		                    }
+		                },
+		                {
+		                    text: "为您挑选了一个好物",
+		                    type: "text",
+		                    css: {
+		                        color: "rgba(255,255,255,.7)",
+		                        fontSize: "24rpx"
+		                    },
+		                }
+		            ],
+		        },
+		        {
+		            css: {
+		                marginLeft: "40rpx",
+		                marginTop: "30rpx",
+		                padding: "32rpx",
+		                boxSizing: "border-box",
+		                background: "#fff",
+		                borderRadius: "16rpx",
+		                width: "670rpx",
+		                boxShadow: "0 20rpx 58rpx rgba(0,0,0,.15)"
+		            },
+		            views: [
+		                {
+							src: "https://m.360buyimg.com/babel/jfs/t1/196317/32/13733/288158/60f4ea39E6fb378ed/d69205b1a8ed3c97.jpg",
+							type: "image",
+		                    css: {
+		                        objectFit: "cover",
+		                        objectPosition: "50% 50%",
+		                        width: "606rpx",
+		                        height: "606rpx"
+		                    },
+		                }, {
+		                    css: {
+		                        marginTop: "32rpx",
+		                        color: "#FF0000",
+		                        fontWeight: "bold",
+		                        fontSize: "28rpx",
+		                        lineHeight: "1em"
+		                    },
+		                    views: [{
+								text: "¥",
+								type: "text",
+		                        css: {
+		                            verticalAlign: "bottom"
+		                        },
+		                    }, {
+								text: "39",
+								type: "text",
+		                        css: {
+		                            verticalAlign: "bottom",
+		                            fontSize: "58rpx"
+		                        },
+		                    }, {
+								text: ".39",
+								type: "text",
+		                        css: {
+		                            verticalAlign: "bottom"
+		                        },
+		                    }, {
+								text: "¥59.99",
+								type: "text",
+		                        css: {
+		                            verticalAlign: "bottom",
+		                            paddingLeft: "10rpx",
+		                            fontWeight: "normal",
+		                            textDecoration: "line-through",
+		                            color: "#999999"
+		                        }
+		                    }],
+
+		                    type: "view"
+		                }, {
+		                    css: {
+		                        marginTop: "32rpx",
+		                        fontSize: "26rpx",
+		                        color: "#8c5400"
+		                    },
+		                    views: [{
+								text: "自营",
+								type: "text",
+		                        css: {
+		                            color: "#212121",
+		                            background: "#ffb400"
+		                        },
+		                    }, {
+								text: "30天最低价",
+								type: "text",
+		                        css: {
+		                            marginLeft: "16rpx",
+		                            background: "#fff4d9",
+		                            textDecoration: "line-through"
+		                        },
+		                    }, {
+								text: "满减优惠",
+								type: "text",
+		                        css: {
+		                            marginLeft: "16rpx",
+		                            background: "#fff4d9"
+		                        },
+		                    }, {
+								text: "超高好评",
+								type: "text",
+		                        css: {
+		                            marginLeft: "16rpx",
+		                            background: "#fff4d9"
+		                        },
+
+		                    }],
+
+		                    type: "view"
+		                }, {
+		                    css: {
+		                        marginTop: "30rpx"
+		                    },
+		                    views: [
+								{
+									text: "360儿童电话手表9X 智能语音问答定位支付手表 4G全网通20米游泳级防水视频通话拍照手表男女孩星空蓝",
+									type: "text",
+									css: {
+										paddingRight: "32rpx",
+										boxSizing: "border-box",
+										lineClamp: 2,
+										color: "#333333",
+										lineHeight: "1.8em",
+										fontSize: "36rpx",
+										width: "478rpx"
+		                        },
+		                    }, {
+								text: "limeui.qcoon.cn",
+								type: "qrcode",
+		                        css: {
+		                            width: "128rpx",
+		                            height: "128rpx",
+		                        },
+
+		                    }],
+		                    type: "view"
+		                }],
+		            type: "view"
+		        }
+		    ]
+		}
+	}
+}
+```
+
+
+### 自定义字体
+- 需要平台的支持,已知微信小程序支持,其它的没试过,如果可行请告之
+
+```
+// 需要在app.vue中下载字体
+uni.loadFontFace({
+	global:true,
+	scopes: ['native'],
+	family: '自定义字体名称',
+	source: 'url("https://sungd.github.io/Pacifico.ttf")',
+  
+	success() {
+	  console.log('success')
+  }
+})
+
+
+// 然后就可以在插件的css中写font-family: '自定义字体名称'
+```
+
+
+### Nvue
+- 必须为HBX 3.4.11及以上
+
+
+### 原生小程序
+
+- 插件里的`painter.js`支持在原生小程序中使用
+- new Painter 之后在`source`里传入 JSON
+- 再调用`render`绘制海报
+- 如需生成图片,请查看微信小程序 cavnas 的[canvasToTempFilePath](https://developers.weixin.qq.com/miniprogram/dev/api/canvas/wx.canvasToTempFilePath.html)
+
+```html
+<canvas type="2d" id="painter" style="width: 100%"></canvas>
+```
+
+```js
+import { Painter } from "./painter";
+page({
+  data: {
+    poster: {
+      css: {
+        width: "750rpx",
+      },
+      views: [
+        {
+          type: "view",
+          css: {
+            background: "#d2d4c8",
+            paddingTop: "100rpx",
+          },
+          views: [
+            {
+              type: "view",
+              css: {
+                background: "#5f7470",
+                width: "33.33%",
+                height: "100rpx",
+                display: "inline-block",
+              },
+            },
+            {
+              type: "view",
+              css: {
+                background: "#889696",
+                width: "33.33%",
+                height: "100rpx",
+                display: "inline-block",
+              },
+            },
+            {
+              type: "view",
+              css: {
+                background: "#b8bdb5",
+                width: "33.33%",
+                height: "100rpx",
+                display: "inline-block",
+              },
+            },
+          ],
+        },
+      ],
+    },
+  },
+  async onLoad() {
+    const res = await this.getCentext();
+    const painter = new Painter(res);
+    // 返回计算布局后的整个内容尺寸
+    const { width, height } = await painter.source(this.data.poster);
+    // 得到计算后的尺寸后 可给canvas尺寸赋值,达到动态响应效果
+    // 渲染
+    await painter.render();
+  },
+  // 获取canvas 2d
+  // 非2d 需要传一个 createImage 方法用于获取图片信息 即把 getImageInfo 的 success 通过 promise resolve 返回
+  getCentext() {
+    return new Promise((resolve) => {
+      wx.createSelectorQuery()
+        .select(`#painter`)
+        .node()
+        .exec((res) => {
+          let { node: canvas } = res[0];
+          resolve({
+            canvas,
+            context: canvas.getContext("2d"),
+            width: canvas.width,
+            height: canvas.height,
+			// createImage: getImageInfo()
+            pixelRatio: 2,
+          });
+        });
+    });
+  },
+});
+```
+
+### 旧版(1.6.x)更新
+
+- 由于 1.8.x 版放弃了以定位的方式,所以 1.6.x 版更新之后要每个样式都加上`position: absolute`
+- 旧版的 `image` mode 模式被放弃,使用`object-fit`
+- 旧版的 `isRenderImage` 改成 `is-canvas-to-temp-file-path`
+- 旧版的 `maxLines` 改成 `line-clamp`
+
+## API
+
+### Props
+
+| 参数                       | 说明                                                         | 类型             | 默认值       |
+| -------------------------- | ------------------------------------------------------------ | ---------------- | ------------ |
+| board                      | JSON 方式的海报元素对象集                                    | <em>object</em>  | -            |
+| css                        | 海报内容最外层的样式,可以理解为`body`                           | <em>object</em>  | 参数请向下看 |
+| custom-style               | canvas 元素的样式                                            | <em>string</em>  |              |
+| hidden               		 | 隐藏画板                                                    | <em>boolean</em>  |   `false`    |
+| is-canvas-to-temp-file-path | 是否生成图片,在`@success`事件接收图片地址                   | <em>boolean</em> | `false`      |
+| after-delay                | 生成图片错乱,可延时生成图片                                 | <em>number</em>  | `100`        |
+| type                       | canvas 类型,对微信头条支付宝小程序可有效,可选值:`2d`,`''` | <em>string</em>  | `2d`         |
+| file-type                  | 生成图片的后缀类型, 可选值:`png`、`jpg`                     | <em>string</em>  | `png`        |
+| path-type                  | 生成图片路径类型,可选值`url`、`base64`                      | <em>string</em>  | `-`          |
+| pixel-ratio                | 生成图片的像素密度,默认为对应手机的像素密度,`nvue`无效     | <em>number</em>  | `-`          |
+| hidpi                | H5和APP是否使用高清处理     | <em>boolean</em>  | `true`          |
+| width                      | **废弃** 画板的宽度,一般只用于通过内部方法时加上            | <em>number</em>  | ``           |
+| height                     | **废弃** 画板的高度 ,同上                                   | <em>number</em>  | ``           |
+
+### css
+| 属性名                                                                              | 支持的值或类型                                                                                                                                                                       | 默认值   |
+| ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------- |
+| (min\max)width                                                                      | 支持`%`、`rpx`、`px`                                                                                                                                                                 | -        |
+| height                                                                              | 同上                                                                                                                                                                                 | -        |
+| color                                                                               | `string`                                                                                                                                                                             | -        |
+| position                                                                            | 定位,可选值:`absolute`、`fixed`                                                                                                                                                    | -        |
+| ↳ left、top、right、bottom                                                          | 配合`position`才生效,支持`%`、`rpx`、`px`                                                                                                                                           | -        |
+| margin                                                                              | 可简写或各方向分别写,如:`margin-top`,支持`auto`、`rpx`、`px`                                                                                                                      | -        |
+| padding                                                                             | 可简写或各方向分别写,支持`rpx`、`px`                                                                                                                                                | -        |
+| border                                                                              | 可简写或各个值分开写:`border-width`、`border-style` 、`border-color`,简写请按顺序写                                                                                                | -        |
+| line-clamp                                                                          | `number`,超过行数显示省略号                                                                                                                                                         | -        |
+| vertical-align                                                                      | 文字垂直对齐,可选值:`bottom`、`top`、`middle`                                                                                                                                      | `middle` |
+| line-height                                                                         | 文字行高,支持`rpx`、`px`、`em`                                                                                                                                                      | `1.4em`  |
+| font-weight                                                                         | 文字粗细,可选值:`normal`、`bold`                                                                                                                                                   | `normal` |
+| font-size                                                                           | 文字大小,`string`,支持`rpx`、`px`                                                                                                                                                  | `14px`   |
+| text-decoration                                                                     | 文本修饰,可选值:`underline` 、`line-through`、`overline`                                                                                                                           | -        |
+| text-stroke                                                                         | 文字描边,可简写或各个值分开写,如:`text-stroke-color`, `text-stroke-width`                                                                                                              | -        |
+| text-align                                                                          | 文本水平对齐,可选值:`right` 、`center`                                                                                                                                             | `left`   |
+| display                                                                             | 框类型,可选值:`block`、`inline-block`、`flex`、`none`,当为`none`时是不渲染该段, `flex`功能简陋。                                                                                                            | -        |
+| flex                                                                                | 配合 display: flex; 属性定义了在分配多余空间,目前只用为数值如: flex: 1                                                                                                           | -        |
+| align-self                                                                          | 配合 display: flex; 单个项目垂直轴对齐方式: `flex-start` `flex-end` `center`                                                                                                         | `flex-start`        |
+| justify-content                                                                     | 配合 display: flex; 水平轴对齐方式: `flex-start` `flex-end` `center`                                                                                                         | `flex-start`        |
+| align-items                                                                         | 配合 display: flex; 垂直轴对齐方式: `flex-start` `flex-end` `center`                                                                                                  | `flex-start`        |
+| border-radius                                                                       | 圆角边框,支持`%`、`rpx`、`px`                                                                                                                                                       | -        |
+| box-sizing                                                                          | 可选值:`border-box`                                                                                                                                                                 | -        |
+| box-shadow                                                                          | 投影                                                                                                                                                                                 | -        |
+| background(color)                                                                   | 支持渐变,但必须写百分比!如:`linear-gradient(,#ff971b 0%, #ff5000 100%)`、`radial-gradient(#0ff 15%, #f0f 60%)`,目前 radial-gradient 渐变的圆心为元素中点,半径为最长边,不支持设置 | -        |
+| background-clip                                                                	  | 文字渐变,配合`background`背景渐变,设置`background-clip: text` 达到文字渐变效果 | -        |
+| background-image                                                                    | view 元素背景:`url(src)`,若只是设置背景图,请不要设置`background-repeat`                                                                                                                                                           | -        |
+| background-repeat                                                                   | 设置是否及如何重复背景纹理,可选值:`repeat`、`repeat-x`、`repeat-y`、`no-repeat`                                                                                                    | `repeat` |
+| [object-fit](https://developer.mozilla.org/zh-CN/docs/Web/CSS/object-fit/)          | 图片元素适应容器方式,类似于`mode`,可选值:`cover`、 `contain`、 `fill`、 `none`                                                                                                      | -        |
+| [object-position](https://developer.mozilla.org/zh-CN/docs/Web/CSS/object-position) | 图片的对齐方式,配合`object-fit`使用                                                                                                                                                 | -        |
+
+### 图片填充模式 object-fit
+
+| 名称    | 含义                                                   |
+| ------- | ------------------------------------------------------ |
+| contain | 保持宽高缩放图片,使图片的长边能完全显示出来           |
+| cover   | 保持宽高缩放图片,使图片的短边能完全显示出来,裁剪长边 |
+| fill    | 拉伸图片,使图片填满元素                               |
+| none    | 保持图片原有尺寸                                       |
+
+### 事件 Events
+
+| 事件名   | 说明                                                             | 返回值 |
+| -------- | ---------------------------------------------------------------- | ------ |
+| success  | 生成图片成功,若使用`is-canvas-to-temp-filePath` 可以接收图片地址 | path   |
+| fail     | 生成图片失败                                                     | error  |
+| done     | 绘制成功                                                         |        |
+| progress | 绘制进度                                                         | number |
+
+### 暴露函数 Expose
+| 事件名   | 说明                                                             | 返回值 |
+| -------- | ---------------------------------------------------------------- | ------ |
+| render(object)   |  渲染器,传入JSON 绘制海报 | promise   |
+| [canvasToTempFilePath](https://uniapp.dcloud.io/api/canvas/canvasToTempFilePath.html#canvastotempfilepath)(object)   | 把当前画布指定区域的内容导出生成指定大小的图片,并返回文件临时路径。    |   |
+| canvasToTempFilePathSync(object)    | 同步接口,同上                                                         |        |
+
+
+## 常见问题
+
+- 1、H5 端使用网络图片需要解决跨域问题。
+- 2、小程序使用网络图片需要去公众平台增加下载白名单!二级域名也需要配!
+- 3、H5 端生成图片是 base64,有时显示只有一半可以使用原生标签`<IMG/>`
+- 4、发生保存图片倾斜变形或提示 native buffer exceed size limit 时,使用 pixel-ratio="2"参数,降分辨率。
+- 5、h5 保存图片不需要调接口,提示用户长按图片保存。
+- 6、画板不能隐藏,包括`v-if`,`v-show`、`display:none`、`opacity:0`,另外也不要把画板放在弹窗里。如果需要隐藏画板请设置 `custom-style="position: fixed; left: 200%"`
+- 7、微信小程序真机调试请使用 **真机调试2.0**,不支持1.0。
+- 8、微信小程序打开调试时可以生但并闭无法生成时,这种情况一般是没有在公众号配置download域名
+- 9、HBX 3.4.5之前的版本不支持vue3
+- 10、在微信开发工具上 canvas 层级最高无法zindex,并不影响真机
+- 11、请不要导入非uni_modules插件
+- 12、关于QQ小程序 报 Propertyor method"toJSON"is not defined 请把基础库调到 1.50.3
+- 13、支付宝小程序 IDE 不支持 生成图片 请以真机调试结果为准
+- 14、返回值为字符串 `data:,` 大概是尺寸超过限制,设置 pixel-ratio="2"
+- 华为手机 APP 上无法生成图片,请使用 HBX2.9.11++(已过时,忽略这条)
+- IOS APP 请勿使用 HBX2.9.3.20201014 的版本!这个版本无法生成图片。(已过时,忽略这条)
+- 苹果微信 7.0.20 存在闪退和图片无法 onload 为微信 bug(已过时,忽略这条)
+- 微信小程序 IOS 旧接口 如父级设置圆角,子级也设会导致子级的失效,为旧接口BUG。
+- 微信小程序 安卓 旧接口 如使用图片必须加背景色,为旧接口BUG。
+- 微信小程序 安卓端 [图片可能在首次可以加载成功,再次加载会不触发任何事件](https://developers.weixin.qq.com/community/develop/doc/000ee2b8dacf4009337f51f4556800?highLine=canvas%25202d%2520createImage),临时解决方法是给图片加个时间戳
+## 打赏
+
+如果你觉得本插件,解决了你的问题,赠人玫瑰,手留余香。
+
+![](https://testingcf.jsdelivr.net/gh/liangei/image@1.9/alipay.png)
+![](https://testingcf.jsdelivr.net/gh/liangei/image@1.9/wpay.png)

+ 18 - 0
uni_modules/mu-canvas/changelog.md

@@ -0,0 +1,18 @@
+## 1.0.8(2023-11-22)
+修改参数规则
+## 1.0.7(2023-11-16)
+文档名称不符合
+## 1.0.6(2023-11-16)
+文档名称不符合问题
+## 1.0.5(2023-11-15)
+解决微信小程序不能保存文件问题
+## 1.0.4(2023-11-15)
+修改重新加载的方式
+## 1.0.3(2023-11-15)
+整理文档
+## 1.0.2(2023-11-15)
+添加参数默认数据
+## 1.0.1(2023-11-15)
+修改传入图片绘制参数添加sHeight和sWidth
+## 1.0.0(2023-11-15)
+1.0.0 初始化

Diferenças do arquivo suprimidas por serem muito extensas
+ 7 - 0
uni_modules/mu-canvas/components/mu-canvas/mu-canvas.vue


+ 241 - 0
uni_modules/mu-canvas/js_sdk/gcanvas/bridge/bridge-weex.js

@@ -0,0 +1,241 @@
+const isWeex = typeof WXEnvironment !== 'undefined';
+const isWeexIOS = isWeex && /ios/i.test(WXEnvironment.platform);
+const isWeexAndroid = isWeex && !isWeexIOS;
+
+import GLmethod from '../context-webgl/GLmethod';
+
+const GCanvasModule =
+    (typeof weex !== 'undefined' && weex.requireModule) ? (weex.requireModule('gcanvas')) :
+        (typeof __weex_require__ !== 'undefined') ? (__weex_require__('@weex-module/gcanvas')) : {};
+
+let isDebugging = false;
+
+let isComboDisabled = false;
+
+const logCommand = (function () {
+    const methodQuery = [];
+    Object.keys(GLmethod).forEach(key => {
+        methodQuery[GLmethod[key]] = key;
+    })
+    const queryMethod = (id) => {
+        return methodQuery[parseInt(id)] || 'NotFoundMethod';
+    }
+    const logCommand = (id, cmds) => {
+        const mId = cmds.split(',')[0];
+        const mName = queryMethod(mId);
+        console.log(`=== callNative - componentId:${id}; method: ${mName}; cmds: ${cmds}`);
+    }
+    return logCommand;
+})();
+
+function joinArray(arr, sep) {
+    let res = '';
+    for (let i = 0; i < arr.length; i++) {
+        if (i !== 0) {
+            res += sep;
+        }
+        res += arr[i];
+    }
+    return res;
+}
+
+const commandsCache = {}
+
+const GBridge = {
+
+    callEnable: (ref, configArray) => {
+
+        commandsCache[ref] = [];
+
+        return GCanvasModule.enable({
+            componentId: ref,
+            config: configArray
+        });
+    },
+
+    callEnableDebug: () => {
+        isDebugging = true;
+    },
+
+    callEnableDisableCombo: () => {
+        isComboDisabled = true;
+    },
+
+    callSetContextType: function (componentId, context_type) {
+        GCanvasModule.setContextType(context_type, componentId);
+    },
+
+    callReset: function(id){
+        GCanvasModule.resetComponent && canvasModule.resetComponent(componentId);
+    },
+
+    render: isWeexIOS ? function (componentId) {
+        return GCanvasModule.extendCallNative({
+            contextId: componentId,
+            type: 0x60000001
+        });
+    } : function (componentId) {
+        return callGCanvasLinkNative(componentId, 0x60000001, 'render');
+    },
+
+    render2d: isWeexIOS ? function (componentId, commands, callback) {
+
+        if (isDebugging) {
+            console.log('>>> >>> render2d ===');
+            console.log('>>> commands: ' + commands);
+        }
+		
+        GCanvasModule.render([commands, callback?true:false], componentId, callback);
+
+    } : function (componentId, commands,callback) {
+
+        if (isDebugging) {
+            console.log('>>> >>> render2d ===');
+            console.log('>>> commands: ' + commands);
+        }
+
+        callGCanvasLinkNative(componentId, 0x20000001, commands);
+		if(callback){
+		callback();
+		}
+    },
+
+    callExtendCallNative: isWeexIOS ? function (componentId, cmdArgs) {
+
+        throw 'should not be here anymore ' + cmdArgs;
+
+    } : function (componentId, cmdArgs) {
+
+        throw 'should not be here anymore ' + cmdArgs;
+
+    },
+
+
+    flushNative: isWeexIOS ? function (componentId) {
+
+        const cmdArgs = joinArray(commandsCache[componentId], ';');
+        commandsCache[componentId] = [];
+
+        if (isDebugging) {
+            console.log('>>> >>> flush native ===');
+            console.log('>>> commands: ' + cmdArgs);
+        }
+
+        const result = GCanvasModule.extendCallNative({
+            "contextId": componentId,
+            "type": 0x60000000,
+            "args": cmdArgs
+        });
+
+        const res = result && result.result;
+
+        if (isDebugging) {
+            console.log('>>> result: ' + res);
+        }
+
+        return res;
+
+    } : function (componentId) {
+
+        const cmdArgs = joinArray(commandsCache[componentId], ';');
+        commandsCache[componentId] = [];
+
+        if (isDebugging) {
+            console.log('>>> >>> flush native ===');
+            console.log('>>> commands: ' + cmdArgs);
+        }
+
+        const result = callGCanvasLinkNative(componentId, 0x60000000, cmdArgs);
+
+        if (isDebugging) {
+            console.log('>>> result: ' + result);
+        }
+
+        return result;
+    },
+
+    callNative: function (componentId, cmdArgs, cache) {
+
+        if (isDebugging) {
+            logCommand(componentId, cmdArgs);
+        }
+
+        commandsCache[componentId].push(cmdArgs);
+
+        if (!cache || isComboDisabled) {
+            return GBridge.flushNative(componentId);
+        } else {
+            return undefined;
+        }
+    },
+
+    texImage2D(componentId, ...args) {
+        if (isWeexIOS) {
+            if (args.length === 6) {
+                const [target, level, internalformat, format, type, image] = args;
+                GBridge.callNative(
+                    componentId,
+                    GLmethod.texImage2D + ',' + 6 + ',' + target + ',' + level + ',' + internalformat + ',' + format + ',' + type + ',' + image.src
+                )
+            } else if (args.length === 9) {
+                const [target, level, internalformat, width, height, border, format, type, image] = args;
+                GBridge.callNative(
+                    componentId,
+                    GLmethod.texImage2D + ',' + 9 + ',' + target + ',' + level + ',' + internalformat + ',' + width + ',' + height + ',' + border + ',' +
+                    + format + ',' + type + ',' + (image ? image.src : 0)
+                )
+            }
+        } else if (isWeexAndroid) {
+            if (args.length === 6) {
+                const [target, level, internalformat, format, type, image] = args;
+                GCanvasModule.texImage2D(componentId, target, level, internalformat, format, type, image.src);
+            } else if (args.length === 9) {
+                const [target, level, internalformat, width, height, border, format, type, image] = args;
+                GCanvasModule.texImage2D(componentId, target, level, internalformat, width, height, border, format, type, (image ? image.src : 0));
+            }
+        }
+    },
+
+    texSubImage2D(componentId, target, level, xoffset, yoffset, format, type, image) {
+        if (isWeexIOS) {
+            if (arguments.length === 8) {
+                GBridge.callNative(
+                    componentId,
+                    GLmethod.texSubImage2D + ',' + 6 + ',' + target + ',' + level + ',' + xoffset + ',' + yoffset, + ',' + format + ',' + type + ',' + image.src
+                )
+            }
+        } else if (isWeexAndroid) {
+            GCanvasModule.texSubImage2D(componentId, target, level, xoffset, yoffset, format, type, image.src);
+        }
+    },
+
+    bindImageTexture(componentId, src, imageId) {
+        GCanvasModule.bindImageTexture([src, imageId], componentId);
+    },
+
+    perloadImage([url, id], callback) {
+        GCanvasModule.preLoadImage([url, id], function (image) {
+            image.url = url;
+            image.id = id;
+            callback(image);
+        });
+    },
+	
+	measureText(text, fontStyle, componentId) {
+	    return GCanvasModule.measureText([text, fontStyle], componentId);
+	},
+	
+	getImageData (componentId, x, y, w, h, callback) {
+		GCanvasModule.getImageData([x, y,w,h],componentId,callback);
+	},
+	
+	putImageData (componentId, data, x, y, w, h, callback) {
+		GCanvasModule.putImageData([x, y,w,h,data],componentId,callback);
+	},
+	
+	toTempFilePath(componentId, x, y, width, height, destWidth, destHeight, fileType, quality, callback){ 
+		GCanvasModule.toTempFilePath([x, y, width,height, destWidth, destHeight, fileType, quality], componentId, callback);
+	}
+}
+
+export default GBridge;

+ 18 - 0
uni_modules/mu-canvas/js_sdk/gcanvas/context-2d/FillStyleLinearGradient.js

@@ -0,0 +1,18 @@
+class FillStyleLinearGradient {
+
+    constructor(x0, y0, x1, y1) {
+        this._start_pos = { _x: x0, _y: y0 };
+        this._end_pos = { _x: x1, _y: y1 };
+        this._stop_count = 0;
+        this._stops = [0, 0, 0, 0, 0];
+    }
+
+    addColorStop = function (pos, color) {
+        if (this._stop_count < 5 && 0.0 <= pos && pos <= 1.0) {
+            this._stops[this._stop_count] = { _pos: pos, _color: color };
+            this._stop_count++;
+        }
+    }
+}
+
+export default FillStyleLinearGradient;

+ 8 - 0
uni_modules/mu-canvas/js_sdk/gcanvas/context-2d/FillStylePattern.js

@@ -0,0 +1,8 @@
+class FillStylePattern {
+    constructor(img, pattern) {
+        this._style = pattern;
+        this._img = img;
+    }
+}
+
+export default FillStylePattern;

+ 17 - 0
uni_modules/mu-canvas/js_sdk/gcanvas/context-2d/FillStyleRadialGradient.js

@@ -0,0 +1,17 @@
+class FillStyleRadialGradient {
+    constructor(x0, y0, r0, x1, y1, r1) {
+        this._start_pos = { _x: x0, _y: y0, _r: r0 };
+        this._end_pos = { _x: x1, _y: y1, _r: r1 };
+        this._stop_count = 0;
+        this._stops = [0, 0, 0, 0, 0];
+    }
+
+    addColorStop(pos, color) {
+        if (this._stop_count < 5 && 0.0 <= pos && pos <= 1.0) {
+            this._stops[this._stop_count] = { _pos: pos, _color: color };
+            this._stop_count++;
+        }
+    }
+}
+
+export default FillStyleRadialGradient;

+ 666 - 0
uni_modules/mu-canvas/js_sdk/gcanvas/context-2d/RenderingContext.js

@@ -0,0 +1,666 @@
+import FillStylePattern from './FillStylePattern';
+import FillStyleLinearGradient from './FillStyleLinearGradient';
+import FillStyleRadialGradient from './FillStyleRadialGradient';
+import GImage from '../env/image.js';
+import {
+	ArrayBufferToBase64,
+	Base64ToUint8ClampedArray
+} from '../env/tool.js';
+
+export default class CanvasRenderingContext2D {
+
+	_drawCommands = '';
+
+	_globalAlpha = 1.0;
+
+	_fillStyle = 'rgb(0,0,0)';
+	_strokeStyle = 'rgb(0,0,0)';
+
+	_lineWidth = 1;
+	_lineCap = 'butt';
+	_lineJoin = 'miter';
+
+	_miterLimit = 10;
+
+	_globalCompositeOperation = 'source-over';
+
+	_textAlign = 'start';
+	_textBaseline = 'alphabetic';
+
+	_font = '10px sans-serif';
+
+	_savedGlobalAlpha = [];
+
+	timer = null;
+	componentId = null;
+
+	_notCommitDrawImageCache = [];
+	_needRedrawImageCache = [];
+	_redrawCommands = '';
+	_autoSaveContext = true;
+	// _imageMap = new GHashMap();
+	// _textureMap = new GHashMap();
+
+	constructor() {
+		this.className = 'CanvasRenderingContext2D';
+		//this.save()
+	}
+
+	setFillStyle(value) {
+		this.fillStyle = value;
+	}
+
+	set fillStyle(value) {
+		this._fillStyle = value;
+
+		if (typeof(value) == 'string') {
+			this._drawCommands = this._drawCommands.concat("F" + value + ";");
+		} else if (value instanceof FillStylePattern) {
+			const image = value._img;
+			if (!image.complete) {
+				image.onload = () => {
+					var index = this._needRedrawImageCache.indexOf(image);
+					if (index > -1) {
+						this._needRedrawImageCache.splice(index, 1);
+						CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
+						this._redrawflush(true);
+					}
+				}
+				this._notCommitDrawImageCache.push(image);
+			} else {
+				CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
+			}
+
+			//CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
+			this._drawCommands = this._drawCommands.concat("G" + image._id + "," + value._style + ";");
+		} else if (value instanceof FillStyleLinearGradient) {
+			var command = "D" + value._start_pos._x.toFixed(2) + "," + value._start_pos._y.toFixed(2) + "," +
+				value._end_pos._x.toFixed(2) + "," + value._end_pos._y.toFixed(2) + "," +
+				value._stop_count;
+			for (var i = 0; i < value._stop_count; ++i) {
+				command += ("," + value._stops[i]._pos + "," + value._stops[i]._color);
+			}
+			this._drawCommands = this._drawCommands.concat(command + ";");
+		} else if (value instanceof FillStyleRadialGradient) {
+			var command = "H" + value._start_pos._x.toFixed(2) + "," + value._start_pos._y.toFixed(2) + "," + value._start_pos._r
+				.toFixed(2) + "," +
+				value._end_pos._x.toFixed(2) + "," + value._end_pos._y.toFixed(2) + "," + value._end_pos._r.toFixed(2) + "," +
+				value._stop_count;
+			for (var i = 0; i < value._stop_count; ++i) {
+				command += ("," + value._stops[i]._pos + "," + value._stops[i]._color);
+			}
+			this._drawCommands = this._drawCommands.concat(command + ";");
+		}
+	}
+
+	get fillStyle() {
+		return this._fillStyle;
+	}
+
+	get globalAlpha() {
+		return this._globalAlpha;
+	}
+
+	setGlobalAlpha(value) {
+		this.globalAlpha = value;
+	}
+
+	set globalAlpha(value) {
+		this._globalAlpha = value;
+		this._drawCommands = this._drawCommands.concat("a" + value.toFixed(2) + ";");
+	}
+
+
+	get strokeStyle() {
+		return this._strokeStyle;
+	}
+
+	setStrokeStyle(value) {
+		this.strokeStyle = value;
+	}
+
+	set strokeStyle(value) {
+
+		this._strokeStyle = value;
+
+		if (typeof(value) == 'string') {
+			this._drawCommands = this._drawCommands.concat("S" + value + ";");
+		} else if (value instanceof FillStylePattern) {
+			CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
+			this._drawCommands = this._drawCommands.concat("G" + image._id + "," + value._style + ";");
+		} else if (value instanceof FillStyleLinearGradient) {
+			var command = "D" + value._start_pos._x.toFixed(2) + "," + value._start_pos._y.toFixed(2) + "," +
+				value._end_pos._x.toFixed(2) + "," + value._end_pos._y.toFixed(2) + "," +
+				value._stop_count;
+
+			for (var i = 0; i < value._stop_count; ++i) {
+				command += ("," + value._stops[i]._pos + "," + value._stops[i]._color);
+			}
+			this._drawCommands = this._drawCommands.concat(command + ";");
+		} else if (value instanceof FillStyleRadialGradient) {
+			var command = "H" + value._start_pos._x.toFixed(2) + "," + value._start_pos._y.toFixed(2) + "," + value._start_pos._r
+				.toFixed(2) + "," +
+				value._end_pos._x.toFixed(2) + "," + value._end_pos._y + ",".toFixed(2) + value._end_pos._r.toFixed(2) + "," +
+				value._stop_count;
+
+			for (var i = 0; i < value._stop_count; ++i) {
+				command += ("," + value._stops[i]._pos + "," + value._stops[i]._color);
+			}
+			this._drawCommands = this._drawCommands.concat(command + ";");
+		}
+	}
+
+	get lineWidth() {
+		return this._lineWidth;
+	}
+
+	setLineWidth(value) {
+		this.lineWidth = value;
+	}
+
+	set lineWidth(value) {
+		this._lineWidth = value;
+		this._drawCommands = this._drawCommands.concat("W" + value + ";");
+	}
+
+	get lineCap() {
+		return this._lineCap;
+	}
+
+	setLineCap(value) {
+		this.lineCap = value;
+	}
+
+	set lineCap(value) {
+		this._lineCap = value;
+		this._drawCommands = this._drawCommands.concat("C" + value + ";");
+	}
+
+	get lineJoin() {
+		return this._lineJoin;
+	}
+
+	setLineJoin(value) {
+		this.lineJoin = value
+	}
+
+	set lineJoin(value) {
+		this._lineJoin = value;
+		this._drawCommands = this._drawCommands.concat("J" + value + ";");
+	}
+
+	get miterLimit() {
+		return this._miterLimit;
+	}
+
+	setMiterLimit(value) {
+		this.miterLimit = value
+	}
+
+	set miterLimit(value) {
+		this._miterLimit = value;
+		this._drawCommands = this._drawCommands.concat("M" + value + ";");
+	}
+
+	get globalCompositeOperation() {
+		return this._globalCompositeOperation;
+	}
+
+	set globalCompositeOperation(value) {
+
+		this._globalCompositeOperation = value;
+		let mode = 0;
+		switch (value) {
+			case "source-over":
+				mode = 0;
+				break;
+			case "source-atop":
+				mode = 5;
+				break;
+			case "source-in":
+				mode = 0;
+				break;
+			case "source-out":
+				mode = 2;
+				break;
+			case "destination-over":
+				mode = 4;
+				break;
+			case "destination-atop":
+				mode = 4;
+				break;
+			case "destination-in":
+				mode = 4;
+				break;
+			case "destination-out":
+				mode = 3;
+				break;
+			case "lighter":
+				mode = 1;
+				break;
+			case "copy":
+				mode = 2;
+				break;
+			case "xor":
+				mode = 6;
+				break;
+			default:
+				mode = 0;
+		}
+
+		this._drawCommands = this._drawCommands.concat("B" + mode + ";");
+	}
+
+	get textAlign() {
+		return this._textAlign;
+	}
+
+	setTextAlign(value) {
+		this.textAlign = value
+	}
+
+	set textAlign(value) {
+
+		this._textAlign = value;
+		let Align = 0;
+		switch (value) {
+			case "start":
+				Align = 0;
+				break;
+			case "end":
+				Align = 1;
+				break;
+			case "left":
+				Align = 2;
+				break;
+			case "center":
+				Align = 3;
+				break;
+			case "right":
+				Align = 4;
+				break;
+			default:
+				Align = 0;
+		}
+
+		this._drawCommands = this._drawCommands.concat("A" + Align + ";");
+	}
+
+	get textBaseline() {
+		return this._textBaseline;
+	}
+
+	setTextBaseline(value) {
+		this.textBaseline = value
+	}
+
+	set textBaseline(value) {
+		this._textBaseline = value;
+		let baseline = 0;
+		switch (value) {
+			case "alphabetic":
+				baseline = 0;
+				break;
+			case "middle":
+				baseline = 1;
+				break;
+			case "top":
+				baseline = 2;
+				break;
+			case "hanging":
+				baseline = 3;
+				break;
+			case "bottom":
+				baseline = 4;
+				break;
+			case "ideographic":
+				baseline = 5;
+				break;
+			default:
+				baseline = 0;
+				break;
+		}
+
+		this._drawCommands = this._drawCommands.concat("E" + baseline + ";");
+	}
+
+	get font() {
+		return this._font;
+	}
+
+	setFontSize(size) {
+		var str = this._font;
+		var strs = str.trim().split(/\s+/);
+		for (var i = 0; i < strs.length; i++) {
+			var values = ["normal", "italic", "oblique", "normal", "small-caps", "normal", "bold",
+				"bolder", "lighter", "100", "200", "300", "400", "500", "600", "700", "800", "900",
+				"normal", "ultra-condensed", "extra-condensed", "condensed", "semi-condensed",
+				"semi-expanded", "expanded", "extra-expanded", "ultra-expanded"
+			];
+
+			if (-1 == values.indexOf(strs[i].trim())) {
+				if (typeof size === 'string') {
+					strs[i] = size;
+				} else if (typeof size === 'number') {
+					strs[i] = String(size) + 'px';
+				}
+				break;
+			}
+		}
+		this.font = strs.join(" ");
+	}
+
+	set font(value) {
+		this._font = value;
+		this._drawCommands = this._drawCommands.concat("j" + value + ";");
+	}
+
+	setTransform(a, b, c, d, tx, ty) {
+		this._drawCommands = this._drawCommands.concat("t" +
+			(a === 1 ? "1" : a.toFixed(2)) + "," +
+			(b === 0 ? "0" : b.toFixed(2)) + "," +
+			(c === 0 ? "0" : c.toFixed(2)) + "," +
+			(d === 1 ? "1" : d.toFixed(2)) + "," + tx.toFixed(2) + "," + ty.toFixed(2) + ";");
+	}
+
+	transform(a, b, c, d, tx, ty) {
+		this._drawCommands = this._drawCommands.concat("f" +
+			(a === 1 ? "1" : a.toFixed(2)) + "," +
+			(b === 0 ? "0" : b.toFixed(2)) + "," +
+			(c === 0 ? "0" : c.toFixed(2)) + "," +
+			(d === 1 ? "1" : d.toFixed(2)) + "," + tx + "," + ty + ";");
+	}
+
+	resetTransform() {
+		this._drawCommands = this._drawCommands.concat("m;");
+	}
+
+	scale(a, d) {
+		this._drawCommands = this._drawCommands.concat("k" + a.toFixed(2) + "," +
+			d.toFixed(2) + ";");
+	}
+
+	rotate(angle) {
+		this._drawCommands = this._drawCommands
+			.concat("r" + angle.toFixed(6) + ";");
+	}
+
+	translate(tx, ty) {
+		this._drawCommands = this._drawCommands.concat("l" + tx.toFixed(2) + "," + ty.toFixed(2) + ";");
+	}
+
+	save() {
+		this._savedGlobalAlpha.push(this._globalAlpha);
+		this._drawCommands = this._drawCommands.concat("v;");
+	}
+
+	restore() {
+		this._drawCommands = this._drawCommands.concat("e;");
+		this._globalAlpha = this._savedGlobalAlpha.pop();
+	}
+
+	createPattern(img, pattern) {
+		if (typeof img === 'string') {
+			var imgObj = new GImage();
+			imgObj.src = img;
+			img = imgObj;
+		}
+		return new FillStylePattern(img, pattern);
+	}
+
+	createLinearGradient(x0, y0, x1, y1) {
+		return new FillStyleLinearGradient(x0, y0, x1, y1);
+	}
+
+	createRadialGradient = function(x0, y0, r0, x1, y1, r1) {
+		return new FillStyleRadialGradient(x0, y0, r0, x1, y1, r1);
+	};
+
+	createCircularGradient = function(x0, y0, r0) {
+		return new FillStyleRadialGradient(x0, y0, 0, x0, y0, r0);
+	};
+
+	strokeRect(x, y, w, h) {
+		this._drawCommands = this._drawCommands.concat("s" + x + "," + y + "," + w + "," + h + ";");
+	}
+
+
+	clearRect(x, y, w, h) {
+		this._drawCommands = this._drawCommands.concat("c" + x + "," + y + "," + w +
+			"," + h + ";");
+	}
+
+	clip() {
+		this._drawCommands = this._drawCommands.concat("p;");
+	}
+
+	resetClip() {
+		this._drawCommands = this._drawCommands.concat("q;");
+	}
+
+	closePath() {
+		this._drawCommands = this._drawCommands.concat("o;");
+	}
+
+	moveTo(x, y) {
+		this._drawCommands = this._drawCommands.concat("g" + x.toFixed(2) + "," + y.toFixed(2) + ";");
+	}
+
+	lineTo(x, y) {
+		this._drawCommands = this._drawCommands.concat("i" + x.toFixed(2) + "," + y.toFixed(2) + ";");
+	}
+
+	quadraticCurveTo = function(cpx, cpy, x, y) {
+		this._drawCommands = this._drawCommands.concat("u" + cpx + "," + cpy + "," + x + "," + y + ";");
+	}
+
+	bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y, ) {
+		this._drawCommands = this._drawCommands.concat(
+			"z" + cp1x.toFixed(2) + "," + cp1y.toFixed(2) + "," + cp2x.toFixed(2) + "," + cp2y.toFixed(2) + "," +
+			x.toFixed(2) + "," + y.toFixed(2) + ";");
+	}
+
+	arcTo(x1, y1, x2, y2, radius) {
+		this._drawCommands = this._drawCommands.concat("h" + x1 + "," + y1 + "," + x2 + "," + y2 + "," + radius + ";");
+	}
+
+	beginPath() {
+		this._drawCommands = this._drawCommands.concat("b;");
+	}
+
+
+	fillRect(x, y, w, h) {
+		this._drawCommands = this._drawCommands.concat("n" + x + "," + y + "," + w +
+			"," + h + ";");
+	}
+
+	rect(x, y, w, h) {
+		this._drawCommands = this._drawCommands.concat("w" + x + "," + y + "," + w + "," + h + ";");
+	}
+
+	fill() {
+		this._drawCommands = this._drawCommands.concat("L;");
+	}
+
+	stroke(path) {
+		this._drawCommands = this._drawCommands.concat("x;");
+	}
+
+	arc(x, y, radius, startAngle, endAngle, anticlockwise) {
+
+		let ianticlockwise = 0;
+		if (anticlockwise) {
+			ianticlockwise = 1;
+		}
+
+		this._drawCommands = this._drawCommands.concat(
+			"y" + x.toFixed(2) + "," + y.toFixed(2) + "," +
+			radius.toFixed(2) + "," + startAngle + "," + endAngle + "," + ianticlockwise +
+			";"
+		);
+	}
+
+	fillText(text, x, y) {
+		let tmptext = text.replace(/!/g, "!!");
+		tmptext = tmptext.replace(/,/g, "!,");
+		tmptext = tmptext.replace(/;/g, "!;");
+		this._drawCommands = this._drawCommands.concat("T" + tmptext + "," + x + "," + y + ",0.0;");
+	}
+
+	strokeText = function(text, x, y) {
+		let tmptext = text.replace(/!/g, "!!");
+		tmptext = tmptext.replace(/,/g, "!,");
+		tmptext = tmptext.replace(/;/g, "!;");
+		this._drawCommands = this._drawCommands.concat("U" + tmptext + "," + x + "," + y + ",0.0;");
+	}
+
+	measureText(text) {
+		return CanvasRenderingContext2D.GBridge.measureText(text, this.font, this.componentId);
+	}
+
+	isPointInPath = function(x, y) {
+		throw new Error('GCanvas not supported yet');
+	}
+
+	drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh) {
+		if (typeof image === 'string') {
+			var imgObj = new GImage();
+			imgObj.src = image;
+			image = imgObj;
+		}
+		if (image instanceof GImage) {
+			if (!image.complete) {
+				imgObj.onload = () => {
+					var index = this._needRedrawImageCache.indexOf(image);
+					if (index > -1) {
+						this._needRedrawImageCache.splice(index, 1);
+						CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
+						this._redrawflush(true);
+					}
+				}
+				this._notCommitDrawImageCache.push(image);
+			} else {
+				CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
+			}
+			var srcArgs = [image, sx, sy, sw, sh, dx, dy, dw, dh];
+			var args = [];
+			for (var arg in srcArgs) {
+				if (typeof(srcArgs[arg]) != 'undefined') {
+					args.push(srcArgs[arg]);
+				}
+			}
+			this.__drawImage.apply(this, args);
+			//this.__drawImage(image,sx, sy, sw, sh, dx, dy, dw, dh);
+		}
+	}
+
+	__drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh) {
+		const numArgs = arguments.length;
+
+		function drawImageCommands() {
+
+			if (numArgs === 3) {
+				const x = parseFloat(sx) || 0.0;
+				const y = parseFloat(sy) || 0.0;
+
+				return ("d" + image._id + ",0,0," +
+					image.width + "," + image.height + "," +
+					x + "," + y + "," + image.width + "," + image.height + ";");
+			} else if (numArgs === 5) {
+				const x = parseFloat(sx) || 0.0;
+				const y = parseFloat(sy) || 0.0;
+				const width = parseInt(sw) || image.width;
+				const height = parseInt(sh) || image.height;
+
+				return ("d" + image._id + ",0,0," +
+					image.width + "," + image.height + "," +
+					x + "," + y + "," + width + "," + height + ";");
+			} else if (numArgs === 9) {
+				sx = parseFloat(sx) || 0.0;
+				sy = parseFloat(sy) || 0.0;
+				sw = parseInt(sw) || image.width;
+				sh = parseInt(sh) || image.height;
+				dx = parseFloat(dx) || 0.0;
+				dy = parseFloat(dy) || 0.0;
+				dw = parseInt(dw) || image.width;
+				dh = parseInt(dh) || image.height;
+
+				return ("d" + image._id + "," +
+					sx + "," + sy + "," + sw + "," + sh + "," +
+					dx + "," + dy + "," + dw + "," + dh + ";");
+			}
+		}
+		this._drawCommands += drawImageCommands();
+	}
+
+	_flush(reserve, callback) {
+		const commands = this._drawCommands;
+		this._drawCommands = '';
+		CanvasRenderingContext2D.GBridge.render2d(this.componentId, commands, callback);
+		this._needRender = false;
+	}
+
+	_redrawflush(reserve, callback) {
+		const commands = this._redrawCommands;
+		CanvasRenderingContext2D.GBridge.render2d(this.componentId, commands, callback);
+		if (this._needRedrawImageCache.length == 0) {
+			this._redrawCommands = '';
+		}
+	}
+
+	draw(reserve, callback) {
+		if (!reserve) {
+			this._globalAlpha = this._savedGlobalAlpha.pop();
+			this._savedGlobalAlpha.push(this._globalAlpha);
+			this._redrawCommands = this._drawCommands;
+			this._needRedrawImageCache = this._notCommitDrawImageCache;
+			if (this._autoSaveContext) {
+				this._drawCommands = ("v;" + this._drawCommands);
+				this._autoSaveContext = false;
+			} else {
+				this._drawCommands = ("e;X;v;" + this._drawCommands);
+			}
+		} else {
+			this._needRedrawImageCache = this._needRedrawImageCache.concat(this._notCommitDrawImageCache);
+			this._redrawCommands += this._drawCommands;
+			if (this._autoSaveContext) {
+				this._drawCommands = ("v;" + this._drawCommands);
+				this._autoSaveContext = false;
+			}
+		}
+		this._notCommitDrawImageCache = [];
+		if (this._flush) {
+			this._flush(reserve, callback);
+		}
+	}
+
+	getImageData(x, y, w, h, callback) {
+		CanvasRenderingContext2D.GBridge.getImageData(this.componentId, x, y, w, h, function(res) {
+			res.data = Base64ToUint8ClampedArray(res.data);
+			if (typeof(callback) == 'function') {
+				callback(res);
+			}
+		});
+	}
+
+	putImageData(data, x, y, w, h, callback) {
+		if (data instanceof Uint8ClampedArray) {
+			data = ArrayBufferToBase64(data);
+			CanvasRenderingContext2D.GBridge.putImageData(this.componentId, data, x, y, w, h, function(res) {
+				if (typeof(callback) == 'function') {
+					callback(res);
+				}
+			});
+		}
+	}
+
+	toTempFilePath(x, y, width, height, destWidth, destHeight, fileType, quality, callback) {
+		CanvasRenderingContext2D.GBridge.toTempFilePath(this.componentId, x, y, width, height, destWidth, destHeight,
+			fileType, quality,
+			function(res) {
+				if (typeof(callback) == 'function') {
+					callback(res);
+				}
+			});
+	}
+}

+ 11 - 0
uni_modules/mu-canvas/js_sdk/gcanvas/context-webgl/ActiveInfo.js

@@ -0,0 +1,11 @@
+export default class WebGLActiveInfo {
+    className = 'WebGLActiveInfo';
+
+    constructor({
+        type, name, size
+    }) {
+        this.type = type;
+        this.name = name;
+        this.size = size;
+    }
+}

+ 21 - 0
uni_modules/mu-canvas/js_sdk/gcanvas/context-webgl/Buffer.js

@@ -0,0 +1,21 @@
+import {getTransferedObjectUUID} from './classUtils';
+
+const name = 'WebGLBuffer';
+
+function uuid(id) {
+    return getTransferedObjectUUID(name, id);
+}
+
+export default class WebGLBuffer {
+    className = name;
+
+    constructor(id) {
+        this.id = id;
+    }
+
+    static uuid = uuid;
+
+    uuid() {
+        return uuid(this.id);
+    }
+}

+ 21 - 0
uni_modules/mu-canvas/js_sdk/gcanvas/context-webgl/Framebuffer.js

@@ -0,0 +1,21 @@
+import {getTransferedObjectUUID} from './classUtils';
+
+const name = 'WebGLFrameBuffer';
+
+function uuid(id) {
+    return getTransferedObjectUUID(name, id);
+}
+
+export default class WebGLFramebuffer {
+    className = name;
+
+    constructor(id) {
+        this.id = id;
+    }
+
+    static uuid = uuid;
+
+    uuid() {
+        return uuid(this.id);
+    }
+}

+ 298 - 0
uni_modules/mu-canvas/js_sdk/gcanvas/context-webgl/GLenum.js

@@ -0,0 +1,298 @@
+export default {
+    "DEPTH_BUFFER_BIT": 256,
+    "STENCIL_BUFFER_BIT": 1024,
+    "COLOR_BUFFER_BIT": 16384,
+    "POINTS": 0,
+    "LINES": 1,
+    "LINE_LOOP": 2,
+    "LINE_STRIP": 3,
+    "TRIANGLES": 4,
+    "TRIANGLE_STRIP": 5,
+    "TRIANGLE_FAN": 6,
+    "ZERO": 0,
+    "ONE": 1,
+    "SRC_COLOR": 768,
+    "ONE_MINUS_SRC_COLOR": 769,
+    "SRC_ALPHA": 770,
+    "ONE_MINUS_SRC_ALPHA": 771,
+    "DST_ALPHA": 772,
+    "ONE_MINUS_DST_ALPHA": 773,
+    "DST_COLOR": 774,
+    "ONE_MINUS_DST_COLOR": 775,
+    "SRC_ALPHA_SATURATE": 776,
+    "FUNC_ADD": 32774,
+    "BLEND_EQUATION": 32777,
+    "BLEND_EQUATION_RGB": 32777,
+    "BLEND_EQUATION_ALPHA": 34877,
+    "FUNC_SUBTRACT": 32778,
+    "FUNC_REVERSE_SUBTRACT": 32779,
+    "BLEND_DST_RGB": 32968,
+    "BLEND_SRC_RGB": 32969,
+    "BLEND_DST_ALPHA": 32970,
+    "BLEND_SRC_ALPHA": 32971,
+    "CONSTANT_COLOR": 32769,
+    "ONE_MINUS_CONSTANT_COLOR": 32770,
+    "CONSTANT_ALPHA": 32771,
+    "ONE_MINUS_CONSTANT_ALPHA": 32772,
+    "BLEND_COLOR": 32773,
+    "ARRAY_BUFFER": 34962,
+    "ELEMENT_ARRAY_BUFFER": 34963,
+    "ARRAY_BUFFER_BINDING": 34964,
+    "ELEMENT_ARRAY_BUFFER_BINDING": 34965,
+    "STREAM_DRAW": 35040,
+    "STATIC_DRAW": 35044,
+    "DYNAMIC_DRAW": 35048,
+    "BUFFER_SIZE": 34660,
+    "BUFFER_USAGE": 34661,
+    "CURRENT_VERTEX_ATTRIB": 34342,
+    "FRONT": 1028,
+    "BACK": 1029,
+    "FRONT_AND_BACK": 1032,
+    "TEXTURE_2D": 3553,
+    "CULL_FACE": 2884,
+    "BLEND": 3042,
+    "DITHER": 3024,
+    "STENCIL_TEST": 2960,
+    "DEPTH_TEST": 2929,
+    "SCISSOR_TEST": 3089,
+    "POLYGON_OFFSET_FILL": 32823,
+    "SAMPLE_ALPHA_TO_COVERAGE": 32926,
+    "SAMPLE_COVERAGE": 32928,
+    "NO_ERROR": 0,
+    "INVALID_ENUM": 1280,
+    "INVALID_VALUE": 1281,
+    "INVALID_OPERATION": 1282,
+    "OUT_OF_MEMORY": 1285,
+    "CW": 2304,
+    "CCW": 2305,
+    "LINE_WIDTH": 2849,
+    "ALIASED_POINT_SIZE_RANGE": 33901,
+    "ALIASED_LINE_WIDTH_RANGE": 33902,
+    "CULL_FACE_MODE": 2885,
+    "FRONT_FACE": 2886,
+    "DEPTH_RANGE": 2928,
+    "DEPTH_WRITEMASK": 2930,
+    "DEPTH_CLEAR_VALUE": 2931,
+    "DEPTH_FUNC": 2932,
+    "STENCIL_CLEAR_VALUE": 2961,
+    "STENCIL_FUNC": 2962,
+    "STENCIL_FAIL": 2964,
+    "STENCIL_PASS_DEPTH_FAIL": 2965,
+    "STENCIL_PASS_DEPTH_PASS": 2966,
+    "STENCIL_REF": 2967,
+    "STENCIL_VALUE_MASK": 2963,
+    "STENCIL_WRITEMASK": 2968,
+    "STENCIL_BACK_FUNC": 34816,
+    "STENCIL_BACK_FAIL": 34817,
+    "STENCIL_BACK_PASS_DEPTH_FAIL": 34818,
+    "STENCIL_BACK_PASS_DEPTH_PASS": 34819,
+    "STENCIL_BACK_REF": 36003,
+    "STENCIL_BACK_VALUE_MASK": 36004,
+    "STENCIL_BACK_WRITEMASK": 36005,
+    "VIEWPORT": 2978,
+    "SCISSOR_BOX": 3088,
+    "COLOR_CLEAR_VALUE": 3106,
+    "COLOR_WRITEMASK": 3107,
+    "UNPACK_ALIGNMENT": 3317,
+    "PACK_ALIGNMENT": 3333,
+    "MAX_TEXTURE_SIZE": 3379,
+    "MAX_VIEWPORT_DIMS": 3386,
+    "SUBPIXEL_BITS": 3408,
+    "RED_BITS": 3410,
+    "GREEN_BITS": 3411,
+    "BLUE_BITS": 3412,
+    "ALPHA_BITS": 3413,
+    "DEPTH_BITS": 3414,
+    "STENCIL_BITS": 3415,
+    "POLYGON_OFFSET_UNITS": 10752,
+    "POLYGON_OFFSET_FACTOR": 32824,
+    "TEXTURE_BINDING_2D": 32873,
+    "SAMPLE_BUFFERS": 32936,
+    "SAMPLES": 32937,
+    "SAMPLE_COVERAGE_VALUE": 32938,
+    "SAMPLE_COVERAGE_INVERT": 32939,
+    "COMPRESSED_TEXTURE_FORMATS": 34467,
+    "DONT_CARE": 4352,
+    "FASTEST": 4353,
+    "NICEST": 4354,
+    "GENERATE_MIPMAP_HINT": 33170,
+    "BYTE": 5120,
+    "UNSIGNED_BYTE": 5121,
+    "SHORT": 5122,
+    "UNSIGNED_SHORT": 5123,
+    "INT": 5124,
+    "UNSIGNED_INT": 5125,
+    "FLOAT": 5126,
+    "DEPTH_COMPONENT": 6402,
+    "ALPHA": 6406,
+    "RGB": 6407,
+    "RGBA": 6408,
+    "LUMINANCE": 6409,
+    "LUMINANCE_ALPHA": 6410,
+    "UNSIGNED_SHORT_4_4_4_4": 32819,
+    "UNSIGNED_SHORT_5_5_5_1": 32820,
+    "UNSIGNED_SHORT_5_6_5": 33635,
+    "FRAGMENT_SHADER": 35632,
+    "VERTEX_SHADER": 35633,
+    "MAX_VERTEX_ATTRIBS": 34921,
+    "MAX_VERTEX_UNIFORM_VECTORS": 36347,
+    "MAX_VARYING_VECTORS": 36348,
+    "MAX_COMBINED_TEXTURE_IMAGE_UNITS": 35661,
+    "MAX_VERTEX_TEXTURE_IMAGE_UNITS": 35660,
+    "MAX_TEXTURE_IMAGE_UNITS": 34930,
+    "MAX_FRAGMENT_UNIFORM_VECTORS": 36349,
+    "SHADER_TYPE": 35663,
+    "DELETE_STATUS": 35712,
+    "LINK_STATUS": 35714,
+    "VALIDATE_STATUS": 35715,
+    "ATTACHED_SHADERS": 35717,
+    "ACTIVE_UNIFORMS": 35718,
+    "ACTIVE_ATTRIBUTES": 35721,
+    "SHADING_LANGUAGE_VERSION": 35724,
+    "CURRENT_PROGRAM": 35725,
+    "NEVER": 512,
+    "LESS": 513,
+    "EQUAL": 514,
+    "LEQUAL": 515,
+    "GREATER": 516,
+    "NOTEQUAL": 517,
+    "GEQUAL": 518,
+    "ALWAYS": 519,
+    "KEEP": 7680,
+    "REPLACE": 7681,
+    "INCR": 7682,
+    "DECR": 7683,
+    "INVERT": 5386,
+    "INCR_WRAP": 34055,
+    "DECR_WRAP": 34056,
+    "VENDOR": 7936,
+    "RENDERER": 7937,
+    "VERSION": 7938,
+    "NEAREST": 9728,
+    "LINEAR": 9729,
+    "NEAREST_MIPMAP_NEAREST": 9984,
+    "LINEAR_MIPMAP_NEAREST": 9985,
+    "NEAREST_MIPMAP_LINEAR": 9986,
+    "LINEAR_MIPMAP_LINEAR": 9987,
+    "TEXTURE_MAG_FILTER": 10240,
+    "TEXTURE_MIN_FILTER": 10241,
+    "TEXTURE_WRAP_S": 10242,
+    "TEXTURE_WRAP_T": 10243,
+    "TEXTURE": 5890,
+    "TEXTURE_CUBE_MAP": 34067,
+    "TEXTURE_BINDING_CUBE_MAP": 34068,
+    "TEXTURE_CUBE_MAP_POSITIVE_X": 34069,
+    "TEXTURE_CUBE_MAP_NEGATIVE_X": 34070,
+    "TEXTURE_CUBE_MAP_POSITIVE_Y": 34071,
+    "TEXTURE_CUBE_MAP_NEGATIVE_Y": 34072,
+    "TEXTURE_CUBE_MAP_POSITIVE_Z": 34073,
+    "TEXTURE_CUBE_MAP_NEGATIVE_Z": 34074,
+    "MAX_CUBE_MAP_TEXTURE_SIZE": 34076,
+    "TEXTURE0": 33984,
+    "TEXTURE1": 33985,
+    "TEXTURE2": 33986,
+    "TEXTURE3": 33987,
+    "TEXTURE4": 33988,
+    "TEXTURE5": 33989,
+    "TEXTURE6": 33990,
+    "TEXTURE7": 33991,
+    "TEXTURE8": 33992,
+    "TEXTURE9": 33993,
+    "TEXTURE10": 33994,
+    "TEXTURE11": 33995,
+    "TEXTURE12": 33996,
+    "TEXTURE13": 33997,
+    "TEXTURE14": 33998,
+    "TEXTURE15": 33999,
+    "TEXTURE16": 34000,
+    "TEXTURE17": 34001,
+    "TEXTURE18": 34002,
+    "TEXTURE19": 34003,
+    "TEXTURE20": 34004,
+    "TEXTURE21": 34005,
+    "TEXTURE22": 34006,
+    "TEXTURE23": 34007,
+    "TEXTURE24": 34008,
+    "TEXTURE25": 34009,
+    "TEXTURE26": 34010,
+    "TEXTURE27": 34011,
+    "TEXTURE28": 34012,
+    "TEXTURE29": 34013,
+    "TEXTURE30": 34014,
+    "TEXTURE31": 34015,
+    "ACTIVE_TEXTURE": 34016,
+    "REPEAT": 10497,
+    "CLAMP_TO_EDGE": 33071,
+    "MIRRORED_REPEAT": 33648,
+    "FLOAT_VEC2": 35664,
+    "FLOAT_VEC3": 35665,
+    "FLOAT_VEC4": 35666,
+    "INT_VEC2": 35667,
+    "INT_VEC3": 35668,
+    "INT_VEC4": 35669,
+    "BOOL": 35670,
+    "BOOL_VEC2": 35671,
+    "BOOL_VEC3": 35672,
+    "BOOL_VEC4": 35673,
+    "FLOAT_MAT2": 35674,
+    "FLOAT_MAT3": 35675,
+    "FLOAT_MAT4": 35676,
+    "SAMPLER_2D": 35678,
+    "SAMPLER_CUBE": 35680,
+    "VERTEX_ATTRIB_ARRAY_ENABLED": 34338,
+    "VERTEX_ATTRIB_ARRAY_SIZE": 34339,
+    "VERTEX_ATTRIB_ARRAY_STRIDE": 34340,
+    "VERTEX_ATTRIB_ARRAY_TYPE": 34341,
+    "VERTEX_ATTRIB_ARRAY_NORMALIZED": 34922,
+    "VERTEX_ATTRIB_ARRAY_POINTER": 34373,
+    "VERTEX_ATTRIB_ARRAY_BUFFER_BINDING": 34975,
+    "IMPLEMENTATION_COLOR_READ_TYPE": 35738,
+    "IMPLEMENTATION_COLOR_READ_FORMAT": 35739,
+    "COMPILE_STATUS": 35713,
+    "LOW_FLOAT": 36336,
+    "MEDIUM_FLOAT": 36337,
+    "HIGH_FLOAT": 36338,
+    "LOW_INT": 36339,
+    "MEDIUM_INT": 36340,
+    "HIGH_INT": 36341,
+    "FRAMEBUFFER": 36160,
+    "RENDERBUFFER": 36161,
+    "RGBA4": 32854,
+    "RGB5_A1": 32855,
+    "RGB565": 36194,
+    "DEPTH_COMPONENT16": 33189,
+    "STENCIL_INDEX8": 36168,
+    "DEPTH_STENCIL": 34041,
+    "RENDERBUFFER_WIDTH": 36162,
+    "RENDERBUFFER_HEIGHT": 36163,
+    "RENDERBUFFER_INTERNAL_FORMAT": 36164,
+    "RENDERBUFFER_RED_SIZE": 36176,
+    "RENDERBUFFER_GREEN_SIZE": 36177,
+    "RENDERBUFFER_BLUE_SIZE": 36178,
+    "RENDERBUFFER_ALPHA_SIZE": 36179,
+    "RENDERBUFFER_DEPTH_SIZE": 36180,
+    "RENDERBUFFER_STENCIL_SIZE": 36181,
+    "FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE": 36048,
+    "FRAMEBUFFER_ATTACHMENT_OBJECT_NAME": 36049,
+    "FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL": 36050,
+    "FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE": 36051,
+    "COLOR_ATTACHMENT0": 36064,
+    "DEPTH_ATTACHMENT": 36096,
+    "STENCIL_ATTACHMENT": 36128,
+    "DEPTH_STENCIL_ATTACHMENT": 33306,
+    "NONE": 0,
+    "FRAMEBUFFER_COMPLETE": 36053,
+    "FRAMEBUFFER_INCOMPLETE_ATTACHMENT": 36054,
+    "FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT": 36055,
+    "FRAMEBUFFER_INCOMPLETE_DIMENSIONS": 36057,
+    "FRAMEBUFFER_UNSUPPORTED": 36061,
+    "FRAMEBUFFER_BINDING": 36006,
+    "RENDERBUFFER_BINDING": 36007,
+    "MAX_RENDERBUFFER_SIZE": 34024,
+    "INVALID_FRAMEBUFFER_OPERATION": 1286,
+    "UNPACK_FLIP_Y_WEBGL": 37440,
+    "UNPACK_PREMULTIPLY_ALPHA_WEBGL": 37441,
+    "CONTEXT_LOST_WEBGL": 37442,
+    "UNPACK_COLORSPACE_CONVERSION_WEBGL": 37443,
+    "BROWSER_DEFAULT_WEBGL": 37444
+};

+ 142 - 0
uni_modules/mu-canvas/js_sdk/gcanvas/context-webgl/GLmethod.js

@@ -0,0 +1,142 @@
+let i = 1;
+
+const GLmethod = {};
+
+GLmethod.activeTexture = i++;         //1
+GLmethod.attachShader = i++;
+GLmethod.bindAttribLocation = i++;
+GLmethod.bindBuffer = i++;
+GLmethod.bindFramebuffer = i++;
+GLmethod.bindRenderbuffer = i++;
+GLmethod.bindTexture = i++;
+GLmethod.blendColor = i++;
+GLmethod.blendEquation = i++;
+GLmethod.blendEquationSeparate = i++; //10
+GLmethod.blendFunc = i++;
+GLmethod.blendFuncSeparate = i++;
+GLmethod.bufferData = i++;
+GLmethod.bufferSubData = i++;
+GLmethod.checkFramebufferStatus = i++;
+GLmethod.clear = i++;
+GLmethod.clearColor = i++;
+GLmethod.clearDepth = i++;
+GLmethod.clearStencil = i++;
+GLmethod.colorMask = i++;              //20
+GLmethod.compileShader = i++;
+GLmethod.compressedTexImage2D = i++;
+GLmethod.compressedTexSubImage2D = i++;
+GLmethod.copyTexImage2D = i++;
+GLmethod.copyTexSubImage2D = i++;
+GLmethod.createBuffer = i++;
+GLmethod.createFramebuffer = i++;
+GLmethod.createProgram = i++;
+GLmethod.createRenderbuffer = i++;
+GLmethod.createShader = i++;           //30
+GLmethod.createTexture = i++;
+GLmethod.cullFace = i++;
+GLmethod.deleteBuffer = i++;
+GLmethod.deleteFramebuffer = i++;
+GLmethod.deleteProgram = i++;
+GLmethod.deleteRenderbuffer = i++;
+GLmethod.deleteShader = i++;
+GLmethod.deleteTexture = i++;
+GLmethod.depthFunc = i++;
+GLmethod.depthMask = i++;              //40
+GLmethod.depthRange = i++;
+GLmethod.detachShader = i++;
+GLmethod.disable = i++;
+GLmethod.disableVertexAttribArray = i++;
+GLmethod.drawArrays = i++;
+GLmethod.drawArraysInstancedANGLE = i++;
+GLmethod.drawElements = i++;
+GLmethod.drawElementsInstancedANGLE = i++;
+GLmethod.enable = i++;
+GLmethod.enableVertexAttribArray = i++;    //50
+GLmethod.flush = i++;
+GLmethod.framebufferRenderbuffer = i++;
+GLmethod.framebufferTexture2D = i++;
+GLmethod.frontFace = i++;
+GLmethod.generateMipmap = i++;
+GLmethod.getActiveAttrib = i++;
+GLmethod.getActiveUniform = i++;
+GLmethod.getAttachedShaders = i++;
+GLmethod.getAttribLocation = i++;
+GLmethod.getBufferParameter = i++;         //60
+GLmethod.getContextAttributes = i++;
+GLmethod.getError = i++;
+GLmethod.getExtension = i++;
+GLmethod.getFramebufferAttachmentParameter = i++;
+GLmethod.getParameter = i++;
+GLmethod.getProgramInfoLog = i++;
+GLmethod.getProgramParameter = i++;
+GLmethod.getRenderbufferParameter = i++;
+GLmethod.getShaderInfoLog = i++;
+GLmethod.getShaderParameter = i++;         //70
+GLmethod.getShaderPrecisionFormat = i++;
+GLmethod.getShaderSource = i++;
+GLmethod.getSupportedExtensions = i++;
+GLmethod.getTexParameter = i++;
+GLmethod.getUniform = i++;
+GLmethod.getUniformLocation = i++;
+GLmethod.getVertexAttrib = i++;
+GLmethod.getVertexAttribOffset = i++;
+GLmethod.isBuffer = i++;
+GLmethod.isContextLost = i++;              //80
+GLmethod.isEnabled = i++;
+GLmethod.isFramebuffer = i++;
+GLmethod.isProgram = i++;
+GLmethod.isRenderbuffer = i++;
+GLmethod.isShader = i++;
+GLmethod.isTexture = i++;
+GLmethod.lineWidth = i++;
+GLmethod.linkProgram = i++;
+GLmethod.pixelStorei = i++;
+GLmethod.polygonOffset = i++;              //90
+GLmethod.readPixels = i++;
+GLmethod.renderbufferStorage = i++;
+GLmethod.sampleCoverage = i++;
+GLmethod.scissor = i++;
+GLmethod.shaderSource = i++;
+GLmethod.stencilFunc = i++;
+GLmethod.stencilFuncSeparate = i++;
+GLmethod.stencilMask = i++;
+GLmethod.stencilMaskSeparate = i++;
+GLmethod.stencilOp = i++;                  //100
+GLmethod.stencilOpSeparate = i++;
+GLmethod.texImage2D = i++;
+GLmethod.texParameterf = i++;
+GLmethod.texParameteri = i++;
+GLmethod.texSubImage2D = i++;
+GLmethod.uniform1f = i++;
+GLmethod.uniform1fv = i++;
+GLmethod.uniform1i = i++;
+GLmethod.uniform1iv = i++;
+GLmethod.uniform2f = i++;                  //110
+GLmethod.uniform2fv = i++;
+GLmethod.uniform2i = i++;
+GLmethod.uniform2iv = i++;
+GLmethod.uniform3f = i++;
+GLmethod.uniform3fv = i++;
+GLmethod.uniform3i = i++;
+GLmethod.uniform3iv = i++;
+GLmethod.uniform4f = i++;
+GLmethod.uniform4fv = i++;
+GLmethod.uniform4i = i++;                  //120
+GLmethod.uniform4iv = i++;
+GLmethod.uniformMatrix2fv = i++;
+GLmethod.uniformMatrix3fv = i++;
+GLmethod.uniformMatrix4fv = i++;
+GLmethod.useProgram = i++;
+GLmethod.validateProgram = i++;
+GLmethod.vertexAttrib1f = i++; //new
+GLmethod.vertexAttrib2f = i++; //new
+GLmethod.vertexAttrib3f = i++; //new
+GLmethod.vertexAttrib4f = i++; //new       //130
+GLmethod.vertexAttrib1fv = i++; //new
+GLmethod.vertexAttrib2fv = i++; //new
+GLmethod.vertexAttrib3fv = i++; //new
+GLmethod.vertexAttrib4fv = i++; //new
+GLmethod.vertexAttribPointer = i++;
+GLmethod.viewport = i++;
+
+export default GLmethod;

+ 23 - 0
uni_modules/mu-canvas/js_sdk/gcanvas/context-webgl/GLtype.js

@@ -0,0 +1,23 @@
+const GLtype = {};
+
+[
+    "GLbitfield",    
+    "GLboolean",
+    "GLbyte",
+    "GLclampf",
+    "GLenum",
+    "GLfloat",
+    "GLint",
+    "GLintptr",
+    "GLsizei",
+    "GLsizeiptr",
+    "GLshort",
+    "GLubyte",
+    "GLuint",
+    "GLushort"
+].sort().map((typeName, i) => GLtype[typeName] = 1 >> (i + 1));
+
+export default GLtype;
+
+
+

+ 21 - 0
uni_modules/mu-canvas/js_sdk/gcanvas/context-webgl/Program.js

@@ -0,0 +1,21 @@
+import {getTransferedObjectUUID} from './classUtils';
+
+const name = 'WebGLProgram';
+
+function uuid(id) {
+    return getTransferedObjectUUID(name, id);
+}
+
+export default class WebGLProgram {
+    className = name;
+
+    constructor(id) {
+        this.id = id;
+    }
+
+    static uuid = uuid;
+
+    uuid() {
+        return uuid(this.id);
+    }
+}

+ 21 - 0
uni_modules/mu-canvas/js_sdk/gcanvas/context-webgl/Renderbuffer.js

@@ -0,0 +1,21 @@
+import {getTransferedObjectUUID} from './classUtils';
+
+const name = 'WebGLRenderBuffer';
+
+function uuid(id) {
+    return getTransferedObjectUUID(name, id);
+}
+
+export default class WebGLRenderbuffer {
+    className = name;
+
+    constructor(id) {
+        this.id = id;
+    }
+
+    static uuid = uuid;
+
+    uuid() {
+        return uuid(this.id);
+    }
+}

+ 1191 - 0
uni_modules/mu-canvas/js_sdk/gcanvas/context-webgl/RenderingContext.js

@@ -0,0 +1,1191 @@
+import GLenum from './GLenum';
+import ActiveInfo from './ActiveInfo';
+import Buffer from './Buffer';
+import Framebuffer from './Framebuffer';
+import Renderbuffer from './Renderbuffer';
+import Texture from './Texture';
+import Program from './Program';
+import Shader from './Shader';
+import ShaderPrecisionFormat from './ShaderPrecisionFormat';
+import UniformLocation from './UniformLocation';
+import GLmethod from './GLmethod';
+
+const processArray = (array, checkArrayType = false) => {
+
+    function joinArray(arr, sep) {
+        let res = '';
+        for (let i = 0; i < arr.length; i++) {
+            if (i !== 0) {
+                res += sep;
+            }
+            res += arr[i];
+        }
+        return res;
+    }
+
+    let type = 'Float32Array';
+    if (checkArrayType) {
+        if (array instanceof Uint8Array) {
+            type = 'Uint8Array'
+        } else if (array instanceof Uint16Array) {
+            type = 'Uint16Array';
+        } else if (array instanceof Uint32Array) {
+            type = 'Uint32Array';
+        } else if (array instanceof Float32Array) {
+            type = 'Float32Array';
+        } else {
+            throw new Error('Check array type failed. Array type is ' + typeof array);
+        }
+    }
+
+    const ArrayTypes = {
+        Uint8Array: 1,
+        Uint16Array: 2,
+        Uint32Array: 4,
+        Float32Array: 14
+    };
+    return ArrayTypes[type] + ',' + btoa(joinArray(array, ','))
+}
+
+export default class WebGLRenderingContext {
+
+    // static GBridge = null;
+
+    className = 'WebGLRenderingContext';
+
+    constructor(canvas, type, attrs) {
+        this._canvas = canvas;
+        this._type = type;
+        this._version = 'WebGL 1.0';
+        this._attrs = attrs;
+        this._map = new Map();
+
+        Object.keys(GLenum)
+            .forEach(name => Object.defineProperty(this, name, {
+                value: GLenum[name]
+            }));
+    }
+
+    get canvas() {
+        return this._canvas;
+    }
+
+    activeTexture = function (textureUnit) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.activeTexture + ',' + textureUnit,
+            true
+        );
+    }
+
+    attachShader = function (progarm, shader) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.attachShader + ',' + progarm.id + ',' + shader.id,
+            true
+        );
+    }
+
+    bindAttribLocation = function (program, index, name) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.bindAttribLocation + ',' + program.id + ',' + index + ',' + name,
+            true
+        )
+    }
+
+    bindBuffer = function (target, buffer) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.bindBuffer + ',' + target + ',' + (buffer ? buffer.id : 0),
+            true
+        );
+    }
+
+    bindFramebuffer = function (target, framebuffer) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.bindFramebuffer + ',' + target + ',' + (framebuffer ? framebuffer.id : 0),
+            true
+        )
+    }
+
+    bindRenderbuffer = function (target, renderBuffer) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.bindRenderbuffer + ',' + target + ',' + (renderBuffer ? renderBuffer.id : 0),
+            true
+        )
+    }
+
+    bindTexture = function (target, texture) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.bindTexture + ',' + target + ',' + (texture ? texture.id : 0),
+            true
+        )
+    }
+
+    blendColor = function (r, g, b, a) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.blendColor + ',' + target + ',' + r + ',' + g + ',' + b + ',' + a,
+            true
+        )
+    }
+
+    blendEquation = function (mode) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.blendEquation + ',' + mode,
+            true
+        )
+    }
+
+    blendEquationSeparate = function (modeRGB, modeAlpha) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.blendEquationSeparate + ',' + modeRGB + ',' + modeAlpha,
+            true
+        )
+    }
+
+
+    blendFunc = function (sfactor, dfactor) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.blendFunc + ',' + sfactor + ',' + dfactor,
+            true
+        );
+    }
+
+    blendFuncSeparate = function (srcRGB, dstRGB, srcAlpha, dstAlpha) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.blendFuncSeparate + ',' + srcRGB + ',' + dstRGB + ',' + srcAlpha + ',' + dstAlpha,
+            true
+        );
+    }
+
+    bufferData = function (target, data, usage) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.bufferData + ',' + target + ',' + processArray(data, true) + ',' + usage,
+            true
+        )
+    }
+
+    bufferSubData = function (target, offset, data) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.bufferSubData + ',' + target + ',' + offset + ',' + processArray(data, true),
+            true
+        )
+    }
+
+    checkFramebufferStatus = function (target) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.checkFramebufferStatus + ',' + target
+        );
+        return Number(result);
+    }
+
+    clear = function (mask) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.clear + ',' + mask
+        );
+        this._canvas._needRender = true;
+    }
+
+    clearColor = function (r, g, b, a) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.clearColor + ',' + r + ',' + g + ',' + b,
+            true
+        )
+    }
+
+    clearDepth = function (depth) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.clearDepth + ',' + depth,
+            true
+        )
+    }
+
+    clearStencil = function (s) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.clearStencil + ',' + s
+        );
+    }
+
+    colorMask = function (r, g, b, a) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.colorMask + ',' + r + ',' + g + ',' + b + ',' + a
+        )
+    }
+
+    compileShader = function (shader) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.compileShader + ',' + shader.id,
+            true
+        )
+    }
+
+    compressedTexImage2D = function (target, level, internalformat, width, height, border, pixels) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.compressedTexImage2D + ',' + target + ',' + level + ',' + internalformat + ',' +
+            width + ',' + height + ',' + border + ',' + processArray(pixels),
+            true
+        )
+    }
+
+    compressedTexSubImage2D = function (target, level, xoffset, yoffset, width, height, format, pixels) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.compressedTexSubImage2D + ',' + target + ',' + level + ',' + xoffset + ',' + yoffset + ',' +
+            width + ',' + height + ',' + format + ',' + processArray(pixels),
+            true
+        )
+    }
+
+
+    copyTexImage2D = function (target, level, internalformat, x, y, width, height, border) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.copyTexImage2D + ',' + target + ',' + level + ',' + internalformat + ',' + x + ',' + y + ',' +
+            width + ',' + height + ',' + border,
+            true
+        );
+    }
+
+    copyTexSubImage2D = function (target, level, xoffset, yoffset, x, y, width, height) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.copyTexSubImage2D + ',' + target + ',' + level + ',' + xoffset + ',' + yoffset + ',' + x + ',' + y + ',' +
+            width + ',' + height
+        );
+    }
+
+    createBuffer = function () {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.createBuffer + ''
+        );
+        const buffer = new Buffer(result);
+        this._map.set(buffer.uuid(), buffer);
+        return buffer;
+    }
+
+    createFramebuffer = function () {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.createFramebuffer + ''
+        );
+        const framebuffer = new Framebuffer(result);
+        this._map.set(framebuffer.uuid(), framebuffer);
+        return framebuffer;
+    }
+
+
+    createProgram = function () {
+        const id = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.createProgram + ''
+        );
+        const program = new Program(id);
+        this._map.set(program.uuid(), program);
+        return program;
+    }
+
+    createRenderbuffer = function () {
+        const id = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.createRenderbuffer + ''
+        )
+        const renderBuffer = new Renderbuffer(id);
+        this._map.set(renderBuffer.uuid(), renderBuffer);
+        return renderBuffer;
+    }
+
+    createShader = function (type) {
+        const id = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.createShader + ',' + type
+        )
+        const shader = new Shader(id, type);
+        this._map.set(shader.uuid(), shader);
+        return shader;
+    }
+
+    createTexture = function () {
+        const id = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.createTexture + ''
+        );
+        const texture = new Texture(id);
+        this._map.set(texture.uuid(), texture);
+        return texture;
+    }
+
+    cullFace = function (mode) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.cullFace + ',' + mode,
+            true
+        )
+    }
+
+
+    deleteBuffer = function (buffer) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.deleteBuffer + ',' + buffer.id,
+            true
+        )
+    }
+
+    deleteFramebuffer = function (framebuffer) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.deleteFramebuffer + ',' + framebuffer.id,
+            true
+        )
+    }
+
+    deleteProgram = function (program) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.deleteProgram + ',' + program.id,
+            true
+        )
+    }
+
+    deleteRenderbuffer = function (renderbuffer) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.deleteRenderbuffer + ',' + renderbuffer.id,
+            true
+        )
+    }
+
+    deleteShader = function (shader) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.deleteShader + ',' + shader.id,
+            true
+        )
+    }
+
+    deleteTexture = function (texture) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.deleteTexture + ',' + texture.id,
+            true
+        )
+    }
+
+    depthFunc = function (func) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.depthFunc + ',' + func
+        )
+    }
+
+    depthMask = function (flag) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.depthMask + ',' + Number(flag),
+            true
+        )
+    }
+
+    depthRange = function (zNear, zFar) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.depthRange + ',' + zNear + ',' + zFar,
+            true
+        )
+    }
+
+    detachShader = function (program, shader) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.detachShader + ',' + program.id + ',' + shader.id,
+            true
+        )
+    }
+
+    disable = function (cap) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.disable + ',' + cap,
+            true
+        )
+    }
+
+    disableVertexAttribArray = function (index) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.disableVertexAttribArray + ',' + index,
+            true
+        );
+    }
+
+    drawArrays = function (mode, first, count) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.drawArrays + ',' + mode + ',' + first + ',' + count
+        )
+        this._canvas._needRender = true;
+    }
+
+    drawElements = function (mode, count, type, offset) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.drawElements + ',' + mode + ',' + count + ',' + type + ',' + offset + ';'
+        );
+        this._canvas._needRender = true;
+    }
+
+    enable = function (cap) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.enable + ',' + cap,
+            true
+        );
+    }
+
+    enableVertexAttribArray = function (index) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.enableVertexAttribArray + ',' + index,
+            true
+        )
+    }
+
+
+    flush = function () {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.flush + ''
+        )
+    }
+
+    framebufferRenderbuffer = function (target, attachment, textarget, texture, level) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.framebufferRenderbuffer + ',' + target + ',' + attachment + ',' + textarget + ',' + (texture ? texture.id : 0) + ',' + level,
+            true
+        )
+    }
+
+    framebufferTexture2D = function (target, attachment, textarget, texture, level) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.framebufferTexture2D + ',' + target + ',' + attachment + ',' + textarget + ',' + (texture ? texture.id : 0) + ',' + level,
+            true
+        )
+    }
+
+    frontFace = function (mode) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.frontFace + ',' + mode,
+            true
+        )
+    }
+
+    generateMipmap = function (target) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.generateMipmap + ',' + target,
+            true
+        )
+    }
+
+    getActiveAttrib = function (progarm, index) {
+        const resultString = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getActiveAttrib + ',' + progarm.id + ',' + index
+        )
+        const [type, size, name] = resultString.split(',');
+        return new ActiveInfo({
+            type: Number(type),
+            size: Number(size),
+            name
+        });
+    }
+
+    getActiveUniform = function (progarm, index) {
+        const resultString = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getActiveUniform + ',' + progarm.id + ',' + index
+        );
+        const [type, size, name] = resultString.split(',');
+        return new ActiveInfo({
+            type: Number(type),
+            size: Number(size),
+            name
+        })
+    }
+
+    getAttachedShaders = function (progarm) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getAttachedShaders + ',' + progarm.id
+        );
+        const [type, ...ids] = result;
+        return ids.map(id => this._map.get(Shader.uuid(id)));
+    }
+
+    getAttribLocation = function (progarm, name) {
+        return WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getAttribLocation + ',' + progarm.id + ',' + name
+        )
+    }
+
+    getBufferParameter = function (target, pname) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getBufferParameter + ',' + target + ',' + pname
+        );
+        const [type, res] = getBufferParameter;
+        return res;
+    }
+
+    getError = function () {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getError + ''
+        )
+        return result;
+    }
+
+    getExtension = function (name) {
+        return null;
+    }
+
+    getFramebufferAttachmentParameter = function (target, attachment, pname) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getFramebufferAttachmentParameter + ',' + target + ',' + attachment + ',' + pname
+        )
+        switch (pname) {
+            case GLenum.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+                return this._map.get(Renderbuffer.uuid(result)) || this._map.get(Texture.uuid(result)) || null;
+            default:
+                return result;
+        }
+    }
+
+    getParameter = function (pname) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getParameter + ',' + pname
+        )
+        switch (pname) {
+            case GLenum.VERSION:
+                return this._version;
+            case GLenum.ARRAY_BUFFER_BINDING: // buffer
+            case GLenum.ELEMENT_ARRAY_BUFFER_BINDING: // buffer
+                return this._map.get(Buffer.uuid(result)) || null;
+            case GLenum.CURRENT_PROGRAM: // program
+                return this._map.get(Program.uuid(result)) || null;
+            case GLenum.FRAMEBUFFER_BINDING: // framebuffer
+                return this._map.get(Framebuffer.uuid(result)) || null;
+            case GLenum.RENDERBUFFER_BINDING: // renderbuffer
+                return this._map.get(Renderbuffer.uuid(result)) || null;
+            case GLenum.TEXTURE_BINDING_2D: // texture
+            case GLenum.TEXTURE_BINDING_CUBE_MAP: // texture
+                return this._map.get(Texture.uuid(result)) || null;
+            case GLenum.ALIASED_LINE_WIDTH_RANGE: // Float32Array
+            case GLenum.ALIASED_POINT_SIZE_RANGE: // Float32Array
+            case GLenum.BLEND_COLOR: // Float32Array
+            case GLenum.COLOR_CLEAR_VALUE: // Float32Array
+            case GLenum.DEPTH_RANGE: // Float32Array
+            case GLenum.MAX_VIEWPORT_DIMS: // Int32Array
+            case GLenum.SCISSOR_BOX: // Int32Array
+            case GLenum.VIEWPORT: // Int32Array            
+            case GLenum.COMPRESSED_TEXTURE_FORMATS: // Uint32Array
+            default:
+                const [type, ...res] = result.split(',');
+                if (res.length === 1) {
+                    return Number(res[0]);
+                } else {
+                    return res.map(Number);
+                }
+        }
+    }
+
+    getProgramInfoLog = function (progarm) {
+        return WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getProgramInfoLog + ',' + progarm.id
+        )
+    }
+
+    getProgramParameter = function (program, pname) {
+        const res = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getProgramParameter + ',' + program.id + ',' + pname
+        );
+
+        const [type, result] = res.split(',').map(i => parseInt(i));
+
+        if (type === 1) {
+            return Boolean(result);
+        } else if (type === 2) {
+            return result;
+        } else {
+            throw new Error('Unrecongized program paramater ' + res + ', type: ' + typeof res);
+        }
+    }
+
+
+    getRenderbufferParameter = function (target, pname) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getRenderbufferParameter + ',' + target + ',' + pname
+        )
+        return result;
+    }
+
+
+    getShaderInfoLog = function (shader) {
+        return WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getShaderInfoLog + ',' + shader.id
+        );
+    }
+
+    getShaderParameter = function (shader, pname) {
+        return WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getShaderParameter + ',' + shader.id + ',' + pname
+        )
+    }
+
+    getShaderPrecisionFormat = function (shaderType, precisionType) {
+        const [rangeMin, rangeMax, precision] = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getShaderPrecisionFormat + ',' + shaderType + ',' + precisionType
+        );
+        const shaderPrecisionFormat = new ShaderPrecisionFormat({
+            rangeMin: Number(rangeMin),
+            rangeMax: Number(rangeMax),
+            precision: Number(precision)
+        });
+        return shaderPrecisionFormat;
+    }
+
+    getShaderSource = function (shader) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getShaderSource + ',' + shader.id
+        );
+        return result;
+    }
+
+    getSupportedExtensions = function () {
+        return Object.keys({});
+    }
+
+    getTexParameter = function (target, pname) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getTexParameter + ',' + target + ',' + pname
+        )
+        return result;
+    }
+
+    getUniformLocation = function (program, name) {
+        const id = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getUniformLocation + ',' + program.id + ',' + name
+        );
+        if (id === -1) {
+            return null;
+        } else {
+            return new UniformLocation(Number(id));
+        }
+    }
+
+    getVertexAttrib = function (index, pname) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getVertexAttrib + ',' + index + ',' + pname
+        );
+        switch (pname) {
+            case GLenum.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
+                return this._map.get(Buffer.uuid(result)) || null;
+            case GLenum.CURRENT_VERTEX_ATTRIB: // Float32Array
+            default:
+                return result;
+        }
+    }
+
+    getVertexAttribOffset = function (index, pname) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.getVertexAttribOffset + ',' + index + ',' + pname
+        )
+        return Number(result);
+    }
+
+    isBuffer = function (buffer) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.isBuffer + ',' + buffer.id
+        )
+        return Boolean(result);
+    }
+
+    isContextLost = function () {
+        return false;
+    }
+
+    isEnabled = function (cap) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.isEnabled + ',' + cap
+        )
+        return Boolean(result);
+    }
+
+    isFramebuffer = function (framebuffer) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.isFramebuffer + ',' + framebuffer.id
+        )
+        return Boolean(result);
+    }
+
+    isProgram = function (program) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.isProgram + ',' + program.id
+        )
+        return Boolean(result);
+    }
+
+    isRenderbuffer = function (renderBuffer) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.isRenderbuffer + ',' + renderbuffer.id
+        )
+        return Boolean(result);
+    }
+
+    isShader = function (shader) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.isShader + ',' + shader.id
+        )
+        return Boolean(result);
+    }
+
+    isTexture = function (texture) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.isTexture + ',' + texture.id
+        );
+        return Boolean(result);
+    }
+
+    lineWidth = function (width) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.lineWidth + ',' + width,
+            true
+        )
+    }
+
+    linkProgram = function (program) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.linkProgram + ',' + program.id,
+            true
+        );
+    }
+
+
+    pixelStorei = function (pname, param) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.pixelStorei + ',' + pname + ',' + Number(param)
+        )
+    }
+
+    polygonOffset = function (factor, units) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.polygonOffset + ',' + factor + ',' + units
+        )
+    }
+
+    readPixels = function (x, y, width, height, format, type, pixels) {
+        const result = WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.readPixels + ',' + x + ',' + y + ',' + width + ',' + height + ',' + format + ',' + type
+        )
+        return result;
+    }
+
+    renderbufferStorage = function (target, internalFormat, width, height) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.renderbufferStorage + ',' + target + ',' + internalFormat + ',' + width + ',' + height,
+            true
+        )
+    }
+
+    sampleCoverage = function (value, invert) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.sampleCoverage + ',' + value + ',' + Number(invert),
+            true
+        )
+    }
+
+    scissor = function (x, y, width, height) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.scissor + ',' + x + ',' + y + ',' + width + ',' + height,
+            true
+        )
+    }
+
+    shaderSource = function (shader, source) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.shaderSource + ',' + shader.id + ',' + source
+        )
+    }
+
+    stencilFunc = function (func, ref, mask) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.stencilFunc + ',' + func + ',' + ref + ',' + mask,
+            true
+        )
+    }
+
+    stencilFuncSeparate = function (face, func, ref, mask) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.stencilFuncSeparate + ',' + face + ',' + func + ',' + ref + ',' + mask,
+            true
+        )
+    }
+
+    stencilMask = function (mask) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.stencilMask + ',' + mask,
+            true
+        )
+    }
+
+    stencilMaskSeparate = function (face, mask) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.stencilMaskSeparate + ',' + face + ',' + mask,
+            true
+        )
+    }
+
+    stencilOp = function (fail, zfail, zpass) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.stencilOp + ',' + fail + ',' + zfail + ',' + zpass
+        )
+    }
+
+    stencilOpSeparate = function (face, fail, zfail, zpass) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.stencilOp + ',' + face + ',' + fail + ',' + zfail + ',' + zpass,
+            true
+        )
+    }
+
+    texImage2D = function (...args) {
+        WebGLRenderingContext.GBridge.texImage2D(this._canvas.id, ...args);
+    }
+
+
+    texParameterf = function (target, pname, param) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.texParameterf + ',' + target + ',' + pname + ',' + param,
+            true
+        )
+    }
+
+    texParameteri = function (target, pname, param) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.texParameteri + ',' + target + ',' + pname + ',' + param
+        )
+    }
+
+    texSubImage2D = function (...args) {
+        WebGLRenderingContext.GBridge.texSubImage2D(this._canvas.id, ...args);
+    }
+
+    uniform1f = function (location, v0) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform1f + ',' + location.id + ',' + v0
+        )
+    }
+
+    uniform1fv = function (location, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform1fv + ',' + location.id + ',' + processArray(value),
+            true
+        )
+    }
+
+    uniform1i = function (location, v0) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform1i + ',' + location.id + ',' + v0,
+            // true
+        )
+    }
+
+    uniform1iv = function (location, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform1iv + ',' + location.id + ',' + processArray(value),
+            true
+        )
+    }
+
+    uniform2f = function (location, v0, v1) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform2f + ',' + location.id + ',' + v0 + ',' + v1,
+            true
+        )
+    }
+
+    uniform2fv = function (location, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform2fv + ',' + location.id + ',' + processArray(value),
+            true
+        )
+    }
+
+    uniform2i = function (location, v0, v1) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform2i + ',' + location.id + ',' + v0 + ',' + v1,
+            true
+        )
+    }
+
+    uniform2iv = function (location, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform2iv + ',' + location.id + ',' + processArray(value),
+            true
+        )
+    }
+
+    uniform3f = function (location, v0, v1, v2) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform3f + ',' + location.id + ',' + v0 + ',' + v1 + ',' + v2,
+            true
+        )
+    }
+
+    uniform3fv = function (location, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform3fv + ',' + location.id + ',' + processArray(value),
+            true
+        )
+    }
+
+    uniform3i = function (location, v0, v1, v2) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform3i + ',' + location.id + ',' + v0 + ',' + v1 + ',' + v2,
+            true
+        )
+    }
+
+    uniform3iv = function (location, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform3iv + ',' + location.id + ',' + processArray(value),
+            true
+        )
+    }
+
+    uniform4f = function (location, v0, v1, v2, v3) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform4f + ',' + location.id + ',' + v0 + ',' + v1 + ',' + v2 + ',' + v3,
+            true
+        )
+    }
+
+    uniform4fv = function (location, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform4fv + ',' + location.id + ',' + processArray(value),
+            true
+        )
+    }
+
+    uniform4i = function (location, v0, v1, v2, v3) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform4i + ',' + location.id + ',' + v0 + ',' + v1 + ',' + v2 + ',' + v3,
+            true
+        )
+    }
+
+    uniform4iv = function (location, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniform4iv + ',' + location.id + ',' + processArray(value, true),
+            true
+        )
+    }
+
+    uniformMatrix2fv = function (location, transpose, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniformMatrix2fv + ',' + location.id + ',' + Number(transpose) + ',' + processArray(value),
+            true
+        )
+    }
+
+    uniformMatrix3fv = function (location, transpose, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniformMatrix3fv + ',' + location.id + ',' + Number(transpose) + ',' + processArray(value),
+            true
+        )
+    }
+
+    uniformMatrix4fv = function (location, transpose, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.uniformMatrix4fv + ',' + location.id + ',' + Number(transpose) + ',' + processArray(value),
+            true
+        );
+    }
+
+    useProgram = function (progarm) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.useProgram + ',' + progarm.id + '',
+            true
+        )
+    }
+
+
+    validateProgram = function (program) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.validateProgram + ',' + program.id,
+            true
+        )
+    }
+
+    vertexAttrib1f = function (index, v0) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.vertexAttrib1f + ',' + index + ',' + v0,
+            true
+        )
+    }
+
+    vertexAttrib2f = function (index, v0, v1) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.vertexAttrib2f + ',' + index + ',' + v0 + ',' + v1,
+            true
+        )
+    }
+
+    vertexAttrib3f = function (index, v0, v1, v2) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.vertexAttrib3f + ',' + index + ',' + v0 + ',' + v1 + ',' + v2,
+            true
+        )
+    }
+
+    vertexAttrib4f = function (index, v0, v1, v2, v3) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.vertexAttrib4f + ',' + index + ',' + v0 + ',' + v1 + ',' + v2 + ',' + v3,
+            true
+        )
+    }
+
+    vertexAttrib1fv = function (index, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.vertexAttrib1fv + ',' + index + ',' + processArray(value),
+            true
+        )
+    }
+
+    vertexAttrib2fv = function (index, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.vertexAttrib2fv + ',' + index + ',' + processArray(value),
+            true
+        )
+    }
+
+    vertexAttrib3fv = function (index, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.vertexAttrib3fv + ',' + index + ',' + processArray(value),
+            true
+        )
+    }
+
+    vertexAttrib4fv = function (index, value) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.vertexAttrib4fv + ',' + index + ',' + processArray(value),
+            true
+        )
+    }
+
+    vertexAttribPointer = function (index, size, type, normalized, stride, offset) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.vertexAttribPointer + ',' + index + ',' + size + ',' + type + ',' + Number(normalized) + ',' + stride + ',' + offset,
+            true
+        )
+    }
+
+    viewport = function (x, y, width, height) {
+        WebGLRenderingContext.GBridge.callNative(
+            this._canvas.id,
+            GLmethod.viewport + ',' + x + ',' + y + ',' + width + ',' + height,
+            true
+        )
+    }
+}

+ 22 - 0
uni_modules/mu-canvas/js_sdk/gcanvas/context-webgl/Shader.js

@@ -0,0 +1,22 @@
+import {getTransferedObjectUUID} from './classUtils';
+
+const name = 'WebGLShader';
+
+function uuid(id) {
+    return getTransferedObjectUUID(name, id);
+}
+
+export default class WebGLShader {
+    className = name;
+
+    constructor(id, type) {
+        this.id = id;
+        this.type = type;
+    }
+
+    static uuid = uuid;
+
+    uuid() {
+        return uuid(this.id);
+    }
+}

+ 11 - 0
uni_modules/mu-canvas/js_sdk/gcanvas/context-webgl/ShaderPrecisionFormat.js

@@ -0,0 +1,11 @@
+export default class WebGLShaderPrecisionFormat {
+    className = 'WebGLShaderPrecisionFormat';
+
+    constructor({
+        rangeMin, rangeMax, precision
+    }) {
+        this.rangeMin = rangeMin;
+        this.rangeMax = rangeMax;
+        this.precision = precision;
+    }
+}

+ 22 - 0
uni_modules/mu-canvas/js_sdk/gcanvas/context-webgl/Texture.js

@@ -0,0 +1,22 @@
+import {getTransferedObjectUUID} from './classUtils';
+
+const name = 'WebGLTexture';
+
+function uuid(id) {
+    return getTransferedObjectUUID(name, id);
+}
+
+export default class WebGLTexture {
+    className = name;
+
+    constructor(id, type) {
+        this.id = id;
+        this.type = type;
+    }
+
+    static uuid = uuid;
+
+    uuid() {
+        return uuid(this.id);
+    }
+}

+ 22 - 0
uni_modules/mu-canvas/js_sdk/gcanvas/context-webgl/UniformLocation.js

@@ -0,0 +1,22 @@
+import {getTransferedObjectUUID} from './classUtils';
+
+const name = 'WebGLUniformLocation';
+
+function uuid(id) {
+    return getTransferedObjectUUID(name, id);
+}
+
+export default class WebGLUniformLocation {
+    className = name;
+
+    constructor(id, type) {
+        this.id = id;
+        this.type = type;
+    }
+
+    static uuid = uuid;
+
+    uuid() {
+        return uuid(this.id);
+    }
+}

+ 3 - 0
uni_modules/mu-canvas/js_sdk/gcanvas/context-webgl/classUtils.js

@@ -0,0 +1,3 @@
+export function getTransferedObjectUUID(name, id) {
+    return `${name.toLowerCase()}-${id}`;
+}

+ 74 - 0
uni_modules/mu-canvas/js_sdk/gcanvas/env/canvas.js

@@ -0,0 +1,74 @@
+import GContext2D from '../context-2d/RenderingContext';
+import GContextWebGL from '../context-webgl/RenderingContext';
+
+export default class GCanvas {
+
+    // static GBridge = null;
+
+    id = null;
+
+    _needRender = true;
+
+    constructor(id, { disableAutoSwap }) {
+        this.id = id;
+
+        this._disableAutoSwap = disableAutoSwap;
+        if (disableAutoSwap) {
+            this._swapBuffers = () => {
+                GCanvas.GBridge.render(this.id);
+            }
+        }
+    }
+
+    getContext(type) {
+
+        let context = null;
+
+        if (type.match(/webgl/i)) {
+            context = new GContextWebGL(this);
+
+            context.componentId = this.id;
+
+            if (!this._disableAutoSwap) {
+                const render = () => {
+                    if (this._needRender) {
+                        GCanvas.GBridge.render(this.id);
+                        this._needRender = false;
+                    }
+                }
+                setInterval(render, 16);
+            }
+
+            GCanvas.GBridge.callSetContextType(this.id, 1); // 0 for 2d; 1 for webgl
+        } else if (type.match(/2d/i)) {
+            context = new GContext2D(this);
+
+            context.componentId = this.id;
+
+//             const render = ( callback ) => {
+// 
+//                 const commands = context._drawCommands;
+//                 context._drawCommands = '';
+// 
+//                 GCanvas.GBridge.render2d(this.id, commands, callback);
+//                 this._needRender = false;
+//             }
+// 			//draw方法触发
+// 			context._flush = render;
+//             //setInterval(render, 16);
+
+            GCanvas.GBridge.callSetContextType(this.id, 0);
+        } else {
+            throw new Error('not supported context ' + type);
+        }
+
+        return context;
+
+    }
+
+    reset() {
+        GCanvas.GBridge.callReset(this.id);
+    }
+
+
+}

+ 96 - 0
uni_modules/mu-canvas/js_sdk/gcanvas/env/image.js

@@ -0,0 +1,96 @@
+let incId = 1;
+
+const noop = function () { };
+
+class GImage {
+
+    static GBridge = null;
+
+    constructor() {
+        this._id = incId++;
+        this._width = 0;
+        this._height = 0;
+        this._src = undefined;
+        this._onload = noop;
+        this._onerror = noop;
+        this.complete = false;
+    }
+
+    get width() {
+        return this._width;
+    }
+    set width(v) {
+        this._width = v;
+    }
+
+    get height() {
+        return this._height;
+    }
+
+    set height(v) {
+        this._height = v;
+    }
+
+    get src() {
+        return this._src;
+    }
+
+    set src(v) {
+
+        if (v.startsWith('//')) {
+            v = 'http:' + v;
+        }
+
+        this._src = v;
+
+        GImage.GBridge.perloadImage([this._src, this._id], (data) => {
+            if (typeof data === 'string') {
+                data = JSON.parse(data);
+            }
+            if (data.error) {
+                var evt = { type: 'error', target: this };
+                this.onerror(evt);
+            } else {
+                this.complete = true;
+                this.width = typeof data.width === 'number' ? data.width : 0;
+                this.height = typeof data.height === 'number' ? data.height : 0;
+                var evt = { type: 'load', target: this };
+                this.onload(evt);
+            }
+        });
+    }
+
+    addEventListener(name, listener) {
+        if (name === 'load') {
+            this.onload = listener;
+        } else if (name === 'error') {
+            this.onerror = listener;
+        }
+    }
+
+    removeEventListener(name, listener) {
+        if (name === 'load') {
+            this.onload = noop;
+        } else if (name === 'error') {
+            this.onerror = noop;
+        }
+    }
+
+    get onload() {
+        return this._onload;
+    }
+
+    set onload(v) {
+        this._onload = v;
+    }
+
+    get onerror() {
+        return this._onerror;
+    }
+
+    set onerror(v) {
+        this._onerror = v;
+    }
+}
+
+export default GImage;

+ 24 - 0
uni_modules/mu-canvas/js_sdk/gcanvas/env/tool.js

@@ -0,0 +1,24 @@
+
+export function ArrayBufferToBase64 (buffer) {
+    var binary = '';
+    var bytes = new Uint8ClampedArray(buffer);
+    for (var len = bytes.byteLength, i = 0; i < len; i++) {
+        binary += String.fromCharCode(bytes[i]);
+    }
+    return btoa(binary);
+}
+	
+export function Base64ToUint8ClampedArray(base64String) {
+	const padding = '='.repeat((4 - base64String.length % 4) % 4);
+	const base64 = (base64String + padding)
+		.replace(/\-/g, '+')
+		.replace(/_/g, '/');
+
+	const rawData = atob(base64);
+	const outputArray = new Uint8ClampedArray(rawData.length);
+
+	for (let i = 0; i < rawData.length; ++i) {
+		outputArray[i] = rawData.charCodeAt(i);
+	}
+	return outputArray;
+}

+ 39 - 0
uni_modules/mu-canvas/js_sdk/gcanvas/index.js

@@ -0,0 +1,39 @@
+import GCanvas from './env/canvas';
+import GImage from './env/image';
+
+import GWebGLRenderingContext from './context-webgl/RenderingContext';
+import GContext2D from './context-2d/RenderingContext';
+
+import GBridgeWeex from './bridge/bridge-weex';
+
+export let Image = GImage;
+
+export let WeexBridge = GBridgeWeex;
+
+export function enable(el, { bridge, debug, disableAutoSwap, disableComboCommands } = {}) {
+
+    const GBridge = GImage.GBridge = GCanvas.GBridge = GWebGLRenderingContext.GBridge = GContext2D.GBridge = bridge;
+
+    GBridge.callEnable(el.ref, [
+        0,      // renderMode: 0--RENDERMODE_WHEN_DIRTY, 1--RENDERMODE_CONTINUOUSLY
+        -1,     // hybridLayerType:  0--LAYER_TYPE_NONE 1--LAYER_TYPE_SOFTWARE 2--LAYER_TYPE_HARDWARE
+        false,  // supportScroll
+        false,  // newCanvasMode
+        1,      // compatible
+        'white',// clearColor
+        false   // sameLevel: newCanvasMode = true && true => GCanvasView and Webview is same level
+    ]);
+
+    if (debug === true) {
+        GBridge.callEnableDebug();
+    }
+    if (disableComboCommands) {
+        GBridge.callEnableDisableCombo();
+    }
+
+    var canvas = new GCanvas(el.ref, { disableAutoSwap });
+    canvas.width = el.style.width;
+    canvas.height = el.style.height;
+
+    return canvas;
+};

Diferenças do arquivo suprimidas por serem muito extensas
+ 33 - 0
uni_modules/mu-canvas/js_sdk/uqrcode/uqrcode.js


+ 81 - 0
uni_modules/mu-canvas/package.json

@@ -0,0 +1,81 @@
+{
+  "id": "mu-canvas",
+  "displayName": "自定义canvas样式海报",
+  "version": "1.0.8",
+  "description": "可自定义样式的海报生成器,上面可画图片,可画文字,可画二维码",
+  "keywords": [
+    "mu-canvas,海报,canvas,自定义canvas样式海报"
+],
+  "repository": "",
+  "engines": {
+    "HBuilderX": "^3.5.4"
+  },
+  "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"
+        }
+      }
+    }
+  }
+}

+ 137 - 0
uni_modules/mu-canvas/readme.md

@@ -0,0 +1,137 @@
+# mu-canvas
+# 使用方法
+
+
+```javascript
+<template>
+	<view>
+		<mu-canvas ref="share" width="650" unit="rpx" height="1160" styles="margin-left: 50rpx;margin-top: 36rpx;" backgroundColor="#FFFFFF" :elementList="elementList" :auto="true"></mu-canvas>
+	</view>
+</template>
+
+<script>
+export default {
+	// components: { XqGeneratePoster },
+	data() {
+		return {
+			elementList: {
+				images: [ //图片对象
+					{
+						path: "http://t6.xin.cn/uploads/20231113/a07068b23e1d4969d09f4105fee78631.png", //图片路径[必填]
+						dx: 0, //左上角x轴[必填]
+						dy: 0, //左上角y轴[必填]
+						dWidth: 325, //宽度[必填]
+						dHeight: 430, //高度[必填]
+						sx: 0, //绘画的宽度[选填]
+						sy: 0, //绘画的高度[选填]
+					}
+				],
+				text: [ //渲染文字
+					{
+						value: "邀请码:", //渲染的文字
+						color: "#333333", //文字颜色[选填]
+						size: "14", //大小[选填]
+						font: "PingFang SC-Regular, PingFang SC;", //字体[选填]
+						x: 13, //左上角x轴[必填]
+						y: 452, //左上角y轴[必填]
+						// backgroundColor: "#ffffff", //背景色
+						maxWidth: "", //字体最大宽度
+						maxHeight: "", //字体最大高度
+					}
+				],
+				qr: [ //渲染的二维码
+					{
+						url: "http://t6.xin.cn/#/pages/user/code_login?invite_mobile=5", //二维码文字[必填]
+						dx: 241, //左上角x轴[必填]
+						dy: 452, //左上角y轴[必填]
+						size: 71, //二维码大小
+						color: "#333333", //二维码前景色
+						backgroundColor: "#ffffff" //二维码背景色
+					}
+				]
+			
+			}
+		};
+	},
+	methods: {
+		redraw(){
+			this.$refs.share.redraw();
+		},
+		getImgSrc(){
+			this.$refs.share.getImgSrc();
+		},
+		save(){
+			this.$refs.share.saveImg();
+		}
+	}
+};
+</script>
+```
+## mu-canvas参数说明
+
+| 参数               | 说明                    |  类型   |    默认    |
+| -------------     | ------------------------| -----  | ---------------|
+| canvasId     | canvas-id的名称            |  String |        canvas-id,同页面不能重复   |
+| auto     |是否自动渲染           |  Bool |          true是自动渲染,false需要手动调用          |
+| styles     | 样式[不设置宽高和背景颜色]            |  String |                    |
+| backgroundColor  | canvas背景颜色              |  String |   下载时会显示  |
+| width        | canvas的宽度            |  String/num |   单位px,不设置,为最宽图片宽度|
+| height     | canvas高度              |  String/num |    单位px,不设置,为最高图片高度|
+| unit       | canvas的宽高的单位[支持rpx和px]       |  String |     rpx/px|
+| elementList           | 绘画描述  |  Object | 下面描述|
+
+## elementList参数说明
+
+| 参数               | 说明                    |  类型   |    默认    |
+| -------------     | ------------------------| -----  | ---------------|
+| images     | 图片描述           |  Array |        多张图片   |
+| text     |文本描述          |  Array |          多个文字          |
+| qr     | 二维码面           |  Array |           多个二维码         |
+
+## images参数说明
+
+| 参数               | 说明                    |  类型   |  
+| -------------     | ------------------------| -----  | 
+| path     | 图片路径(必须可下载,h5跨域要能下载图片)           |  String |           
+| dx     |左上角x轴[必填]          |  String |       
+| dy     | 左上角y轴[必填]           |  String |   
+| dWidth     | canvas上宽度[必填]          |  String/number |       
+| dHeight     | canvas上高度[必填]]          |  String/number |
+| sx     | 源图左上角x轴[必填]         |  String/number |
+| sy     | 源图左上角y轴[必填]            |  String/number |
+| sWidth     | 源图宽            |  String/number |
+| sHeight     | 源图高            |  String/number |
+
+
+## text参数说明
+
+| 参数               | 说明                    |  类型   |  
+| -------------     | ------------------------| -----  | 
+| value     | 要展示的文字           |  String |           
+| color     |颜色          |  String |       
+| size     | 文字大小         |  String/Number |   
+| font     | 文字字体          |  String |       
+| x     | 文字左上角x轴          |  String/number |
+| y     | 文字左上角y轴           |  String/number |
+| backgroundColor     | 文字背景颜色            |  String |
+| maxWidth     | 最大渲染宽度            |  String/number |
+| maxHeight     | 最大渲染高度            |  String/number |
+
+## qr参数说明
+
+| 参数               | 说明                    |  类型   |  
+| -------------     | ------------------------| -----  | 
+| url     | 渲染地址           |  String |           
+| dx     |二维码左上角x轴          |  String |       
+| dy     | 二维码左上角y轴         |  String/Number |   
+| size     | 二维码大小       |  String/number |       
+| color| 前景色         |  String |
+| backgroundColor    | 背景色           |  String |
+
+## 可用函数说明
+
+| 函数               | 说明                    |
+| -------------     | ------------------------|
+| redraw       | 手动渲染图片      |
+| getImgSrc       | 获取图片的src[有可能是base64图片]      |
+| saveImg       | 保存图片      |

Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/common/main.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/common/runtime.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/common/vendor.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/components/kj-flow/kj-flow.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/components/kj-tabbar/kj-tabbar.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/components/zh-slidingMenu/zhSlidingMenu/zhSlidingMenu.js


+ 1 - 1
unpackage/dist/build/mp-weixin/pageA/balance.js

@@ -1 +1 @@
-require('./common/vendor.js');(global["webpackJsonp"]=global["webpackJsonp"]||[]).push([["pageA/balance"],{"038d":function(e,n,t){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0;n.default={data:function(){return{}}}},"2ecb":function(e,n,t){"use strict";t.r(n);var u=t("038d"),a=t.n(u);for(var c in u)["default"].indexOf(c)<0&&function(e){t.d(n,e,(function(){return u[e]}))}(c);n["default"]=a.a},4470:function(e,n,t){"use strict";t.d(n,"b",(function(){return u})),t.d(n,"c",(function(){return a})),t.d(n,"a",(function(){}));var u=function(){var e=this.$createElement;this._self._c},a=[]},7055:function(e,n,t){"use strict";t.r(n);var u=t("4470"),a=t("2ecb");for(var c in a)["default"].indexOf(c)<0&&function(e){t.d(n,e,(function(){return a[e]}))}(c);var r=t("828b"),i=Object(r["a"])(a["default"],u["b"],u["c"],!1,null,null,null,!1,u["a"],void 0);n["default"]=i.exports},c9be:function(e,n,t){"use strict";(function(e,n){var u=t("47a9");t("abeb");u(t("3240"));var a=u(t("7055"));e.__webpack_require_UNI_MP_PLUGIN__=t,n(a.default)}).call(this,t("3223")["default"],t("df3c")["createPage"])}},[["c9be","common/runtime","common/vendor"]]]);
+require('./common/vendor.js');(global["webpackJsonp"]=global["webpackJsonp"]||[]).push([["pageA/balance"],{"0148":function(e,n,t){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0;var u={data:function(){return{}}};n.default=u},"2a70":function(e,n,t){"use strict";t.r(n);var u=t("0148"),a=t.n(u);for(var r in u)["default"].indexOf(r)<0&&function(e){t.d(n,e,(function(){return u[e]}))}(r);n["default"]=a.a},5536:function(e,n,t){"use strict";t.r(n);var u=t("cdee"),a=t("2a70");for(var r in a)["default"].indexOf(r)<0&&function(e){t.d(n,e,(function(){return a[e]}))}(r);var c,f=t("f0c5"),i=Object(f["a"])(a["default"],u["b"],u["c"],!1,null,null,null,!1,u["a"],c);n["default"]=i.exports},5605:function(e,n,t){"use strict";(function(e,n){var u=t("4ea4");t("f93b");u(t("66fd"));var a=u(t("5536"));e.__webpack_require_UNI_MP_PLUGIN__=t,n(a.default)}).call(this,t("bc2e")["default"],t("543d")["createPage"])},cdee:function(e,n,t){"use strict";var u;t.d(n,"b",(function(){return a})),t.d(n,"c",(function(){return r})),t.d(n,"a",(function(){return u}));var a=function(){var e=this,n=e.$createElement;e._self._c},r=[]}},[["5605","common/runtime","common/vendor"]]]);

Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/pageA/changelange.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/pageA/chat/chat.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/pageA/chat/chat.wxml


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/pageA/chat/news.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/pageA/chat/news.wxml


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/pageA/comment.js


+ 1 - 1
unpackage/dist/build/mp-weixin/pageA/confirm.js

@@ -1 +1 @@
-require('./common/vendor.js');(global["webpackJsonp"]=global["webpackJsonp"]||[]).push([["pageA/confirm"],{"10a7":function(n,t,e){"use strict";e.r(t);var u=e("ea50"),c=e("53f3");for(var i in c)["default"].indexOf(i)<0&&function(n){e.d(t,n,(function(){return c[n]}))}(i);e("fcd2");var a=e("828b"),f=Object(a["a"])(c["default"],u["b"],u["c"],!1,null,"25e811c0",null,!1,u["a"],void 0);t["default"]=f.exports},"29cd":function(n,t,e){"use strict";(function(n){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var e={data:function(){return{}},computed:{i18n:function(){return this.$t("index")}},methods:{orderinfo:function(){n.switchTab({url:"/pages/mine/mine"})},toindex:function(){n.switchTab({url:"/pages/index/index"})}}};t.default=e}).call(this,e("df3c")["default"])},"4f77":function(n,t,e){},"53f3":function(n,t,e){"use strict";e.r(t);var u=e("29cd"),c=e.n(u);for(var i in u)["default"].indexOf(i)<0&&function(n){e.d(t,n,(function(){return u[n]}))}(i);t["default"]=c.a},ea50:function(n,t,e){"use strict";e.d(t,"b",(function(){return u})),e.d(t,"c",(function(){return c})),e.d(t,"a",(function(){}));var u=function(){var n=this.$createElement;this._self._c},c=[]},fcd2:function(n,t,e){"use strict";var u=e("4f77"),c=e.n(u);c.a},fdd5:function(n,t,e){"use strict";(function(n,t){var u=e("47a9");e("abeb");u(e("3240"));var c=u(e("10a7"));n.__webpack_require_UNI_MP_PLUGIN__=e,t(c.default)}).call(this,e("3223")["default"],e("df3c")["createPage"])}},[["fdd5","common/runtime","common/vendor"]]]);
+require('./common/vendor.js');(global["webpackJsonp"]=global["webpackJsonp"]||[]).push([["pageA/confirm"],{6491:function(n,t,e){"use strict";e.r(t);var u=e("92df"),a=e.n(u);for(var c in u)["default"].indexOf(c)<0&&function(n){e.d(t,n,(function(){return u[n]}))}(c);t["default"]=a.a},"6e3d":function(n,t,e){"use strict";e.r(t);var u=e("a8c7"),a=e("6491");for(var c in a)["default"].indexOf(c)<0&&function(n){e.d(t,n,(function(){return a[n]}))}(c);e("7474");var i,r=e("f0c5"),f=Object(r["a"])(a["default"],u["b"],u["c"],!1,null,"25e811c0",null,!1,u["a"],i);t["default"]=f.exports},7474:function(n,t,e){"use strict";var u=e("ac60"),a=e.n(u);a.a},"8a38":function(n,t,e){"use strict";(function(n,t){var u=e("4ea4");e("f93b");u(e("66fd"));var a=u(e("6e3d"));n.__webpack_require_UNI_MP_PLUGIN__=e,t(a.default)}).call(this,e("bc2e")["default"],e("543d")["createPage"])},"92df":function(n,t,e){"use strict";(function(n){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var e={data:function(){return{}},computed:{i18n:function(){return this.$t("index")}},methods:{orderinfo:function(){n.switchTab({url:"/pages/mine/mine"})},toindex:function(){n.switchTab({url:"/pages/index/index"})}}};t.default=e}).call(this,e("543d")["default"])},a8c7:function(n,t,e){"use strict";var u;e.d(t,"b",(function(){return a})),e.d(t,"c",(function(){return c})),e.d(t,"a",(function(){return u}));var a=function(){var n=this,t=n.$createElement;n._self._c},c=[]},ac60:function(n,t,e){}},[["8a38","common/runtime","common/vendor"]]]);

Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/pageA/counter.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/pageA/counter.wxml


+ 1 - 1
unpackage/dist/build/mp-weixin/pageA/index.js

@@ -1 +1 @@
-require('./common/vendor.js');(global["webpackJsonp"]=global["webpackJsonp"]||[]).push([["pageA/index"],{"9c25":function(e,t,n){},"9f3f":function(e,t,n){"use strict";n.r(t);var a=n("f6eb"),r=n("e35d");for(var c in r)["default"].indexOf(c)<0&&function(e){n.d(t,e,(function(){return r[e]}))}(c);n("a165");var o=n("828b"),u=Object(o["a"])(r["default"],a["b"],a["c"],!1,null,null,null,!1,a["a"],void 0);t["default"]=u.exports},a165:function(e,t,n){"use strict";var a=n("9c25"),r=n.n(a);r.a},a412:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var a={data:function(){return{code:"",characters:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}},methods:{generateRandomCode:function(){for(var e="",t=0;t<4;t++){var n=Math.floor(Math.random()*this.characters.length);e+=this.characters[n]}this.code=e,console.log(this.code)},generateCode:function(){this.generateRandomCode()}},mounted:function(){this.generateCode()}};t.default=a},ca23:function(e,t,n){"use strict";(function(e,t){var a=n("47a9");n("abeb");a(n("3240"));var r=a(n("9f3f"));e.__webpack_require_UNI_MP_PLUGIN__=n,t(r.default)}).call(this,n("3223")["default"],n("df3c")["createPage"])},e35d:function(e,t,n){"use strict";n.r(t);var a=n("a412"),r=n.n(a);for(var c in a)["default"].indexOf(c)<0&&function(e){n.d(t,e,(function(){return a[e]}))}(c);t["default"]=r.a},f6eb:function(e,t,n){"use strict";n.d(t,"b",(function(){return a})),n.d(t,"c",(function(){return r})),n.d(t,"a",(function(){}));var a=function(){var e=this.$createElement;this._self._c},r=[]}},[["ca23","common/runtime","common/vendor"]]]);
+require('./common/vendor.js');(global["webpackJsonp"]=global["webpackJsonp"]||[]).push([["pageA/index"],{"0387":function(e,t,n){"use strict";var a=n("b61b"),r=n.n(a);r.a},"73d5":function(e,t,n){"use strict";var a;n.d(t,"b",(function(){return r})),n.d(t,"c",(function(){return c})),n.d(t,"a",(function(){return a}));var r=function(){var e=this,t=e.$createElement;e._self._c},c=[]},b00b:function(e,t,n){"use strict";n.r(t);var a=n("73d5"),r=n("e3c0");for(var c in r)["default"].indexOf(c)<0&&function(e){n.d(t,e,(function(){return r[e]}))}(c);n("0387");var o,u=n("f0c5"),i=Object(u["a"])(r["default"],a["b"],a["c"],!1,null,null,null,!1,a["a"],o);t["default"]=i.exports},b61b:function(e,t,n){},cde8:function(e,t,n){"use strict";(function(e,t){var a=n("4ea4");n("f93b");a(n("66fd"));var r=a(n("b00b"));e.__webpack_require_UNI_MP_PLUGIN__=n,t(r.default)}).call(this,n("bc2e")["default"],n("543d")["createPage"])},e3c0:function(e,t,n){"use strict";n.r(t);var a=n("f05a"),r=n.n(a);for(var c in a)["default"].indexOf(c)<0&&function(e){n.d(t,e,(function(){return a[e]}))}(c);t["default"]=r.a},f05a:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var a={data:function(){return{code:"",characters:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}},methods:{generateRandomCode:function(){for(var e="",t=0;t<4;t++){var n=Math.floor(Math.random()*this.characters.length);e+=this.characters[n]}this.code=e,console.log(this.code)},generateCode:function(){this.generateRandomCode()}},mounted:function(){this.generateCode()}};t.default=a}},[["cde8","common/runtime","common/vendor"]]]);

Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/pageA/logisticsinfo.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/pageA/order.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/pageA/order.wxml


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/pageA/payorder.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/pageA/payorder.wxml


+ 5 - 1
unpackage/dist/build/mp-weixin/pageA/payorder.wxss

@@ -1 +1,5 @@
-.payment.data-v-5dcbc573{font-family:PingFangSC,PingFang SC;font-weight:500;font-size:24rpx;color:#222;line-height:34rpx;text-align:left;font-style:normal}.content.data-v-5dcbc573{font-family:PingFangSC,PingFang SC;font-weight:400;font-size:20rpx;color:#777;line-height:28rpx;text-align:left;font-style:normal}.stateac.data-v-5dcbc573{font-family:PingFangSC,PingFang SC;font-weight:400;font-size:24rpx;color:#ff1515;line-height:34rpx;text-align:left;font-style:normal}.unstate.data-v-5dcbc573{font-family:PingFangSC,PingFang SC;font-weight:400;font-size:24rpx;color:#222;line-height:34rpx;text-align:left;font-style:normal}.confirm.data-v-5dcbc573{position:fixed;bottom:66rpx;width:702rpx;height:84rpx;background:#f83224;border-radius:44rpx;font-family:PingFangSC,PingFang SC;font-weight:500;font-size:32rpx;color:#fff;line-height:84rpx;text-align:center;font-style:normal}.payitem.data-v-5dcbc573{width:702rpx;height:140rpx;background:#fff;border-radius:12rpx;padding:34rpx 24rpx;box-sizing:border-box}.back.data-v-5dcbc573{padding:20rpx 24rpx;box-sizing:border-box}.back .topbox.data-v-5dcbc573{position:relative}.back .topbox .state.data-v-5dcbc573{background:#fff;border-radius:6rpx;padding:12rpx;box-sizing:border-box}.back .topbox .paysum.data-v-5dcbc573{font-family:PingFangSC,PingFang SC;font-weight:400;font-size:28rpx;color:#222;line-height:40rpx;text-align:left;font-style:normal}.back .topbox .numbe.data-v-5dcbc573{font-family:HarmonyOS_Sans_Medium;font-size:28rpx;color:#000;line-height:38rpx;text-align:left;font-style:normal;margin-top:20rpx}
+<<<<<<< HEAD
+.payment.data-v-5dcbc573{font-family:PingFangSC,PingFang SC;font-weight:500;font-size:24rpx;color:#222;line-height:34rpx;text-align:left;font-style:normal}.content.data-v-5dcbc573{font-family:PingFangSC,PingFang SC;font-weight:400;font-size:20rpx;color:#777;line-height:28rpx;text-align:left;font-style:normal}.stateac.data-v-5dcbc573{font-family:PingFangSC,PingFang SC;font-weight:400;font-size:24rpx;color:#ff1515;line-height:34rpx;text-align:left;font-style:normal}.unstate.data-v-5dcbc573{font-family:PingFangSC,PingFang SC;font-weight:400;font-size:24rpx;color:#222;line-height:34rpx;text-align:left;font-style:normal}.confirm.data-v-5dcbc573{position:fixed;bottom:66rpx;width:702rpx;height:84rpx;background:#f83224;border-radius:44rpx;font-family:PingFangSC,PingFang SC;font-weight:500;font-size:32rpx;color:#fff;line-height:84rpx;text-align:center;font-style:normal}.payitem.data-v-5dcbc573{width:702rpx;height:140rpx;background:#fff;border-radius:12rpx;padding:34rpx 24rpx;box-sizing:border-box}.back.data-v-5dcbc573{padding:20rpx 24rpx;box-sizing:border-box}.back .topbox.data-v-5dcbc573{position:relative}.back .topbox .state.data-v-5dcbc573{background:#fff;border-radius:6rpx;padding:12rpx;box-sizing:border-box}.back .topbox .paysum.data-v-5dcbc573{font-family:PingFangSC,PingFang SC;font-weight:400;font-size:28rpx;color:#222;line-height:40rpx;text-align:left;font-style:normal}.back .topbox .numbe.data-v-5dcbc573{font-family:HarmonyOS_Sans_Medium;font-size:28rpx;color:#000;line-height:38rpx;text-align:left;font-style:normal;margin-top:20rpx}
+=======
+.payment.data-v-55906226{font-family:PingFangSC,PingFang SC;font-weight:500;font-size:24rpx;color:#222;line-height:34rpx;text-align:left;font-style:normal}.content.data-v-55906226{font-family:PingFangSC,PingFang SC;font-weight:400;font-size:20rpx;color:#777;line-height:28rpx;text-align:left;font-style:normal}.stateac.data-v-55906226{font-family:PingFangSC,PingFang SC;font-weight:400;font-size:24rpx;color:#ff1515;line-height:34rpx;text-align:left;font-style:normal}.unstate.data-v-55906226{font-family:PingFangSC,PingFang SC;font-weight:400;font-size:24rpx;color:#222;line-height:34rpx;text-align:left;font-style:normal}.confirm.data-v-55906226{position:fixed;bottom:66rpx;width:702rpx;height:84rpx;background:#f83224;border-radius:44rpx;font-family:PingFangSC,PingFang SC;font-weight:500;font-size:32rpx;color:#fff;line-height:84rpx;text-align:center;font-style:normal}.payitem.data-v-55906226{width:702rpx;height:140rpx;background:#fff;border-radius:12rpx;padding:34rpx 24rpx;box-sizing:border-box}.back.data-v-55906226{padding:20rpx 24rpx;box-sizing:border-box}.back .topbox.data-v-55906226{position:relative}.back .topbox .state.data-v-55906226{background:#fff;border-radius:6rpx;padding:12rpx;box-sizing:border-box}.back .topbox .paysum.data-v-55906226{font-family:PingFangSC,PingFang SC;font-weight:400;font-size:28rpx;color:#222;line-height:40rpx;text-align:left;font-style:normal}.back .topbox .numbe.data-v-55906226{font-family:HarmonyOS_Sans_Medium;font-size:28rpx;color:#000;line-height:38rpx;text-align:left;font-style:normal;margin-top:20rpx}
+>>>>>>> 3aae73a792e3fefab7103cbdce52cc9f366debc5

Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/pageA/productdetails.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/pageA/rule/rule.js


+ 1 - 1
unpackage/dist/build/mp-weixin/pageA/service/service.js

@@ -1 +1 @@
-require('../common/vendor.js');(global["webpackJsonp"]=global["webpackJsonp"]||[]).push([["pageA/service/service"],{1750:function(n,e,t){"use strict";(function(n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;var t={data:function(){return{}},methods:{retu:function(){n.navigateBack()}}};e.default=t}).call(this,t("df3c")["default"])},"2ad7":function(n,e,t){},"3b72":function(n,e,t){"use strict";t.r(e);var u=t("6fdd"),a=t("cc53");for(var c in a)["default"].indexOf(c)<0&&function(n){t.d(e,n,(function(){return a[n]}))}(c);t("9473");var r=t("828b"),i=Object(r["a"])(a["default"],u["b"],u["c"],!1,null,null,null,!1,u["a"],void 0);e["default"]=i.exports},"6fdd":function(n,e,t){"use strict";t.d(e,"b",(function(){return a})),t.d(e,"c",(function(){return c})),t.d(e,"a",(function(){return u}));var u={uNavbar:function(){return Promise.all([t.e("common/vendor"),t.e("uview-ui/components/u-navbar/u-navbar")]).then(t.bind(null,"f3ae"))},uIcon:function(){return Promise.all([t.e("common/vendor"),t.e("uview-ui/components/u-icon/u-icon")]).then(t.bind(null,"b73a"))}},a=function(){var n=this.$createElement;this._self._c},c=[]},9473:function(n,e,t){"use strict";var u=t("2ad7"),a=t.n(u);a.a},"99ba":function(n,e,t){"use strict";(function(n,e){var u=t("47a9");t("abeb");u(t("3240"));var a=u(t("3b72"));n.__webpack_require_UNI_MP_PLUGIN__=t,e(a.default)}).call(this,t("3223")["default"],t("df3c")["createPage"])},cc53:function(n,e,t){"use strict";t.r(e);var u=t("1750"),a=t.n(u);for(var c in u)["default"].indexOf(c)<0&&function(n){t.d(e,n,(function(){return u[n]}))}(c);e["default"]=a.a}},[["99ba","common/runtime","common/vendor"]]]);
+require('../common/vendor.js');(global["webpackJsonp"]=global["webpackJsonp"]||[]).push([["pageA/service/service"],{"277f":function(n,e,t){"use strict";t.r(e);var u=t("3fe9"),c=t("c5ad");for(var a in c)["default"].indexOf(a)<0&&function(n){t.d(e,n,(function(){return c[n]}))}(a);t("c8a7");var r,o=t("f0c5"),i=Object(o["a"])(c["default"],u["b"],u["c"],!1,null,null,null,!1,u["a"],r);e["default"]=i.exports},"2bce":function(n,e,t){"use strict";(function(n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;var t={data:function(){return{}},methods:{retu:function(){n.navigateBack()}}};e.default=t}).call(this,t("543d")["default"])},"3fe9":function(n,e,t){"use strict";t.d(e,"b",(function(){return c})),t.d(e,"c",(function(){return a})),t.d(e,"a",(function(){return u}));var u={uNavbar:function(){return Promise.all([t.e("common/vendor"),t.e("uview-ui/components/u-navbar/u-navbar")]).then(t.bind(null,"b6bd"))},uIcon:function(){return Promise.all([t.e("common/vendor"),t.e("uview-ui/components/u-icon/u-icon")]).then(t.bind(null,"01eb"))}},c=function(){var n=this,e=n.$createElement;n._self._c},a=[]},ad23:function(n,e,t){"use strict";(function(n,e){var u=t("4ea4");t("f93b");u(t("66fd"));var c=u(t("277f"));n.__webpack_require_UNI_MP_PLUGIN__=t,e(c.default)}).call(this,t("bc2e")["default"],t("543d")["createPage"])},c5ad:function(n,e,t){"use strict";t.r(e);var u=t("2bce"),c=t.n(u);for(var a in u)["default"].indexOf(a)<0&&function(n){t.d(e,n,(function(){return u[n]}))}(a);e["default"]=c.a},c8a7:function(n,e,t){"use strict";var u=t("df3c"),c=t.n(u);c.a},df3c:function(n,e,t){}},[["ad23","common/runtime","common/vendor"]]]);

Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/pageA/shoplist.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/pageA/shoplist.wxml


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/pageA/shoptype.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/pageA/subsidy.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/pageA/subsidy.wxml


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/pageB/ParcelExpress.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/pageB/ParcelExpress.wxml


+ 1 - 1
unpackage/dist/build/mp-weixin/pageB/Senderinfor.js

@@ -1 +1 @@
-(global["webpackJsonp"]=global["webpackJsonp"]||[]).push([["pageB/Senderinfor"],{3160:function(n,e,t){"use strict";t.d(e,"b",(function(){return u})),t.d(e,"c",(function(){return c})),t.d(e,"a",(function(){return o}));var o={uIcon:function(){return Promise.all([t.e("common/vendor"),t.e("uview-ui/components/u-icon/u-icon")]).then(t.bind(null,"b73a"))},uCheckboxGroup:function(){return Promise.all([t.e("common/vendor"),t.e("uview-ui/components/u-checkbox-group/u-checkbox-group")]).then(t.bind(null,"c952"))},uCheckbox:function(){return Promise.all([t.e("common/vendor"),t.e("uview-ui/components/u-checkbox/u-checkbox")]).then(t.bind(null,"5fa3"))}},u=function(){var n=this.$createElement;this._self._c},c=[]},"3f1dd":function(n,e,t){"use strict";t.r(e);var o=t("ef2d"),u=t.n(o);for(var c in o)["default"].indexOf(c)<0&&function(n){t.d(e,n,(function(){return o[n]}))}(c);e["default"]=u.a},"791e":function(n,e,t){"use strict";(function(n,e){var o=t("47a9");t("abeb");o(t("3240"));var u=o(t("acf1"));n.__webpack_require_UNI_MP_PLUGIN__=t,e(u.default)}).call(this,t("3223")["default"],t("df3c")["createPage"])},"8f3e":function(n,e,t){"use strict";var o=t("94a0"),u=t.n(o);u.a},"94a0":function(n,e,t){},acf1:function(n,e,t){"use strict";t.r(e);var o=t("3160"),u=t("3f1dd");for(var c in u)["default"].indexOf(c)<0&&function(n){t.d(e,n,(function(){return u[n]}))}(c);t("8f3e");var i=t("828b"),r=Object(i["a"])(u["default"],o["b"],o["c"],!1,null,null,null,!1,o["a"],void 0);e["default"]=r.exports},ef2d:function(n,e,t){"use strict";(function(n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;var t={data:function(){return{checkboxValue1:[],name:1}},computed:{i18n:function(){return this.$t("index")}},onShow:function(){n.setNavigationBarTitle({title:this.i18n.goods})},methods:{checkboxChange:function(n){console.log("change",n)}}};e.default=t}).call(this,t("df3c")["default"])}},[["791e","common/runtime","common/vendor"]]]);
+(global["webpackJsonp"]=global["webpackJsonp"]||[]).push([["pageB/Senderinfor"],{"233a":function(n,e,t){},2365:function(n,e,t){"use strict";t.r(e);var o=t("9b26"),u=t.n(o);for(var c in o)["default"].indexOf(c)<0&&function(n){t.d(e,n,(function(){return o[n]}))}(c);e["default"]=u.a},"4b35":function(n,e,t){"use strict";(function(n,e){var o=t("4ea4");t("f93b");o(t("66fd"));var u=o(t("5172"));n.__webpack_require_UNI_MP_PLUGIN__=t,e(u.default)}).call(this,t("bc2e")["default"],t("543d")["createPage"])},5172:function(n,e,t){"use strict";t.r(e);var o=t("7a38"),u=t("2365");for(var c in u)["default"].indexOf(c)<0&&function(n){t.d(e,n,(function(){return u[n]}))}(c);t("faca");var i,r=t("f0c5"),a=Object(r["a"])(u["default"],o["b"],o["c"],!1,null,null,null,!1,o["a"],i);e["default"]=a.exports},"7a38":function(n,e,t){"use strict";t.d(e,"b",(function(){return u})),t.d(e,"c",(function(){return c})),t.d(e,"a",(function(){return o}));var o={uIcon:function(){return Promise.all([t.e("common/vendor"),t.e("uview-ui/components/u-icon/u-icon")]).then(t.bind(null,"01eb"))},uCheckboxGroup:function(){return Promise.all([t.e("common/vendor"),t.e("uview-ui/components/u-checkbox-group/u-checkbox-group")]).then(t.bind(null,"72c8"))},uCheckbox:function(){return Promise.all([t.e("common/vendor"),t.e("uview-ui/components/u-checkbox/u-checkbox")]).then(t.bind(null,"d2b4"))}},u=function(){var n=this,e=n.$createElement;n._self._c},c=[]},"9b26":function(n,e,t){"use strict";(function(n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;var t={data:function(){return{checkboxValue1:[],name:1}},computed:{i18n:function(){return this.$t("index")}},onShow:function(){n.setNavigationBarTitle({title:this.i18n.goods})},methods:{checkboxChange:function(n){console.log("change",n)}}};e.default=t}).call(this,t("543d")["default"])},faca:function(n,e,t){"use strict";var o=t("233a"),u=t.n(o);u.a}},[["4b35","common/runtime","common/vendor"]]]);

+ 1 - 1
unpackage/dist/build/mp-weixin/pageB/Senderinfor.wxml

@@ -1 +1 @@
-<view class="back"><view class="info"><view class="item u-flex u-row-between"><text class="title">{{i18n.senderinfo}}</text><view class="u-flex"><u-icon vue-id="a383861e-1" name="order" color="rgba(0, 0, 0, 0.6)" size="23" bind:__l="__l"></u-icon><text class="wx">{{i18n.wxAddress}}</text></view></view><view class="item u-flex"><text class="left">{{i18n.name}}</text><view class="right"><input type="text" placeholder="{{i18n.Fill}}"/></view></view><view class="item u-flex"><text class="left">{{i18n.phone}}</text><view class="right"><input type="text" placeholder="{{i18n.Fill}}"/></view></view><view class="item u-flex"><text class="left">{{i18n.city}}</text><view class="right"><input type="text" placeholder="{{i18n.selection}}" disabled/></view></view><view class="item u-flex"><text class="left">{{i18n.detailed}}</text><view class="right"><input type="area" placeholder="{{i18n.Fill}}" disabled/></view></view><view class="item u-flex"><input type="area" placeholder="{{i18n.company}}"/></view><view class="u-flex u-row-between" style="margin-top:22rpx;"><view class="u-flex"><view><u-checkbox-group vue-id="a383861e-2" placement="row" value="{{checkboxValue1}}" data-event-opts="{{[['^change',[['checkboxChange']]],['^input',[['__set_model',['','checkboxValue1','$event',[]]]]]]}}" bind:change="__e" bind:input="__e" bind:__l="__l" vue-slots="{{['default']}}"><u-checkbox vue-id="{{('a383861e-3')+','+('a383861e-2')}}" shape="circle" customStyle="{{({marginRight:'4px'})}}" name="{{name}}" bind:__l="__l"></u-checkbox></u-checkbox-group></view><text class="clear">{{i18n.initial}}</text></view><text class="clear">{{''+i18n.empty+''}}</text></view></view><view class="history">{{i18n.history}}</view><view class="add"><view><text class="name">陈盼盼</text><text class="phone">176****3298</text></view><view class="addinfo">江苏省南京市浦口区浦口大道东方万汇城北区</view></view><view class="bottom"><view class="btn">{{''+i18n.enter+''}}</view></view></view>
+<view class="back"><view class="info"><view class="item u-flex u-row-between"><text class="title">{{i18n.senderinfo}}</text><view class="u-flex"><u-icon vue-id="a383861e-1" name="order" color="rgba(0, 0, 0, 0.6)" size="23" bind:__l="__l"></u-icon><text class="wx">{{i18n.wxAddress}}</text></view></view><view class="item u-flex "><text class="left">{{i18n.name}}</text><view class="right"><input type="text" placeholder="{{i18n.Fill}}"/></view></view><view class="item u-flex "><text class="left">{{i18n.phone}}</text><view class="right"><input type="text" placeholder="{{i18n.Fill}}"/></view></view><view class="item u-flex "><text class="left">{{i18n.city}}</text><view class="right"><input type="text" placeholder="{{i18n.selection}}" disabled/></view></view><view class="item u-flex "><text class="left">{{i18n.detailed}}</text><view class="right"><input type="area" placeholder="{{i18n.Fill}}" disabled/></view></view><view class="item u-flex "><input type="area" placeholder="{{i18n.company}}"/></view><view class="u-flex u-row-between" style="margin-top:22rpx;"><view class="u-flex"><view><u-checkbox-group vue-id="a383861e-2" placement="row" value="{{checkboxValue1}}" data-event-opts="{{[['^change',[['checkboxChange']]],['^input',[['__set_model',['','checkboxValue1','$event',[]]]]]]}}" bind:change="__e" bind:input="__e" bind:__l="__l" vue-slots="{{['default']}}"><u-checkbox vue-id="{{('a383861e-3')+','+('a383861e-2')}}" shape="circle" customStyle="{{({marginRight:'4px'})}}" name="{{name}}" bind:__l="__l"></u-checkbox></u-checkbox-group></view><text class="clear">{{i18n.initial}}</text></view><text class="clear">{{''+i18n.empty+''}}</text></view></view><view class="history">{{i18n.history}}</view><view class="add"><view><text class="name">陈盼盼</text><text class="phone">176****3298</text></view><view class="addinfo">江苏省南京市浦口区浦口大道东方万汇城北区</view></view><view class="bottom"><view class="btn">{{''+i18n.enter+''}}</view></view></view>

Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/pageB/account.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/pageB/account.wxml


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/pageB/citychange.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/pageB/delivery.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/pageB/delivery.wxml


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/pageB/end.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/pageB/end.wxml


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/pageB/expresstype.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/pageB/goods.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
unpackage/dist/build/mp-weixin/pageB/goods.wxml


+ 1 - 1
unpackage/dist/build/mp-weixin/pageB/index.js

@@ -1 +1 @@
-(global["webpackJsonp"]=global["webpackJsonp"]||[]).push([["pageB/index"],{1260:function(n,t,e){"use strict";e.r(t);var u=e("23f4"),a=e("8646");for(var r in a)["default"].indexOf(r)<0&&function(n){e.d(t,n,(function(){return a[n]}))}(r);var c=e("828b"),f=Object(c["a"])(a["default"],u["b"],u["c"],!1,null,null,null,!1,u["a"],void 0);t["default"]=f.exports},"23f4":function(n,t,e){"use strict";e.d(t,"b",(function(){return u})),e.d(t,"c",(function(){return a})),e.d(t,"a",(function(){}));var u=function(){var n=this.$createElement;this._self._c},a=[]},3201:function(n,t,e){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;t.default={data:function(){return{}}}},5459:function(n,t,e){"use strict";(function(n,t){var u=e("47a9");e("abeb");u(e("3240"));var a=u(e("1260"));n.__webpack_require_UNI_MP_PLUGIN__=e,t(a.default)}).call(this,e("3223")["default"],e("df3c")["createPage"])},8646:function(n,t,e){"use strict";e.r(t);var u=e("3201"),a=e.n(u);for(var r in u)["default"].indexOf(r)<0&&function(n){e.d(t,n,(function(){return u[n]}))}(r);t["default"]=a.a}},[["5459","common/runtime","common/vendor"]]]);
+(global["webpackJsonp"]=global["webpackJsonp"]||[]).push([["pageB/index"],{"37ba":function(e,n,t){"use strict";t.r(n);var u=t("c91e"),r=t.n(u);for(var a in u)["default"].indexOf(a)<0&&function(e){t.d(n,e,(function(){return u[e]}))}(a);n["default"]=r.a},"6f72":function(e,n,t){"use strict";t.r(n);var u=t("72bd"),r=t("37ba");for(var a in r)["default"].indexOf(a)<0&&function(e){t.d(n,e,(function(){return r[e]}))}(a);var c,f=t("f0c5"),i=Object(f["a"])(r["default"],u["b"],u["c"],!1,null,null,null,!1,u["a"],c);n["default"]=i.exports},"72bd":function(e,n,t){"use strict";var u;t.d(n,"b",(function(){return r})),t.d(n,"c",(function(){return a})),t.d(n,"a",(function(){return u}));var r=function(){var e=this,n=e.$createElement;e._self._c},a=[]},"748e":function(e,n,t){"use strict";(function(e,n){var u=t("4ea4");t("f93b");u(t("66fd"));var r=u(t("6f72"));e.__webpack_require_UNI_MP_PLUGIN__=t,n(r.default)}).call(this,t("bc2e")["default"],t("543d")["createPage"])},c91e:function(e,n,t){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0;var u={data:function(){return{}}};n.default=u}},[["748e","common/runtime","common/vendor"]]]);

Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff