diff --git a/README.md b/README.md index 516bbff..a102578 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,6 @@ ## 属性说明 - @@ -16,9 +15,16 @@ - - + + + + + + + + +

组件属性

value二维码内容
template样式模板,可选:'default','water','star'
level纠错等级,可选:'M','L','H','Q'
template样式模板,可选:'default','water','diamond','hexagon','star','rect','bar','heart','glitter','fusion'
level纠错等级,可选:'M','L','Q','H'
width二维码宽度,默认:300
height二维码高度,默认:300
logologo图片地址
background-image背景图片地址
foreground-image前景图片地址
background-color背景色,默认:#ffffff
foreground-color前景色,默认:#000000;(多色用逗号分隔)
inner-color定位点内层颜色,默认:#000000
outer-color定位点外层颜色,默认:#000000
diff --git a/dist/widget-qrcode.min.js b/dist/widget-qrcode.min.js index db4f57a..9f31064 100644 --- a/dist/widget-qrcode.min.js +++ b/dist/widget-qrcode.min.js @@ -8,8 +8,6 @@ * Released under the MIT License * https://github.com/mumuy/widget-qrcode * - * Created on: 2024-05-15 + * Created on: 2024-05-26 */ -!function(){"use strict";function t(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=new Array(e);r65536?(n[0]=240|(1835008&a)>>>18,n[1]=128|(258048&a)>>>12,n[2]=128|(4032&a)>>>6,n[3]=128|63&a):a>2048?(n[0]=224|(61440&a)>>>12,n[1]=128|(4032&a)>>>6,n[2]=128|63&a):a>128?(n[0]=192|(1984&a)>>>6,n[1]=128|63&a):n[0]=a,this.parsedData.push(n)}this.parsedData=Array.prototype.concat.apply([],this.parsedData),this.parsedData.length!=this.data.length&&(this.parsedData.unshift(191),this.parsedData.unshift(187),this.parsedData.unshift(239))}function m(){this.buffer=[],this.length=0}p.prototype={getLength:function(t){return this.parsedData.length},write:function(t){for(var e=0,r=this.parsedData.length;e>>7-t%8&1)},put:function(t,e){for(var r=0;r>>e-r-1&1))},getLengthInBits:function(){return this.length},putBit:function(t){var e=Math.floor(this.length/8);this.buffer.length<=e&&this.buffer.push(0),t&&(this.buffer[e]|=128>>>this.length%8),this.length++}};for(var y={glog:function(t){if(t<1)throw new Error("glog("+t+")");return y.LOG_TABLE[t]},gexp:function(t){for(;t<0;)t+=255;for(;t>=256;)t-=255;return y.EXP_TABLE[t]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},b=0;b<8;b++)y.EXP_TABLE[b]=1<=0;)e^=S.G15<=0;)e^=S.G18<>>=1;return e},getPatternPosition:function(t){return S.PATTERN_POSITION_TABLE[t-1]},getMask:function(t,e,r){switch(t){case L:return(e+r)%2==0;case M:return e%2==0;case B:return r%3==0;case A:return(e+r)%3==0;case T:return(Math.floor(e/2)+Math.floor(r/3))%2==0;case E:return e*r%2+e*r%3==0;case D:return(e*r%2+e*r%3)%2==0;case I:return(e*r%3+(e+r)%2)%2==0;default:throw new Error("bad maskPattern:"+t)}},getErrorCorrectPolynomial:function(t){for(var e=new C([1],0),r=0;r5&&(r+=3+o-5)}for(var l=0;lc.length)throw new Error("Too long data");return r}function O(t,e,r,n,a){var o,i;switch(n){case 0:o=e*a,i=r*a,t.lineTo(o,i);break;case 1:o=e*a+a,i=r*a,t.lineTo(o,i);break;case 2:o=e*a+a,i=r*a+a,t.lineTo(o,i);break;case 3:o=e*a,i=r*a+a,t.lineTo(o,i)}}function V(t,e,r,n,a){var o,i,u=a/2;switch(n){case 0:o=e*a+u,i=r*a+u,t.arc(o,i,u,Math.PI,1.5*Math.PI,!1);break;case 1:o=e*a+a-u,i=r*a+u,t.arc(o,i,u,1.5*Math.PI,2*Math.PI,!1);break;case 2:o=e*a+a-u,i=r*a+a-u,t.arc(o,i,u,0,Math.PI/2,!1);break;case 3:o=e*a+u,i=r*a+a-u,t.arc(o,i,u,Math.PI/2,Math.PI,!1)}}function x(t,e,r,n,a){var o,i,u=a/2;switch(t.beginPath(),n){case 0:o=e*a+u,i=r*a+u,t.arc(o,i,u,Math.PI,1.5*Math.PI,!1),o=e*a,i=r*a;break;case 1:o=e*a+a-u,i=r*a+u,t.arc(o,i,u,1.5*Math.PI,2*Math.PI,!1),o=e*a+a,i=r*a;break;case 2:o=e*a+a-u,i=r*a+a-u,t.arc(o,i,u,0,Math.PI/2,!1),o=e*a+a,i=r*a+a;break;case 3:o=e*a+u,i=r*a+a-u,t.arc(o,i,u,Math.PI/2,Math.PI,!1),o=e*a,i=r*a+a}t.lineTo(o,i),t.closePath(),t.fill(),t.stroke()}function H(t){return{getValue:function(e,r){var n;return null==t||null===(n=t[e])||void 0===n?void 0:n[r]},isPositionPoint:function(e,r){if(!t)return!1;var n=t.length,a=0;return e>=2&&e<5&&r>=2&&r<5?a=1:e<7&&r<7?a=2:e>=n-5&&e=2&r<5?a=1:e>=n-7&&e=0&r<7?a=2:e>=2&&e<5&&r>=n-5&r=0&&e<7&&r>=n-7&r=o||u>=o||(t[i][u]=2)}}}R.prototype={addData:function(t){var e=new p(t);this.dataList.push(e),this.dataCache=null},isDark:function(t,e){if(t<0||this.moduleCount<=t||e<0||this.moduleCount<=e)throw new Error(t+","+e);return this.modules[t][e]},getModuleCount:function(){return this.moduleCount},make:function(){this.makeImpl(!1,this.getBestMaskPattern())},makeImpl:function(t,e){this.moduleCount=4*this.typeNumber+17,this.modules=new Array(this.moduleCount);for(var r=0;r=7&&this.setupTypeNumber(t),null==this.dataCache&&(this.dataCache=R.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,e)},setupPositionProbePattern:function(t,e){for(var r=-1;r<=7;r++)if(!(t+r<=-1||this.moduleCount<=t+r))for(var n=-1;n<=7;n++)e+n<=-1||this.moduleCount<=e+n||(this.modules[t+r][e+n]=0<=r&&r<=6&&(0==n||6==n)||0<=n&&n<=6&&(0==r||6==r)||2<=r&&r<=4&&2<=n&&n<=4)},getBestMaskPattern:function(){for(var t=0,e=0,r=0;r<8;r++){this.makeImpl(!0,r);var n=S.getLostPoint(this);(0==r||t>n)&&(t=n,e=r)}return e},createMovieClip:function(t,e,r){var n=t.createEmptyMovieClip(e,r);this.make();for(var a=0;a>r&1);this.modules[Math.floor(r/3)][r%3+this.moduleCount-8-3]=n}for(var a=0;a<18;a++){var o=!t&&1==(e>>a&1);this.modules[a%3+this.moduleCount-8-3][Math.floor(a/3)]=o}},setupTypeInfo:function(t,e){for(var r=this.errorCorrectLevel<<3|e,n=S.getBCHTypeInfo(r),a=0;a<15;a++){var o=!t&&1==(n>>a&1);a<6?this.modules[a][8]=o:a<8?this.modules[a+1][8]=o:this.modules[this.moduleCount-15+a][8]=o}for(var i=0;i<15;i++){var u=!t&&1==(n>>i&1);i<8?this.modules[8][this.moduleCount-i-1]=u:i<9?this.modules[8][15-i-1+1]=u:this.modules[8][15-i-1]=u}this.modules[this.moduleCount-8][8]=!t},mapData:function(t,e){for(var r=-1,n=this.moduleCount-1,a=7,o=0,i=this.moduleCount-1;i>0;i-=2)for(6==i&&i--;;){for(var u=0;u<2;u++)if(null==this.modules[n][i-u]){var s=!1;o>>a&1)),S.getMask(e,n,i-u)&&(s=!s),this.modules[n][i-u]=s,-1==--a&&(o++,a=7)}if((n+=r)<0||this.moduleCount<=n){n-=r,r=-r;break}}}},R.PAD0=236,R.PAD1=17,R.createData=function(t,e,r){for(var n=k.getRSBlocks(t,e),a=new m,o=0;o8*u)throw new Error("code length overflow. ("+a.getLengthInBits()+">"+8*u+")");for(a.getLengthInBits()+4<=8*u&&a.put(0,4);a.getLengthInBits()%8!=0;)a.putBit(!1);for(;!(a.getLengthInBits()>=8*u||(a.put(R.PAD0,8),a.getLengthInBits()>=8*u));)a.put(R.PAD1,8);return R.createBytes(a,n)},R.createBytes=function(t,e){for(var r=0,n=0,a=0,o=new Array(e.length),i=new Array(e.length),u=0;u=0?f.get(d):0}}for(var v=0,p=0;p\n \n ',e.$module=e.shadowRoot.querySelector(".mod-qrcode"),e.$canvas=e.$module.querySelector("canvas"),e.context=e.$canvas.getContext("2d"),e.resize(),"undefined"!=typeof ResizeObserver&&new ResizeObserver((function(){e.resize()})).observe(e)}},{key:"resize",value:function(){var t=this,e=Math.max(t.clientWidth,t.clientHeight);t.$canvas.width=2*e,t.$canvas.height=2*e,t.drawQRCode()}},{key:"drawQRCode",value:function(){var t=this,e=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"https://passer-by.com/",e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"H",r=new R(_(t,h[e]),h[e]);return r.addData(t),r.make(),r.modules}(t.value,t.level);t.context.clearRect(0,0,t.$canvas.width,t.$canvas.height),(j[t.template]||j.default)(t.context,e,{})}}],i=[{key:"observedAttributes",get:function(){return["value","template","level","width","height"]}}],n&&a(r.prototype,n),i&&a(r,i),Object.defineProperty(r,"prototype",{writable:!1}),s}(l(HTMLElement));customElements.get("widget-qrcode")||customElements.define("widget-qrcode",z)}(); +!function(){"use strict";function e(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,o=new Array(t);r65536?(o[0]=240|(1835008&a)>>>18,o[1]=128|(258048&a)>>>12,o[2]=128|(4032&a)>>>6,o[3]=128|63&a):a>2048?(o[0]=224|(61440&a)>>>12,o[1]=128|(4032&a)>>>6,o[2]=128|63&a):a>128?(o[0]=192|(1984&a)>>>6,o[1]=128|63&a):o[0]=a,this.parsedData.push(o)}this.parsedData=Array.prototype.concat.apply([],this.parsedData),this.parsedData.length!=this.data.length&&(this.parsedData.unshift(191),this.parsedData.unshift(187),this.parsedData.unshift(239))}function b(){this.buffer=[],this.length=0}m.prototype={getLength:function(e){return this.parsedData.length},write:function(e){for(var t=0,r=this.parsedData.length;t>>7-e%8&1)},put:function(e,t){for(var r=0;r>>t-r-1&1))},getLengthInBits:function(){return this.length},putBit:function(e){var t=Math.floor(this.length/8);this.buffer.length<=t&&this.buffer.push(0),e&&(this.buffer[t]|=128>>>this.length%8),this.length++}};for(var P={glog:function(e){if(e<1)throw new Error("glog("+e+")");return P.LOG_TABLE[e]},gexp:function(e){for(;e<0;)e+=255;for(;e>=256;)e-=255;return P.EXP_TABLE[e]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},I=0;I<8;I++)P.EXP_TABLE[I]=1<=0;)t^=D.G15<=0;)t^=D.G18<>>=1;return t},getPatternPosition:function(e){return D.PATTERN_POSITION_TABLE[e-1]},getMask:function(e,t,r){switch(e){case C:return(t+r)%2==0;case T:return t%2==0;case S:return r%3==0;case R:return(t+r)%3==0;case M:return(Math.floor(t/2)+Math.floor(r/3))%2==0;case B:return t*r%2+t*r%3==0;case A:return(t*r%2+t*r%3)%2==0;case L:return(t*r%3+(t+r)%2)%2==0;default:throw new Error("bad maskPattern:"+e)}},getErrorCorrectPolynomial:function(e){for(var t=new k([1],0),r=0;r5&&(r+=3+n-5)}for(var g=0;gf.length)throw new Error("Too long data");return r}function _(e,t,r){return{imageReady:function(e){var t={},r=Object.entries(e).map((function(e){return new Promise((function(r){var o=new Image;o.src=e[1],o.onload=function(){t[e[0]]=o,r()}}))}));return r.length?Promise.all(r).then((function(){return t})):Promise.resolve({})},getValue:function(e,r){var o;return null==t||null===(o=t[e])||void 0===o?void 0:o[r]},isPositionPoint:function(e,r){if(!t)return!1;var o=t.length,a=0;return e>=2&&e<5&&r>=2&&r<5?a=1:e<7&&r<7?a=2:e>=o-5&&e=2&r<5?a=1:e>=o-7&&e=0&r<7?a=2:e>=2&&e<5&&r>=o-5&r=0&&e<7&&r>=o-7&r=n||l>=n||(t[i][l]=2)},getForegroundImageBrush:function(t){var r;if(t.width>e.canvas.width||t.height>e.canvas.height){var o=document.createElement("canvas"),a=o.getContext("2d");t.width>e.canvas.width?(o.width=e.canvas.width,o.height=t.height/t.width*e.canvas.width):(o.width=t.width/t.height*e.canvas.height,o.height=e.canvas.height),a.drawImage(t,0,0,o.width,o.height),r=e.createPattern(o,"repeat")}else r=e.createPattern(t,"repeat");return r},drawRightAngle:function(t,r,o,a){var n,i;switch(o){case 0:n=t*a,i=r*a,e.lineTo(n,i);break;case 1:n=t*a+a,i=r*a,e.lineTo(n,i);break;case 2:n=t*a+a,i=r*a+a,e.lineTo(n,i);break;case 3:n=t*a,i=r*a+a,e.lineTo(n,i)}},drawRoundBrick:function(t,r,o,a){var n,i,l=a/2;switch(o){case 0:n=t*a+l,i=r*a+l,e.arc(n,i,l,Math.PI,1.5*Math.PI,!1);break;case 1:n=t*a+a-l,i=r*a+l,e.arc(n,i,l,1.5*Math.PI,2*Math.PI,!1);break;case 2:n=t*a+a-l,i=r*a+a-l,e.arc(n,i,l,0,Math.PI/2,!1);break;case 3:n=t*a+l,i=r*a+a-l,e.arc(n,i,l,Math.PI/2,Math.PI,!1)}},fillRound:function(t,r,o,a){var n,i,l=a/2;switch(e.beginPath(),o){case 0:n=t*a+l,i=r*a+l,e.arc(n,i,l,Math.PI,1.5*Math.PI,!1),n=t*a,i=r*a;break;case 1:n=t*a+a-l,i=r*a+l,e.arc(n,i,l,1.5*Math.PI,2*Math.PI,!1),n=t*a+a,i=r*a;break;case 2:n=t*a+a-l,i=r*a+a-l,e.arc(n,i,l,0,Math.PI/2,!1),n=t*a+a,i=r*a+a;break;case 3:n=t*a+l,i=r*a+a-l,e.arc(n,i,l,Math.PI/2,Math.PI,!1),n=t*a,i=r*a+a}e.lineTo(n,i),e.closePath(),e.fill(),e.stroke()}}}E.prototype={addData:function(e){var t=new m(e);this.dataList.push(t),this.dataCache=null},isDark:function(e,t){if(e<0||this.moduleCount<=e||t<0||this.moduleCount<=t)throw new Error(e+","+t);return this.modules[e][t]},getModuleCount:function(){return this.moduleCount},make:function(){this.makeImpl(!1,this.getBestMaskPattern())},makeImpl:function(e,t){this.moduleCount=4*this.typeNumber+17,this.modules=new Array(this.moduleCount);for(var r=0;r=7&&this.setupTypeNumber(e),null==this.dataCache&&(this.dataCache=E.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,t)},setupPositionProbePattern:function(e,t){for(var r=-1;r<=7;r++)if(!(e+r<=-1||this.moduleCount<=e+r))for(var o=-1;o<=7;o++)t+o<=-1||this.moduleCount<=t+o||(this.modules[e+r][t+o]=0<=r&&r<=6&&(0==o||6==o)||0<=o&&o<=6&&(0==r||6==r)||2<=r&&r<=4&&2<=o&&o<=4)},getBestMaskPattern:function(){for(var e=0,t=0,r=0;r<8;r++){this.makeImpl(!0,r);var o=D.getLostPoint(this);(0==r||e>o)&&(e=o,t=r)}return t},createMovieClip:function(e,t,r){var o=e.createEmptyMovieClip(t,r);this.make();for(var a=0;a>r&1);this.modules[Math.floor(r/3)][r%3+this.moduleCount-8-3]=o}for(var a=0;a<18;a++){var n=!e&&1==(t>>a&1);this.modules[a%3+this.moduleCount-8-3][Math.floor(a/3)]=n}},setupTypeInfo:function(e,t){for(var r=this.errorCorrectLevel<<3|t,o=D.getBCHTypeInfo(r),a=0;a<15;a++){var n=!e&&1==(o>>a&1);a<6?this.modules[a][8]=n:a<8?this.modules[a+1][8]=n:this.modules[this.moduleCount-15+a][8]=n}for(var i=0;i<15;i++){var l=!e&&1==(o>>i&1);i<8?this.modules[8][this.moduleCount-i-1]=l:i<9?this.modules[8][15-i-1+1]=l:this.modules[8][15-i-1]=l}this.modules[this.moduleCount-8][8]=!e},mapData:function(e,t){for(var r=-1,o=this.moduleCount-1,a=7,n=0,i=this.moduleCount-1;i>0;i-=2)for(6==i&&i--;;){for(var l=0;l<2;l++)if(null==this.modules[o][i-l]){var u=!1;n>>a&1)),D.getMask(t,o,i-l)&&(u=!u),this.modules[o][i-l]=u,-1==--a&&(n++,a=7)}if((o+=r)<0||this.moduleCount<=o){o-=r,r=-r;break}}}},E.PAD0=236,E.PAD1=17,E.createData=function(e,t,r){for(var o=w.getRSBlocks(e,t),a=new b,n=0;n8*l)throw new Error("code length overflow. ("+a.getLengthInBits()+">"+8*l+")");for(a.getLengthInBits()+4<=8*l&&a.put(0,4);a.getLengthInBits()%8!=0;)a.putBit(!1);for(;!(a.getLengthInBits()>=8*l||(a.put(E.PAD0,8),a.getLengthInBits()>=8*l));)a.put(E.PAD1,8);return E.createBytes(a,o)},E.createBytes=function(e,t){for(var r=0,o=0,a=0,n=new Array(t.length),i=new Array(t.length),l=0;l=0?c.get(d):0}}for(var v=0,m=0;m1){var f=e.createLinearGradient(0,0,e.canvas.width,e.canvas.height),c=g.length-1;g.forEach((function(e,t){f.addColorStop(t/c,e)})),s=f}var h=r.innerColor||s,d=r.outerColor||s;e.save(),!r.backgroundColor&&t.backgroundImage?e.drawImage(t.backgroundImage,0,0,e.canvas.width,e.canvas.height):(e.fillStyle=a,e.fillRect(0,0,e.canvas.width,e.canvas.height)),e.restore(),e.save(),e.translate(i,l);for(var v=0;v1){var f=e.createLinearGradient(0,0,e.canvas.width,e.canvas.height),c=g.length-1;g.forEach((function(e,t){f.addColorStop(t/c,e)})),s=f}var h=r.innerColor||s,d=r.outerColor||s;e.save(),!r.backgroundColor&&t.backgroundImage?e.drawImage(t.backgroundImage,0,0,e.canvas.width,e.canvas.height):(e.fillStyle=a,e.fillRect(0,0,e.canvas.width,e.canvas.height)),e.restore(),e.save(),e.translate(i,l);for(var v=0;v1){var f=e.createLinearGradient(0,0,e.canvas.width,e.canvas.height),c=g.length-1;g.forEach((function(e,t){f.addColorStop(t/c,e)})),s=f}var h=r.innerColor||s,d=r.outerColor||s;e.save(),!r.backgroundColor&&t.backgroundImage?e.drawImage(t.backgroundImage,0,0,e.canvas.width,e.canvas.height):(e.fillStyle=a,e.fillRect(0,0,e.canvas.width,e.canvas.height)),e.restore(),e.save(),e.translate(i+n/2,l+n/2);for(var v=0;v1){var s=e.createLinearGradient(0,0,e.canvas.width,e.canvas.height),f=g.length-1;g.forEach((function(e,t){s.addColorStop(t/f,e)})),s}r.innerColor,r.outerColor,e.save(),t.backgroundImage?e.drawImage(t.backgroundImage,0,0,e.canvas.width,e.canvas.height):(e.fillStyle=a,e.fillRect(0,0,e.canvas.width,e.canvas.height)),e.restore(),e.save(),e.translate(i,l);for(var c=0;c\n \n \n ',t.$module=t.shadowRoot.querySelector(".mod-qrcode"),t.$canvas=t.$module.querySelector("canvas"),t.context=t.$canvas.getContext("2d"),t.resize(),"undefined"!=typeof ResizeObserver&&new ResizeObserver((function(){t.resize()})).observe(t)}},{key:"resize",value:function(){var e=this,t=window.getComputedStyle(e);if(t.width&&t.height){var r=Math.max(parseInt(t.width),parseInt(t.height));e.$canvas.width=2*r,e.$canvas.height=2*r,e.drawQRCode()}}},{key:"drawQRCode",value:function(){var e=this,t=e.level;e.logo?(t="H",e.$module.querySelector(".logo").style="background: url(".concat(e.logo,") center center/ 25% 25% no-repeat;")):e.$module.querySelector(".logo").style="";var r=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"https://passer-by.com/",t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"H",r=new E(V(e,s[t]),s[t]);return r.addData(e),r.make(),r.modules}(e.value,t);e.context.clearRect(0,0,e.$canvas.width,e.$canvas.height),(O[e.template]||O.default)(e.context,r,{foregroundImage:e.foregroundImage,backgroundImage:e.backgroundImage,foregroundColor:e.foregroundColor,backgroundColor:e.backgroundColor,innerColor:e.innerColor,outerColor:e.outerColor})}}],i=[{key:"observedAttributes",get:function(){return["value","template","level","width","height","logo","foreground-image","background-image","foreground-color","background-color","inner-color","outer-color"]}}],o&&a(r.prototype,o),i&&a(r,i),Object.defineProperty(r,"prototype",{writable:!1}),u}(g(HTMLElement));customElements.get("widget-qrcode")||customElements.define("widget-qrcode",j)}(); diff --git a/index.html b/index.html index ea1691a..066aa86 100644 --- a/index.html +++ b/index.html @@ -44,7 +44,7 @@

