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;i
1){
+ 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{