https://github.com/yeild/jigsaw
html
<div class="container" id="container"> <div id="captcha"></div> <div id="msg"></div> </div>
调用的地方 (window as any).jigsaw.init({ el: document.getElementById('container'), width: Math.floor(document.getElementById('content-box-item').offsetWidth) - 14, // 可选, 默认310 height: 120, // 可选, 默认155 onSuccess: () => { this.container = true; }, onFail: () => { this.container = false; }, onRefresh: () => { this.container = false; } })
jjgsaw.js
/*! * version: 1.0.3 * docs: https://github.com/yeild/jigsaw * */!function(n){var e={};function t(r){if(e[r])return e[r].exports;var i=e[r]={i:r,l:!1,exports:{}};return n[r].call(i.exports,i,i.exports,t),i.l=!0,i.exports}t.m=n,t.c=e,t.d=function(n,e,r){t.o(n,e)||Object.defineProperty(n,e,{enumerable:!0,get:r})},t.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},t.t=function(n,e){if(1&e&&(n=t(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var r=Object.create(null);if(t.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var i in n)t.d(r,i,function(e){return n[e]}.bind(null,i));return r},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},t.p="",t(t.s=0)}([function(n,e,t){"use strict";var r,i=Object.assign||function(n){for(var e=1;e<arguments.length;e++){var t=arguments[e];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(n[r]=t[r])}return n},o=function(){function n(n,e){for(var t=0;t<e.length;t++){var r=e[t];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(n,r.key,r)}}return function(e,t,r){return t&&n(e.prototype,t),r&&n(e,r),e}}(),s=t(1),a=(r=s)&&r.__esModule?r:{default:r};var l=42,c=Math.PI,d=63;function u(n,e){return Math.round(Math.random()*(e-n)+n)}function f(n,e){var t=document.createElement("canvas");return t.width=n,t.height=e,t}function p(n,e){var t=document.createElement(n);return e&&(t.className=a.default[e]),t}function h(n,e){n.className=a.default[e]}function g(n,e){n.classList.add(a.default[e])}function v(){return"https://picsum.photos/id/"+u(0,1084)+"/310/155"}function b(n,e,t,r){n.beginPath(),n.moveTo(e,t),n.arc(e+21,t-9+2,9,.72*c,2.26*c),n.lineTo(e+l,t),n.arc(e+l+9-2,t+21,9,1.21*c,2.78*c),n.lineTo(e+l,t+l),n.lineTo(e,t+l),n.arc(e+9-2,t+21,9.4,2.76*c,1.24*c,!0),n.lineTo(e,t),n.lineWidth=2,n.fillStyle="rgba(255, 255, 255, 0.7)",n.strokeStyle="rgba(255, 255, 255, 0.7)",n.stroke(),n.globalCompositeOperation="destination-over","fill"===r?n.fill():n.clip()}function _(n,e){return n+e}function x(n){return n*n}var w=function(){function n(e){var t=e.el,r=e.width,o=void 0===r?310:r,s=e.height,a=void 0===s?155:s,l=e.onSuccess,c=e.onFail,d=e.onRefresh;!function(n,e){if(!(n instanceof e))throw new TypeError("Cannot call a class as a function")}(this,n),i(t.style,{position:"relative",width:o+"px",margin:"0 auto"}),this.width=o,this.height=a,this.el=t,this.onSuccess=l,this.onFail=c,this.onRefresh=d}return o(n,[{key:"init",value:function(){this.initDOM(),this.initImg(),this.bindEvents()}},{key:"initDOM",value:function(){var n=this.width,e=this.height,t=f(n,e),r=f(n,e);h(r,"block");var o=p("div","sliderContainer");o.style.width=n+"px",o.style.pointerEvents="none";var s=p("div","refreshIcon"),a=p("div","sliderMask"),l=p("div","slider"),c=p("span","sliderIcon"),d=p("span","sliderText");d.innerHTML="向右滑动填充拼图";var u=p("div","loadingContainer");u.style.width=n+"px",u.style.height=e+"px";var g=p("div","loadingIcon"),v=p("span");v.innerHTML="加载中...",u.appendChild(g),u.appendChild(v);var b=this.el;b.appendChild(u),b.appendChild(t),b.appendChild(s),b.appendChild(r),l.appendChild(c),a.appendChild(l),o.appendChild(a),o.appendChild(d),b.appendChild(o),i(this,{canvas:t,block:r,sliderContainer:o,loadingContainer:u,refreshIcon:s,slider:l,sliderMask:a,sliderIcon:c,text:d,canvasCtx:t.getContext("2d"),blockCtx:r.getContext("2d")})}},{key:"setLoading",value:function(n){this.loadingContainer.style.display=n?"":"none",this.sliderContainer.style.pointerEvents=n?"none":""}},{key:"initImg",value:function(){var n=this,e=function(n){var e=new Image;return e.crossOrigin="Anonymous",e.onload=n,e.onerror=function(){e.setSrc(v())},e.setSrc=function(n){if(window.navigator.userAgent.indexOf("Trident")>-1){var t=new XMLHttpRequest;t.onloadend=function(n){var t=new FileReader;t.readAsDataURL(n.target.response),t.onloadend=function(n){e.src=n.target.result}},t.open("GET",n),t.responseType="blob",t.send()}else e.src=n},e.setSrc(v()),e}((function(){n.setLoading(!1),n.draw(e)}));this.img=e}},{key:"draw",value:function(n){var e=this.width,t=this.height;this.x=u(73,e-73),this.y=u(28,t-73),b(this.canvasCtx,this.x,this.y,"fill"),b(this.blockCtx,this.x,this.y,"clip"),this.canvasCtx.drawImage(n,0,0,e,t),this.blockCtx.drawImage(n,0,0,e,t);var r=this.y-18-1,i=this.blockCtx.getImageData(this.x-3,r,d,d);this.block.width=d,this.blockCtx.putImageData(i,0,r)}},{key:"bindEvents",value:function(){var n=this;this.el.onselectstart=function(){return!1},this.refreshIcon.onclick=function(){n.reset(),"function"==typeof n.onRefresh&&n.onRefresh()};var e=void 0,t=void 0,r=[],i=!1,o=function(n){e=n.clientX||n.touches[0].clientX,t=n.clientY||n.touches[0].clientY,i=!0},s=this.width,l=function(o){if(!i)return!1;o.preventDefault();var a=o.clientX||o.touches[0].clientX,l=o.clientY||o.touches[0].clientY,c=a-e,d=l-t;if(c<0||c+38>=s)return!1;n.slider.style.left=c+"px";var u=(s-40-20)/(s-40)*c;n.block.style.left=u+"px",g(n.sliderContainer,"sliderContainer_active"),n.sliderMask.style.width=c+"px",r.push(d)},c=function(t){if(!i)return!1;var o,s;if(i=!1,(t.clientX||t.changedTouches[0].clientX)===e)return!1;o=n.sliderContainer,s="sliderContainer_active",o.classList.remove(a.default[s]),n.trail=r;var l=n.verify(),c=l.spliced,d=l.verified;c?d?(g(n.sliderContainer,"sliderContainer_success"),"function"==typeof n.onSuccess&&n.onSuccess()):(g(n.sliderContainer,"sliderContainer_fail"),n.text.innerHTML="请再试一次",n.reset()):(g(n.sliderContainer,"sliderContainer_fail"),"function"==typeof n.onFail&&n.onFail(),setTimeout(n.reset.bind(n),1e3))};this.slider.addEventListener("mousedown",o),this.slider.addEventListener("touchstart",o),this.block.addEventListener("mousedown",o),this.block.addEventListener("touchstart",o),document.addEventListener("mousemove",l),document.addEventListener("touchmove",l),document.addEventListener("mouseup",c),document.addEventListener("touchend",c)}},{key:"verify",value:function(){var n=this.trail,e=n.reduce(_)/n.length,t=n.map((function(n){return n-e})),r=Math.sqrt(t.map(x).reduce(_)/n.length),i=parseInt(this.block.style.left);return{spliced:Math.abs(i-this.x)<10,verified:0!==r}}},{key:"reset",value:function(){var n=this.width,e=this.height;h(this.sliderContainer,"sliderContainer"),this.slider.style.left="0px",this.block.width=n,this.block.style.left="0px",this.sliderMask.style.width="0px",this.canvasCtx.clearRect(0,0,n,e),this.blockCtx.clearRect(0,0,n,e),this.setLoading(!0),this.img.setSrc(v())}}]),n}();window.jigsaw={init:function(n){return new w(n).init()}}},function(n,e,t){var r=t(2);"string"==typeof r&&(r=[[n.i,r,""]]);var i={hmr:!0,transform:void 0,insertInto:void 0};t(4)(r,i);r.locals&&(n.exports=r.locals)},function(n,e,t){(e=n.exports=t(3)(!1)).push([n.i,".jigsaw__block--36MBx {\r\n position: absolute;\r\n left: 0;\r\n top: 0;\r\n cursor: pointer;\r\n cursor: grab;\r\n}\r\n\r\n.jigsaw__block--36MBx:active {\r\n cursor: grabbing;\r\n}\r\n\r\n.jigsaw__sliderContainer--1ZGEE {\r\n position: relative;\r\n text-align: center;\r\n width: 310px;\r\n height: 40px;\r\n line-height: 40px;\r\n background: #f7f9fa;\r\n color: #45494c;\r\n border: 1px solid #e4e7eb;\r\n}\r\n\r\n.jigsaw__sliderContainer_active--D4VhU .jigsaw__slider--ihcNg {\r\n height: 38px;\r\n top: -1px;\r\n border: 1px solid #1991FA;\r\n}\r\n\r\n.jigsaw__sliderContainer_active--D4VhU .jigsaw__sliderMask--3jX8t {\r\n height: 38px;\r\n border-width: 1px;\r\n}\r\n\r\n.jigsaw__sliderContainer_success--aYlDd .jigsaw__slider--ihcNg {\r\n height: 38px;\r\n top: -1px;\r\n border: 1px solid #52CCBA;\r\n \r\n}\r\n\r\n.jigsaw__sliderContainer_success--aYlDd .jigsaw__sliderMask--3jX8t {\r\n height: 38px;\r\n border: 1px solid #52CCBA;\r\n \r\n}\r\n\r\n.jigsaw__sliderContainer_success--aYlDd .jigsaw__sliderIcon--3cfSx {\r\n background-position: 0 -26px!important;\r\n}\r\n\r\n.jigsaw__sliderContainer_fail--35R3j .jigsaw__slider--ihcNg {\r\n height: 38px;\r\n top: -1px;\r\n border: 1px solid #f57a7a;\r\n \r\n}\r\n\r\n.jigsaw__sliderContainer_fail--35R3j .jigsaw__sliderMask--3jX8t {\r\n height: 38px;\r\n border: 1px solid #f57a7a;\r\n \r\n}\r\n\r\n.jigsaw__sliderContainer_fail--35R3j .jigsaw__sliderIcon--3cfSx {\r\n top: 14px;\r\n background-position: 0 -82px !important;\r\n}\r\n\r\n.jigsaw__sliderContainer_active--D4VhU .jigsaw__sliderText--2Rhml, .jigsaw__sliderContainer_success--aYlDd .jigsaw__sliderText--2Rhml, .jigsaw__sliderContainer_fail--35R3j .jigsaw__sliderText--2Rhml {\r\n display: none;\r\n}\r\n\r\n.jigsaw__sliderMask--3jX8t {\r\n position: absolute;\r\n left: 0;\r\n top: 0;\r\n height: 40px;\r\n border: 0 solid #1991FA;\r\n background: #D1E9FE;\r\n}\r\n\r\n.jigsaw__slider--ihcNg {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n width: 40px;\r\n height: 40px;\r\n background: #fff;\r\n box-shadow: 0 0 3px rgba(0, 0, 0, 0.3);\r\n transition: background .2s linear;\r\n cursor: pointer;\r\n cursor: grab;\r\n}\r\n\r\n.jigsaw__slider--ihcNg:active {\r\n cursor: grabbing;\r\n}\r\n\r\n.jigsaw__slider--ihcNg:hover {\r\n background: #1991FA;\r\n}\r\n\r\n.jigsaw__sliderIcon--3cfSx {\r\n position: absolute;\r\n top: 15px;\r\n left: 13px;\r\n width: 14px;\r\n height: 12px;\r\n background: url(https://cstaticdun.126.net//2.13.6/images/icon_light.4353d81.png) 0 -13px;\r\n background-size: 32px 544px;\r\n}\r\n\r\n.jigsaw__slider--ihcNg:hover .jigsaw__sliderIcon--3cfSx {\r\n background-position: 0 0;\r\n}\r\n\r\n.jigsaw__refreshIcon--2rYeZ {\r\n position: absolute;\r\n right: 5px;\r\n top: 5px;\r\n width: 30px;\r\n height: 30px;\r\n cursor: pointer;\r\n background: url(https://cstaticdun.126.net//2.13.6/images/icon_light.4353d81.png) 0 -233px;\r\n background-size: 32px 544px;\r\n}\r\n\r\n.jigsaw__refreshIcon--2rYeZ:hover {\r\n background-position: 0 -266px;\r\n}\r\n\r\n.jigsaw__loadingContainer--2jPla {\r\n position: absolute;\r\n left: 0;\r\n top: 0;\r\n width: 310px;\r\n height: 155px;\r\n display: flex;\r\n flex-direction: column;\r\n justify-content: center;\r\n align-items: center;\r\n font-size: 14px;\r\n color: #45494c;\r\n z-index: 2;\r\n background: #EDF0F2;\r\n}\r\n\r\n.jigsaw__loadingIcon--3Dv_j {\r\n width: 32px;\r\n height: 32px;\r\n background: url(https://cstaticdun.126.net//2.13.6/images/icon_light.4353d81.png) 0 -332px;\r\n background-size: 32px 544px;\r\n animation: jigsaw__loading-icon-rotate--YXLLt 0.8s linear infinite;\r\n}\r\n\r\n@keyframes jigsaw__loading-icon-rotate--YXLLt {\r\n from { transform: rotate(0) }\r\n to { transform: rotate(360deg)}\r\n}\r\n",""]),e.locals={block:"jigsaw__block--36MBx",sliderContainer:"jigsaw__sliderContainer--1ZGEE",sliderContainer_active:"jigsaw__sliderContainer_active--D4VhU",slider:"jigsaw__slider--ihcNg",sliderMask:"jigsaw__sliderMask--3jX8t",sliderContainer_success:"jigsaw__sliderContainer_success--aYlDd",sliderIcon:"jigsaw__sliderIcon--3cfSx",sliderContainer_fail:"jigsaw__sliderContainer_fail--35R3j",sliderText:"jigsaw__sliderText--2Rhml",refreshIcon:"jigsaw__refreshIcon--2rYeZ",loadingContainer:"jigsaw__loadingContainer--2jPla",loadingIcon:"jigsaw__loadingIcon--3Dv_j","loading-icon-rotate":"jigsaw__loading-icon-rotate--YXLLt"}},function(n,e){n.exports=function(n){var e=[];return e.toString=function(){return this.map((function(e){var t=function(n,e){var t=n[1]||"",r=n[3];if(!r)return t;if(e&&"function"==typeof btoa){var i=(s=r,"/*# sourceMappingURL=data:application/json;charset=utf-8;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(s))))+" */"),o=r.sources.map((function(n){return"/*# sourceURL="+r.sourceRoot+n+" */"}));return[t].concat(o).concat([i]).join("\n")}var s;return[t].join("\n")}(e,n);return e[2]?"@media "+e[2]+"{"+t+"}":t})).join("")},e.i=function(n,t){"string"==typeof n&&(n=[[null,n,""]]);for(var r={},i=0;i<this.length;i++){var o=this[i][0];"number"==typeof o&&(r[o]=!0)}for(i=0;i<n.length;i++){var s=n[i];"number"==typeof s[0]&&r[s[0]]||(t&&!s[2]?s[2]=t:t&&(s[2]="("+s[2]+") and ("+t+")"),e.push(s))}},e}},function(n,e,t){var r,i,o={},s=(r=function(){return window&&document&&document.all&&!window.atob},function(){return void 0===i&&(i=r.apply(this,arguments)),i}),a=function(n){return document.querySelector(n)},l=function(n){var e={};return function(n){if("function"==typeof n)return n();if(void 0===e[n]){var t=a.call(this,n);if(window.HTMLIFrameElement&&t instanceof window.HTMLIFrameElement)try{t=t.contentDocument.head}catch(n){t=null}e[n]=t}return e[n]}}(),c=null,d=0,u=[],f=t(5);function p(n,e){for(var t=0;t<n.length;t++){var r=n[t],i=o[r.id];if(i){i.refs++;for(var s=0;s<i.parts.length;s++)i.parts[s](r.parts[s]);for(;s<r.parts.length;s++)i.parts.push(x(r.parts[s],e))}else{var a=[];for(s=0;s<r.parts.length;s++)a.push(x(r.parts[s],e));o[r.id]={id:r.id,refs:1,parts:a}}}}function h(n,e){for(var t=[],r={},i=0;i<n.length;i++){var o=n[i],s=e.base?o[0]+e.base:o[0],a={css:o[1],media:o[2],sourceMap:o[3]};r[s]?r[s].parts.push(a):t.push(r[s]={id:s,parts:[a]})}return t}function g(n,e){var t=l(n.insertInto);if(!t)throw new Error("Couldn't find a style target. This probably means that the value for the 'insertInto' parameter is invalid.");var r=u[u.length-1];if("top"===n.insertAt)r?r.nextSibling?t.insertBefore(e,r.nextSibling):t.appendChild(e):t.insertBefore(e,t.firstChild),u.push(e);else if("bottom"===n.insertAt)t.appendChild(e);else{if("object"!=typeof n.insertAt||!n.insertAt.before)throw new Error("[Style Loader]\n\n Invalid value for parameter 'insertAt' ('options.insertAt') found.\n Must be 'top', 'bottom', or Object.\n (https://github.com/webpack-contrib/style-loader#insertat)\n");var i=l(n.insertInto+" "+n.insertAt.before);t.insertBefore(e,i)}}function v(n){if(null===n.parentNode)return!1;n.parentNode.removeChild(n);var e=u.indexOf(n);e>=0&&u.splice(e,1)}function b(n){var e=document.createElement("style");return n.attrs.type="text/css",_(e,n.attrs),g(n,e),e}function _(n,e){Object.keys(e).forEach((function(t){n.setAttribute(t,e[t])}))}function x(n,e){var t,r,i,o;if(e.transform&&n.css){if(!(o=e.transform(n.css)))return function(){};n.css=o}if(e.singleton){var s=d++;t=c||(c=b(e)),r=y.bind(null,t,s,!1),i=y.bind(null,t,s,!0)}else n.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(t=function(n){var e=document.createElement("link");return n.attrs.type="text/css",n.attrs.rel="stylesheet",_(e,n.attrs),g(n,e),e}(e),r=C.bind(null,t,e),i=function(){v(t),t.href&&URL.revokeObjectURL(t.href)}):(t=b(e),r=j.bind(null,t),i=function(){v(t)});return r(n),function(e){if(e){if(e.css===n.css&&e.media===n.media&&e.sourceMap===n.sourceMap)return;r(n=e)}else i()}}n.exports=function(n,e){if("undefined"!=typeof DEBUG&&DEBUG&&"object"!=typeof document)throw new Error("The style-loader cannot be used in a non-browser environment");(e=e||{}).attrs="object"==typeof e.attrs?e.attrs:{},e.singleton||"boolean"==typeof e.singleton||(e.singleton=s()),e.insertInto||(e.insertInto="head"),e.insertAt||(e.insertAt="bottom");var t=h(n,e);return p(t,e),function(n){for(var r=[],i=0;i<t.length;i++){var s=t[i];(a=o[s.id]).refs--,r.push(a)}n&&p(h(n,e),e);for(i=0;i<r.length;i++){var a;if(0===(a=r[i]).refs){for(var l=0;l<a.parts.length;l++)a.parts[l]();delete o[a.id]}}}};var w,m=(w=[],function(n,e){return w[n]=e,w.filter(Boolean).join("\n")});function y(n,e,t,r){var i=t?"":r.css;if(n.styleSheet)n.styleSheet.cssText=m(e,i);else{var o=document.createTextNode(i),s=n.childNodes;s[e]&&n.removeChild(s[e]),s.length?n.insertBefore(o,s[e]):n.appendChild(o)}}function j(n,e){var t=e.css,r=e.media;if(r&&n.setAttribute("media",r),n.styleSheet)n.styleSheet.cssText=t;else{for(;n.firstChild;)n.removeChild(n.firstChild);n.appendChild(document.createTextNode(t))}}function C(n,e,t){var r=t.css,i=t.sourceMap,o=void 0===e.convertToAbsoluteUrls&&i;(e.convertToAbsoluteUrls||o)&&(r=f(r)),i&&(r+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(i))))+" */");var s=new Blob([r],{type:"text/css"}),a=n.href;n.href=URL.createObjectURL(s),a&&URL.revokeObjectURL(a)}},function(n,e){n.exports=function(n){var e="undefined"!=typeof window&&window.location;if(!e)throw new Error("fixUrls requires window.location");if(!n||"string"!=typeof n)return n;var t=e.protocol+"//"+e.host,r=t+e.pathname.replace(/\/[^\/]*$/,"/");return n.replace(/url\s*\(((?:[^)(]|\((?:[^)(]+|\([^)(]*\))*\))*)\)/gi,(function(n,e){var i,o=e.trim().replace(/^"(.*)"$/,(function(n,e){return e})).replace(/^'(.*)'$/,(function(n,e){return e}));return/^(#|data:|http:\/\/|https:\/\/|file:\/\/\/|\s*$)/i.test(o)?n:(i=0===o.indexOf("//")?o:0===o.indexOf("/")?t+o:r+o.replace(/^\.\//,""),"url("+JSON.stringify(i)+")")}))}}]);