二维码组件开源算法

-

仅需一个标签,即可让二维码图片随内容实时变动!让二维码展示更加丝滑~

+

仅需一个HTML标签,即可获得独具个性的二维码!图案随内容实时变化,让二维码更多彩~

@@ -56,7 +56,7 @@

二维码组件开源算法

自定义标签
- <widget-qrcode text="[二维码内容]"></widget-qrcode> + <widget-qrcode value="[二维码内容]"></widget-qrcode>
@@ -64,26 +64,136 @@

二维码组件开源算法

实时演示
- +
+
文本内容
+
+ +
+
+
+
风格模板
+
+ + + + + + + + + + +
+
+
+
颜色方案
+
+ + + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + +

组件属性

属性说明
value二维码内容
template样式模板,可选:'default','water','diamond','hexagon','star','rect','bar','heart','glitter','fusion'
level纠错等级,可选:'M','L','Q','H'
width二维码宽度,默认:300
height二维码高度,默认:300
logologo图片地址
background-image背景图片地址
foreground-image前景图片地址
background-color背景色,默认:#ffffff
foreground-color前景色,默认:#000000;(多色用逗号分隔)
inner-color定位点内层颜色,默认:#000000
outer-color定位点外层颜色,默认:#000000
+
+
+
+
+
样例展示
+
+ + + + + + + + + + +
+
+
@@ -95,7 +205,8 @@

二维码组件开源算法

算法开源
-

算法基于「MIT许可协议」开源,除需在源码中保留版权信息和许可声明外,你有权利使用、复制、修改、合并、出版发行、散布、再授权及贩售软件及软件的副本。数据持续更新中,如发现错漏或有想法建议可在此 反馈问题

+

本项目致力于让你网站中的二维码更加丰富多彩,开发使用便捷高效。本人深感项目的完善仅凭一己之力是远远不够的,如果你对此感兴趣,欢迎关注本项目 或 提交代码,与我一起完善它,使它被更多人熟知和使用。你也可以将自己配置的二维码参数分享给我,有机会让更多人看到你的设计!

+

算法基于「MIT许可协议」开源,除需在源码中保留版权信息和许可声明外,你有权利使用、复制、修改、合并、出版发行、散布、再授权及贩售软件及软件的副本。算法持续更新中,如发现错漏或有想法建议可在此 反馈问题

Follow @mumuy Fork diff --git a/src/module/draw.js b/src/module/draw.js index 63298c2..44a2af9 100644 --- a/src/module/draw.js +++ b/src/module/draw.js @@ -1,10 +1,24 @@ import _default from './template/default.js'; import _water from './template/water.js'; import _star from './template/star.js'; +import _rect from './template/rect.js'; +import _diamond from './template/diamond.js'; +import _hexagon from './template/hexagon.js'; +import _bar from './template/bar.js'; +import _heart from './template/heart.js'; +import _glitter from './template/glitter.js'; +import _fusion from './template/fusion.js'; //基础绘制 export default { 'default':_default, 'water':_water, - 'star':_star + 'star':_star, + 'rect':_rect, + 'diamond':_diamond, + 'hexagon':_hexagon, + 'bar':_bar, + 'heart':_heart, + 'glitter':_glitter, + 'fusion':_fusion }; diff --git a/src/module/method/DrawUtil.js b/src/module/method/DrawUtil.js index e891723..3632a04 100644 --- a/src/module/method/DrawUtil.js +++ b/src/module/method/DrawUtil.js @@ -1,104 +1,24 @@ -// 绘制角 -export function drawRightAngle(context, x, y, dir, pxWidth) { - let cx, cy; - switch (dir) { - case 0: - cx = x * pxWidth; - cy = y * pxWidth; - context.lineTo(cx, cy); - break; - case 1: - cx = x * pxWidth + pxWidth; - cy = y * pxWidth; - context.lineTo(cx, cy); - break; - case 2: - cx = x * pxWidth + pxWidth; - cy = y * pxWidth + pxWidth; - context.lineTo(cx, cy); - break; - case 3: - cx = x * pxWidth; - cy = y * pxWidth + pxWidth; - context.lineTo(cx, cy); - break; - } -}; - -// 绘制填补角 -export function drawRoundBrick(context, x, y, dir, pxWidth) { - let round = pxWidth/2; - let cx, cy; - switch (dir) { - case 0: - cx = x * pxWidth + round; - cy = y * pxWidth + round; - context.arc(cx, cy, round, Math.PI, Math.PI * 1.5, false); - break; - case 1: - cx = x * pxWidth + pxWidth - round; - cy = y * pxWidth + round; - context.arc(cx, cy, round, Math.PI * 1.5, Math.PI * 2, false); - break; - case 2: - cx = x * pxWidth + pxWidth - round; - cy = y * pxWidth + pxWidth - round; - context.arc(cx, cy, round, 0, Math.PI / 2, false); - break; - case 3: - cx = x * pxWidth + round; - cy = y * pxWidth + pxWidth - round; - context.arc(cx, cy, round, Math.PI / 2, Math.PI, false); - break; - } -}; - -// 填充圆 -export function fillRound(context, x, y, dir, pxWidth) { - let round = pxWidth/2; - let cx, cy; - context.beginPath(); - switch (dir) { - case 0: - cx = x * pxWidth + round; - cy = y * pxWidth + round; - context.arc(cx, cy, round, Math.PI, Math.PI * 1.5, false); - cx = x * pxWidth; - cy = y * pxWidth; - break; - case 1: - cx = x * pxWidth + pxWidth - round; - cy = y * pxWidth + round; - context.arc(cx, cy, round, Math.PI * 1.5, Math.PI * 2, false); - cx = x * pxWidth + pxWidth; - cy = y * pxWidth; - break; - case 2: - cx = x * pxWidth + pxWidth - round; - cy = y * pxWidth + pxWidth - round; - context.arc(cx, cy, round, 0, Math.PI / 2, false); - cx = x * pxWidth + pxWidth; - cy = y * pxWidth + pxWidth; - break; - case 3: - cx = x * pxWidth + round; - cy = y * pxWidth + pxWidth - round; - context.arc(cx, cy, round, Math.PI / 2, Math.PI, false); - cx = x * pxWidth; - cy = y * pxWidth + pxWidth; - break; - default: - } - context.lineTo(cx, cy); - context.closePath(); - context.fill(); - context.stroke(); -}; - // 条件判断API -export function getAPI(data) { +export default function(context,data,options) { return { + // 图片加载 + imageReady:function(resources){ + let result = {}; + let promoses = Object.entries(resources).map(function(item){ + return new Promise(function(resolve){ + var image = new Image(); + image.src = item[1]; + image.onload = function(){ + result[item[0]] = image; + resolve(); + }; + }); + }); + return promoses.length?Promise.all(promoses).then(()=>result):Promise.resolve({}); + }, + // 获取当前点的值 getValue:(x, y) => data?.[x]?.[y], + // 判断定位点 isPositionPoint:function(i, j) { if(!data){ return false; @@ -170,6 +90,120 @@ export function getAPI(data) { } } } + }, + // 前景图片笔刷 + getForegroundImageBrush:function(image){ + let brush; + if(image.width>context.canvas.width||image.height>context.canvas.height){ + let $canvas = document.createElement('canvas'); + let contextTemp = $canvas.getContext('2d'); + if(image.width>context.canvas.width){ + $canvas.width = context.canvas.width; + $canvas.height = image.height/image.width*context.canvas.width; + }else{ + $canvas.width = image.width/image.height*context.canvas.height; + $canvas.height = context.canvas.height; + } + contextTemp.drawImage(image,0,0,$canvas.width,$canvas.height); + brush = context.createPattern($canvas,'repeat'); + }else{ + brush = context.createPattern(image,'repeat'); + } + return brush; + }, + // 绘制角 + drawRightAngle:function(x, y, dir, pxWidth) { + let cx, cy; + switch (dir) { + case 0: + cx = x * pxWidth; + cy = y * pxWidth; + context.lineTo(cx, cy); + break; + case 1: + cx = x * pxWidth + pxWidth; + cy = y * pxWidth; + context.lineTo(cx, cy); + break; + case 2: + cx = x * pxWidth + pxWidth; + cy = y * pxWidth + pxWidth; + context.lineTo(cx, cy); + break; + case 3: + cx = x * pxWidth; + cy = y * pxWidth + pxWidth; + context.lineTo(cx, cy); + break; + } + }, + // 绘制角补角 + drawRoundBrick:function(x, y, dir, pxWidth) { + let round = pxWidth/2; + let cx, cy; + switch (dir) { + case 0: + cx = x * pxWidth + round; + cy = y * pxWidth + round; + context.arc(cx, cy, round, Math.PI, Math.PI * 1.5, false); + break; + case 1: + cx = x * pxWidth + pxWidth - round; + cy = y * pxWidth + round; + context.arc(cx, cy, round, Math.PI * 1.5, Math.PI * 2, false); + break; + case 2: + cx = x * pxWidth + pxWidth - round; + cy = y * pxWidth + pxWidth - round; + context.arc(cx, cy, round, 0, Math.PI / 2, false); + break; + case 3: + cx = x * pxWidth + round; + cy = y * pxWidth + pxWidth - round; + context.arc(cx, cy, round, Math.PI / 2, Math.PI, false); + break; + } + }, + // 填充圆 + fillRound:function(x, y, dir, pxWidth) { + let round = pxWidth/2; + let cx, cy; + context.beginPath(); + switch (dir) { + case 0: + cx = x * pxWidth + round; + cy = y * pxWidth + round; + context.arc(cx, cy, round, Math.PI, Math.PI * 1.5, false); + cx = x * pxWidth; + cy = y * pxWidth; + break; + case 1: + cx = x * pxWidth + pxWidth - round; + cy = y * pxWidth + round; + context.arc(cx, cy, round, Math.PI * 1.5, Math.PI * 2, false); + cx = x * pxWidth + pxWidth; + cy = y * pxWidth; + break; + case 2: + cx = x * pxWidth + pxWidth - round; + cy = y * pxWidth + pxWidth - round; + context.arc(cx, cy, round, 0, Math.PI / 2, false); + cx = x * pxWidth + pxWidth; + cy = y * pxWidth + pxWidth; + break; + case 3: + cx = x * pxWidth + round; + cy = y * pxWidth + pxWidth - round; + context.arc(cx, cy, round, Math.PI / 2, Math.PI, false); + cx = x * pxWidth; + cy = y * pxWidth + pxWidth; + break; + default: + } + context.lineTo(cx, cy); + context.closePath(); + context.fill(); + context.stroke(); } }; }; diff --git a/src/module/template/bar.js b/src/module/template/bar.js new file mode 100644 index 0000000..6f53ffc --- /dev/null +++ b/src/module/template/bar.js @@ -0,0 +1,106 @@ +import getAPI from '../method/DrawUtil.js'; + +export default function(context,data,options){ + let len = data.length; + let margin = context.canvas.width*0.05; + let pxWidth = (context.canvas.width-2*margin)/len; + let x = margin; + let y = margin; + let api = getAPI(context,data,options); + let resourcesMap = {}; + if(options.foregroundImage){ + resourcesMap['foregroundImage'] = options.foregroundImage; + } + if(options.backgroundImage){ + resourcesMap['backgroundImage'] = options.backgroundImage; + } + api.imageReady(resourcesMap).then(function(resources){ + let backgroundColor = options.backgroundColor||'#ffffff'; + let foregroundColor = options.foregroundColor||'#000000'; + let colors = foregroundColor.split(','); + let color = colors[0]; + if(!options.foregroundColor&&resources.foregroundImage){ + color = api.getForegroundImageBrush(resources.foregroundImage); + } + let innerColor = options.innerColor||colors?.[1]||color; + let outerColor = options.outerColor||color; + context.save(); + if(!options.backgroundColor&&resources.backgroundImage){ + context.drawImage(resources.backgroundImage,0,0,context.canvas.width,context.canvas.height); + }else{ + context.fillStyle = backgroundColor; + context.fillRect(0,0,context.canvas.width,context.canvas.height); + } + context.restore(); + context.save(); + context.translate(x+0.5*pxWidth,y+0.5*pxWidth); + for(let i=0;i1){ + let gradient = context.createLinearGradient(0,0,context.canvas.width,context.canvas.height); + let length = colors.length-1; + colors.forEach(function(value,index){ + gradient.addColorStop(index/length,value); + }); + color = gradient; + } + let innerColor = options.innerColor||color; + let outerColor = options.outerColor||color; + context.save(); + if(!options.backgroundColor&&resources.backgroundImage){ + context.drawImage(resources.backgroundImage,0,0,context.canvas.width,context.canvas.height); + }else{ + context.fillStyle = backgroundColor; + context.fillRect(0,0,context.canvas.width,context.canvas.height); + } + context.restore(); + context.save(); + context.translate(x,y); + for(let i=0;i1){ + let gradient = context.createLinearGradient(0,0,context.canvas.width,context.canvas.height); + let length = colors.length-1; + colors.forEach(function(value,index){ + gradient.addColorStop(index/length,value); + }); + color = gradient; + } + let innerColor = options.innerColor||color; + let outerColor = options.outerColor||color; + context.save(); + if(!options.backgroundColor&&resources.backgroundImage){ + context.drawImage(resources.backgroundImage,0,0,context.canvas.width,context.canvas.height); + }else{ + context.fillStyle = backgroundColor; + context.fillRect(0,0,context.canvas.width,context.canvas.height); + } + context.restore(); + context.save(); + context.translate(x+pxWidth/2,y+pxWidth/2); + for(let i=0;i1){ + let gradient = context.createLinearGradient(0,0,context.canvas.width,context.canvas.height); + let length = colors.length-1; + colors.forEach(function(value,index){ + gradient.addColorStop(index/length,value); + }); + color = gradient; + } + let innerColor = options.innerColor||color; + let outerColor = options.outerColor||color; + context.save(); + if(resources.backgroundImage){ + context.drawImage(resources.backgroundImage,0,0,context.canvas.width,context.canvas.height); + }else{ + context.fillStyle = backgroundColor; + context.fillRect(0,0,context.canvas.width,context.canvas.height); + } + context.restore(); + context.save(); + context.translate(x,y); + for(let i=0;i1){ + let gradient = context.createLinearGradient(0,0,context.canvas.width,context.canvas.height); + let length = colors.length-1; + colors.forEach(function(value,index){ + gradient.addColorStop(index/length,value); + }); + color = gradient; + } + let innerColor = options.innerColor||color; + let outerColor = options.outerColor||color; + context.save(); + if(!options.backgroundColor&&resources.backgroundImage){ + context.drawImage(resources.backgroundImage,0,0,context.canvas.width,context.canvas.height); + }else{ + context.fillStyle = backgroundColor; + context.fillRect(0,0,context.canvas.width,context.canvas.height); + } + context.restore(); + context.save(); + context.translate(x,y); + for(let i=0;iitem.cssText).join(''); _.shadowRoot.appendChild($style); } - // 节点 _.render(); _.drawQRCode(); - + // 自适应 _.addEventListener('resize',function(){ _.resize(); },false); + // 修复切换tab画布被清空问题 + document.addEventListener('visibilitychange',function(){ + _.drawQRCode(); + }); } render(parser){ let _ = this; _.shadowRoot.innerHTML = `
+
`; _.$module = _.shadowRoot.querySelector('.mod-qrcode'); _.$canvas = _.$module.querySelector('canvas'); @@ -74,16 +99,33 @@ class WidgetQRCode extends HTMLElement { } resize(){ let _ = this; - let clientSize = Math.max(_.clientWidth,_.clientHeight); - _.$canvas.width = clientSize*2; - _.$canvas.height = clientSize*2; - _.drawQRCode(); + let style = window.getComputedStyle(_); + if(style.width&&style.height){ + let clientSize = Math.max(parseInt(style.width),parseInt(style.height)); + _.$canvas.width = clientSize*2; + _.$canvas.height = clientSize*2; + _.drawQRCode(); + } } drawQRCode(){ let _ = this; - let data = QRCode(_.value, _.level); + let level = _.level; + if(_.logo){ + level = 'H'; + _.$module.querySelector('.logo').style = `background: url(${_.logo}) center center/ 25% 25% no-repeat;`; + }else{ + _.$module.querySelector('.logo').style = ``; + } + let data = QRCode(_.value, level); _.context.clearRect(0,0,_.$canvas.width,_.$canvas.height); - (Draw[_.template]||Draw['default'])(_.context, data, {}); + (Draw[_.template]||Draw['default'])(_.context, data, { + 'foregroundImage':_.foregroundImage, + 'backgroundImage':_.backgroundImage, + 'foregroundColor':_.foregroundColor, + 'backgroundColor':_.backgroundColor, + 'innerColor':_.innerColor, + 'outerColor':_.outerColor + }); } } diff --git a/static/image/bg/girl.jpeg b/static/image/bg/girl.jpeg new file mode 100644 index 0000000..2b2fefa Binary files /dev/null and b/static/image/bg/girl.jpeg differ diff --git a/static/image/bg/monkey.jpeg b/static/image/bg/monkey.jpeg new file mode 100644 index 0000000..83b7744 Binary files /dev/null and b/static/image/bg/monkey.jpeg differ diff --git a/static/image/logo/earth.png b/static/image/logo/earth.png new file mode 100644 index 0000000..b7f51dd Binary files /dev/null and b/static/image/logo/earth.png differ diff --git a/static/image/logo/octopus.png b/static/image/logo/octopus.png new file mode 100644 index 0000000..9b3d4a0 Binary files /dev/null and b/static/image/logo/octopus.png differ diff --git a/static/image/logo/snail.png b/static/image/logo/snail.png new file mode 100644 index 0000000..986ecdb Binary files /dev/null and b/static/image/logo/snail.png differ diff --git a/static/image/skin/grass.png b/static/image/skin/grass.png new file mode 100644 index 0000000..49cc4bc Binary files /dev/null and b/static/image/skin/grass.png differ diff --git a/static/image/skin/lowploy.jpg b/static/image/skin/lowploy.jpg new file mode 100644 index 0000000..583fc86 Binary files /dev/null and b/static/image/skin/lowploy.jpg differ diff --git a/static/style/index.css b/static/style/index.css index 74acb88..65e7581 100644 --- a/static/style/index.css +++ b/static/style/index.css @@ -92,7 +92,7 @@ a:hover{ } .mod-panel{ - margin-bottom: 75px; + margin-bottom: 50px; } .mod-panel .hd{ padding: 35px 0; @@ -202,9 +202,32 @@ a:hover{ font-family: Menlo, Monaco, Consolas, "Andale Mono", "lucida console", "Courier New", monospace; color: #666; } +.mod-panel .setting-box .input-wrapper{ + display: flex; + line-height: 36px; + margin-bottom: 5px; +} +.mod-panel .setting-box .input-title{ + width: 64px; + margin-right: 10px; +} +.mod-panel .setting-box .input-content{ + flex: 1px; + min-width: 0; +} +.mod-panel .setting-box label{ + display: inline-block; + min-width: 80px; + margin-right: 15px; + line-height: 24px; + user-select: none; +} +.mod-panel .setting-box label span,.mod-panel .setting-box label input{ + vertical-align: middle; +} .mod-panel .setting-box input[type="search"]{ width: 100%; - height: 40px; + height: 36px; padding: 0 15px; border: 1px solid #e8e8e8; border-radius: 5px; @@ -273,6 +296,76 @@ a:hover{ background: #f0f0f0; color: #aaa; } +.mod-panel .ft{ + padding: 20px; + background: #fff; + border: 1px solid rgba(0, 0, 0, 0.075); + box-shadow: 1px 1px 5px rgba(0,0,0,0.05); +} +.mod-panel .ft .table-inner{ + overflow-x: auto; +} +.mod-panel .ft table{ + width: 100%; +} +.mod-panel .ft table caption{ + line-height: 32px; + font-size: 16px; + font-weight: bold; +} +.mod-panel .ft table caption h3{ + font-weight: bold; + color: #333; +} +.mod-panel .ft table thead{ + background-color: #f8f8f8; +} +.mod-panel .ft table th,.mod-panel .ft table td{ + line-height: 20px; + padding: 6px 10px; + border: 1px solid #e4e4e4; + white-space: nowrap; +} + +.mod-sample{ + margin-bottom: 50px; + background: #fff; + box-shadow: 0 1px 5px 0 rgba(0,0,0,0.05); + border: 1px solid rgba(0,0,0,0.075); +} +.mod-sample .hd{ + padding: 10px 20px; + border-bottom: 1px solid #f0f0f0; +} +.mod-sample .hd .title{ + position: relative; + padding-left: 20px; + margin-left: -18px; + line-height: 24px; + font-size: 18px; + font-weight: bold; + color: #333; +} +.mod-sample .hd .title::before{ + position: absolute; + left: 0; + top: 0; + width: 4px; + height: 100%; + content:''; + background: #2095f2; + border-radius: 2px; +} +.mod-sample .bd{ + padding: 20px; +} +.mod-sample .bd widget-qrcode{ + width: 172px; + height: 172px; + margin: 5px; + box-shadow: 0 1px 5px 0 rgba(0, 0, 0, 0.05); + border: 1px solid rgba(0, 0, 0, 0.075); +} .mod-intro{ margin-bottom: 65px; @@ -373,6 +466,10 @@ a:hover{ font-weight: bold; color: #fd7474; } +.mod-copy .bd .text-blue { + font-weight: bold; + color: #48aeff; +} .mod-copy .bd code{ display: block; margin-bottom: 15px; @@ -466,6 +563,14 @@ a:hover{ line-height: 20px; font-size: 14px; } + .mod-panel .ft{ + padding: 15px; + } + + .mod-sample .bd widget-qrcode{ + width: 132px; + height: 132px; + } .mod-article{