{"_id":"o-crop","_rev":"4-f3495c8db2a1f4a52dea453af50ba51c","name":"o-crop","dist-tags":{"latest":"1.0.3"},"versions":{"1.0.0":{"name":"o-crop","version":"1.0.0","description":"alloyCrop改","main":"index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"keywords":["crop"],"author":{"name":"tangzk"},"license":"MIT","_id":"o-crop@1.0.0","_nodeVersion":"14.15.4","_npmVersion":"7.5.4","dist":{"integrity":"sha512-ZMpPVGTmc79BYhcGFWNUZnvrYAX9+/eipIWajGlD4PjxjqGScYECh33KlCUxVtZgVBoMwk7QnZuT5m8tDYW0DQ==","shasum":"64952482cfe899fa1ddd153142e294fdde2545da","tarball":"https://registry.npmjs.org/o-crop/-/o-crop-1.0.0.tgz","fileCount":2,"unpackedSize":13664,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgS2SACRA9TVsSAnZWagAAPkQP/1PoXIjwZly9YmVfyyb5\npOWbuemOl7fNF1aRQPXw2kXJnJNCGj3jSOKgRUUWk0i4pvf6pa1Oqg1i3s7e\n6QAOE1fKU/llq0sIYEvX64EWONYF0M4t7kYZ7GIpmHQjD8NBXy98OUr/35VW\nTsR2P6DEfaaE/7N/pC0BmbZ9Tkt6jqAaVYnoqpvAkof+KBn7EBuR2T9rcDwF\nd38FiJJV6t6/NggqaZY6SwwlJThjeL4QVaze6TqEHdds7eITrAMtc55zWtU5\nhgILI7iOF6xVq5WSueTKgVx0K1ibHzPHrG3VPOUyu/yq0/Pmxd4Z3AZ6alrB\n/a58++L16fS0ydgLrUSyzhEop08rRd18MctUNNarBOLkKqKi1hTcemDW3NKT\nRgX/XmDedU9az+R/55ZtOX1/8CYtCk09Y9pHfuLO8SUhSCrdh/1EhESPZeiC\nNqviplpcPAj+q2gPv+6+ev1aiObBOP5OXBQx9d/pnhBrxbPZMz7Y2lnguhom\nVUBaLFGzRRnq0hMpwUTZ37Oe5fpp6vzaHyL8WNxolfm7Gf7t1a/SQD2yjxiw\nPiDJL+JURDiLz15iewR00171ykkjh73YV3yEqZOKP4EdjKOrhsV8A8wKW8OE\nv0YehRJgG7yWGd5Y0r9Vs1Sm5rnSHOQye3Eqo2ZSLHM/mwVsXKN2LMcvcvSa\nqgc3\r\n=Bw2x\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDbM+/mSpZG1SZvkyUosWseh5ywmJkTRiPKtDO7OERFcgIhAMBBoitaUhAGYAFzGYXSktVxVo62S+wR97+y77lh651V"}]},"_npmUser":{"name":"tangzk","email":"tangzk@yeah.net"},"directories":{},"maintainers":[{"name":"tangzk","email":"tangzk@yeah.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/o-crop_1.0.0_1615553664095_0.8069029044688465"},"_hasShrinkwrap":false},"1.0.1":{"name":"o-crop","version":"1.0.1","description":"alloyCrop改","main":"index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"keywords":["crop"],"dependencies":{"alloyfinger":"^0.1.8","css3transform":"^1.1.7"},"author":{"name":"tangzk"},"license":"MIT","_id":"o-crop@1.0.1","_nodeVersion":"14.15.4","_npmVersion":"7.5.4","dist":{"integrity":"sha512-FTwYAPtk0HPRVEU0PDC+7rRto9cRyCFLwYzGNcgu1D7uM38Sqm+qgHJewxU/IUfnQVwN5qRIwdKZ8YhH92vy6Q==","shasum":"a4e1b44a0d2ed841f222ce062828c12acf563756","tarball":"https://registry.npmjs.org/o-crop/-/o-crop-1.0.1.tgz","fileCount":2,"unpackedSize":13748,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgS2bJCRA9TVsSAnZWagAA6LQP/jT4aDcYb8dNr0zTW1/D\nlTG501QVAQnSkkG4WSMOR0x+yEe+Ev0JWyZDmJjs8bIpTKz9rW16EGEvq1cL\ncvNSGX/quyFzLDWxn4+R4I1vuaEJme+c6r4/N13+MX1S/eGR8JJwZQVlL/48\nVZu5zoWHS4yI80VUU1aH4KEw97AD3VS7rMWj738R0q633YV5apOg5mSAje7d\nV3IbmhC2WRDDRPU+0Y4qHKTeEURp9E23ActP81KdiKIgB4p3YDsUeW/TPBZb\navg80nJg9YpD7tBZdYa5U1Et9J95CKH8NC9Zd+H3O8uEpH0NXhgVPrufA1Fr\nZF21nyB8H0KX0iNN5UMjIY6Rie/5l5Kdepk/bBs06WsYr5x/qoIAQRLSmNtI\niIZ985j4H1GGDBJaoMi2dxIwyKzGr75wcjuh4SDVWslSsG8U1Qv6V4n42xcw\n9bBCG10wn2RknsJFVH3xj2B9qCvNvJ/FVCI3XBndVwNcEnTc0SRBKUoCbyK/\nuox0650D2OkiUnorLgjx9Zg+CBw4VhNsuqGa/fDrkHF4FnGTrarTgW/z92Va\nmfeedicMazzT3LYiDDlw7YYc6CoyC8VDiBWeYu9Xxh5pEcBe4USZQfJL6VVE\n2+izbTZ/MDN9stgw3YVv6et8/LYIpywXWYVWo8VDbG0gfBvq7NtJEomkewSM\nmekE\r\n=uq0s\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDyyFbjM4Xb0vH9rUsgA0GfyLM/TBwPlla/uBSgT096TwIhAPmzRBExxVrmGIeaUMPcSYLpcccO+4s1XuEYFF6D+2q2"}]},"_npmUser":{"name":"tangzk","email":"tangzk@yeah.net"},"directories":{},"maintainers":[{"name":"tangzk","email":"tangzk@yeah.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/o-crop_1.0.1_1615554249176_0.5720772939757721"},"_hasShrinkwrap":false},"1.0.2":{"_from":"o-crop@^1.0.1","_id":"o-crop@1.0.2","_inBundle":false,"_integrity":"sha512-FTwYAPtk0HPRVEU0PDC+7rRto9cRyCFLwYzGNcgu1D7uM38Sqm+qgHJewxU/IUfnQVwN5qRIwdKZ8YhH92vy6Q==","_location":"/o-crop","_phantomChildren":{},"_requested":{"type":"range","registry":true,"raw":"o-crop@^1.0.1","name":"o-crop","escapedName":"o-crop","rawSpec":"^1.0.1","saveSpec":null,"fetchSpec":"^1.0.1"},"_requiredBy":["/"],"_resolved":"https://registry.npmjs.org/o-crop/-/o-crop-1.0.1.tgz","_shasum":"a4e1b44a0d2ed841f222ce062828c12acf563756","_spec":"o-crop@^1.0.1","_where":"D:\\workspace\\my\\pi\\apps\\ji-dan","author":{"name":"tangzk"},"homepage":"https://gitee.com/327630285/o-crap#readme","dependencies":{"alloyfinger":"^0.1.8","css3transform":"^1.1.7"},"deprecated":false,"description":"alloyCrop改","keywords":["crop"],"license":"MIT","main":"index.js","name":"o-crop","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"version":"1.0.2","gitHead":"dd095c2f4d24b597bd5d0a3b2ae9f5b1b26312f8","_nodeVersion":"14.16.0","_npmVersion":"6.14.11","dist":{"integrity":"sha512-Ac7qAK4Mh6zm5mXqAeDbwml8VHU+nRvwa0z/ilWKxkV+OHxAy+2LJrxH2/gr569CkTYZ6gH3ioh52CjH+ah3Yw==","shasum":"87e8a47bf865df36b6acaf29ba37e0c6180dae7e","tarball":"https://registry.npmjs.org/o-crop/-/o-crop-1.0.2.tgz","fileCount":13,"unpackedSize":385674,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgTxdJCRA9TVsSAnZWagAACOUP/20h+ur8FMXW71LghAJh\n9fP/lyZUHnCIRezMuJAeo7HJ/LoPpHoIsA/GjmMb6P3uZNc2SO5ZveMDnomu\nKHpHJkfCE6A4t2Anbs8FB9rB9W/IiQ71YiJ31S99h6+wu4pMccEYPMQxLHyb\nxf0SgyonLTHsJ5TGKs1dymZEzkILosjgBMt/dgIO+X4P96KMcTEv5xQLDKu7\npxmDPlWG0izNAXwjhx7LuSCysXGCjsuRbNqatAyyp7fYsMj1DO2B2gMInWsX\n5p0yBmposjAI1eL2tjqvlJymjDq3kwbSBx6dcol01WsfVm+yfP4pb/jiq9qK\nKx5e5LSQg6rB39gIcSAZhNha4FDSYFDqNVNIB+6LWuxk0ZN5Q2OZPDgCxurT\n9h9GmEFv8Ryuft3hZnj9rwvzbxbUc7xg0K/gIkMXGMFDu0ao3uuN+2aW3j02\nFVKW5P6A+g+QYm0/MJRlMaVifScYnvgCNY2qBoYQk9bdIoh8LQgYRB9rZ6Aq\nUT2jCHxxVfyZF5gdw7sXxCLZ84rcRui2mdRGoyA1uL5Iuw7p9kPZc+mbWAvK\nyUuI8RPc1Gwrm1NtKuM1rw6k1yrmOnH7sbwCkxc8UcOMGIOoqPjxMIPU+LLz\nTJqOTqsaGwF+EJfxGciJvdiD8WN4Fbc7SpCpY3j91lzELkNVMzYFXTO5G9+o\nv8oa\r\n=ff+r\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIF/rOwCKbuFmdNltpk1C/Wdfnq7LNO/s8J/IJPBBfFknAiA2r27VzmTtHsHQvYGLYcSpteqOsyB6/BzVEzLraYsQdg=="}]},"_npmUser":{"name":"tangzk","email":"tangzk@yeah.net"},"directories":{},"maintainers":[{"name":"tangzk","email":"tangzk@yeah.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/o-crop_1.0.2_1615796040963_0.3505304393989974"},"_hasShrinkwrap":false},"1.0.3":{"author":{"name":"tangzk"},"homepage":"https://gitee.com/327630285/o-crap#readme","dependencies":{"alloyfinger":"^0.1.8","css3transform":"^1.1.7"},"deprecated":false,"description":"alloyCrop改","keywords":["crop"],"license":"MIT","main":"index.js","name":"o-crop","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"version":"1.0.3","gitHead":"dd095c2f4d24b597bd5d0a3b2ae9f5b1b26312f8","_id":"o-crop@1.0.3","_nodeVersion":"14.16.0","_npmVersion":"6.14.11","dist":{"integrity":"sha512-Heg+CSh9F80Xns7dMMICQk815w73TsxYSOY28B8eSh2GEvfT5CwtUEa32Ma2OxFCf+Jl8aCQ5m7FWWi5oXEPdw==","shasum":"87d42223708cd00e4b3b745300de8e62ab17a765","tarball":"https://registry.npmjs.org/o-crop/-/o-crop-1.0.3.tgz","fileCount":13,"unpackedSize":384975,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgTxetCRA9TVsSAnZWagAA0p4P/jDRsVBkFk7bvn/D36od\nZbKRENRb4ochkprLvYpyZvgEwvNBmUPqf830a98QChye+OEMArG1BBM8iU/k\nqE7fPxmmXiY431VwTl7CiyWK8YOzEsN1ddtOFSnkbldy40YWdWr/RkzmcjM+\ndluYjd3Cv9cpydlTxmkSYPxj9ksk7nFPDSb7YWxtDhZCRWALB3kgxYsFky43\ndRxQZqzDXx8HLu2JYA0/vXYgHz9NMJDCyfMsbHxAihOgCoOhckOhPR/EiWYM\n1noFx5cVvv5l8zCRwv5gIDsyMa2y04tjYmAtQIPCsDdKrelSm0J9YBmeMh9i\nfnxLyyipFO8LJsJ6lyYISrxtehvF1tKKc9+epG0u5MTbEXxhCyOv5+UOsjhc\nQLiS4I7hf+nP8vEMehRtTRDH+Fo/9avT1jEPzGSnOhe1cD2XscbFYCMcVn+O\n/h+k8+xgS/xfJaIog2yXLUUV/96MHMT8JrUaZg+h6Auh+VgGWBsyplyXMLT2\nHBJmtVFIDWHGsSqnlDYzdsu3x+Nb9tYc14TGfhpOIj1jhwjYcBu/5/0cyrF1\nGqltJ3iQp+S1rRKQR1QTFHDlUndAa5jYfzO6zTa1MSNe/M+HV1FVrHUtAtBl\nSVBsSqSubgaDiwnFPKD3fg+q9luHx9K5u9EUNZtPSANJZm0tBZsWFLzLXsOw\ngaul\r\n=MRIS\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGC+Uit1uahgXgUSHvojyTzBcKDnxozTnvNsC4qqN7YZAiBLiyW4auy8sFoIjGxne17dl4jBmbl6jVw1GXguIdTQJQ=="}]},"_npmUser":{"name":"tangzk","email":"tangzk@yeah.net"},"directories":{},"maintainers":[{"name":"tangzk","email":"tangzk@yeah.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/o-crop_1.0.3_1615796140583_0.48709365005324323"},"_hasShrinkwrap":false}},"time":{"created":"2021-03-12T12:54:24.095Z","1.0.0":"2021-03-12T12:54:24.245Z","modified":"2022-05-12T00:01:37.427Z","1.0.1":"2021-03-12T13:04:09.296Z","1.0.2":"2021-03-15T08:14:01.176Z","1.0.3":"2021-03-15T08:15:40.781Z"},"maintainers":[{"name":"tangzk","email":"tangzk@yeah.net"}],"description":"alloyCrop改","keywords":["crop"],"author":{"name":"tangzk"},"license":"MIT","readme":"﻿## OCrop\r\n\r\n基于AlloyCrop，优化了裁剪时的缩放方式。\r\n\r\n* 裁剪图像的分辨率太小，是否可配？\r\n* pinch双指放大的时候，放大的中心不是双指中心，是否可以优化？\r\n\r\n现在很高兴地告诉大家，OCrop 已经完全搞定了上面两个问题，本文将解释新版本的变化和OCrop背后的原理。当然AlloyFinger的原理这里就不再阐述，以前有分享过 [超小Web手势库AlloyFinger原理](./asset/alloyfinger.md)\r\n\r\n先看全新的API变化。\r\n\r\n## API\r\n\r\n```js\r\nnew OCrop({\r\n    image_src: \"img src\",\r\n    className: 'crop-box',\r\n    circle: true, // optional parameters , the default value is false\r\n    width: 200, // crop width\r\n    height: 100, // crop height\r\n    output: 2, // output resolution --> 400*200\r\n    ok: function (base64, canvas) { },\r\n    cancel: function () { },\r\n    ok_text: \"yes\", // optional parameters , the default value is ok\r\n    cancel_text: \"no\" // optional parameters , the default value is cancel\r\n});\r\n```\r\n\r\n参数 |是否必填 | 意义\r\n----|------|----\r\nimage_src | 必须  | 需要裁剪图片的src地址\r\nclassName | 不必须  | 裁剪 DOM 容器的 class\r\ncircle | 不必须，默认是false  | 代表选取的是否是圆形还是矩形，默认是矩形，注意:圆形选取裁剪出来的也是正方形图片\r\nwidth | 必须  | 选区的宽\r\nheight | 必须  | 选区的高\r\noutput | 必须 | 输出的倍率。比如如果output为2，选区的宽300，选区的高100，输出的图像的分辨率为 (2×300，2×100）\r\nok | 必须  | 点击ok按钮的回调\r\ncancel | 必须  | 点击cancel按钮的回调\r\nok_text | 不必须，默认是ok  | ok按钮的文本\r\ncancel_text | 不必须，默认是cancel  | cancel按钮的文本\r\n\r\n与之前版本最主要的变化就是新增了 output 支持自定义倍率分辨率的图像输出。\r\n\r\n## output原理\r\n\r\n```js\r\ncrop: function() {\r\n    this.calculateRect();\r\n    this.ctx.drawImage(this.img, this.crop_rect[0], this.crop_rect[1], this.crop_rect[2], this.crop_rect[3], 0, 0, this.canvas.width, this.canvas.height);\r\n\r\n},\r\n```\r\n\r\n其中 this.calculateRect() 是计算选取和图片重叠在一起的矩形区域，drawImage 是把裁剪的区域绘制到 canvas 上。注意 canvas 的宽高是多少？且看:\r\n\r\n```js\r\nthis.canvas.width = option.width * this.output;\r\nthis.canvas.height = option.height * this.output;\r\n```\r\n\r\n所以就达到了自定义倍率分辨率的目的。当然这里图片的失真又或者超分辨，都取决于 drawImage 插值过程。关于插值，以前特意对比过，使用三次卷积插值完爆了其他几个,但是三次卷积插值速度也是最慢，所以浏览器内核要权衡效率和插值结果去实现 drawImage。\r\n\r\n![img](http://images2017.cnblogs.com/blog/105416/201708/105416-20170801102838052-884320030.jpg)\r\n\r\n## calculateRect计算裁剪区域\r\n\r\n因为我们需要把图片的某个区域绘制到整个canvas上。所以drawImage的后四个参数为（0, 0, this.canvas.width, this.canvas.height），然后我们需要去计算图片裁剪的区域。\r\n\r\n![pv](http://images2017.cnblogs.com/blog/105416/201708/105416-20170801103251646-2132149523.jpg)\r\n\r\n大概就分上面两种情况，一种是完全包含，一种部分相交。\r\n\r\n![](http://images2017.cnblogs.com/blog/105416/201708/105416-20170801104639005-638761920.jpg)\r\n\r\n![](http://images2017.cnblogs.com/blog/105416/201708/105416-20170801104749802-38131761.jpg)\r\n\r\n因为图片会被放大或者缩小(scale)，所以情况会变得稍微复杂一点点。求出相交的矩形区域后，要对图片scale进行校正，校正回到1的比例，才能用于drawImage。具体代码参见 [https://github.com/AlloyTeam/OCrop/blob/master/alloy-crop.js#L227-L255](https://github.com/AlloyTeam/OCrop/blob/master/alloy-crop.js#L227-L255)\r\n\r\n## pinch 缩放优化\r\n\r\n使用OCrop是可以放大或者缩小再进行裁剪，怎么基于 pinch 的两个手指的中间进行放大呢？所以的秘密都在这个multipointStart里。\r\n\r\n* multipointStart是AlloyFinger抛出的多手指开始碰到屏幕的回调函数，通过evt.touches拿到前两个手指的坐标去计算中心坐标\r\n* 重置 originX 和 originY　到两手指的中心\r\n* 再重置 translateX 和 translateY　去抹平　originX和originY变更带来的位移\r\n\t\r\n```js\r\n new AlloyFinger(this.croppingBox, {\r\n\tmultipointStart: function (evt) {\r\n\t    //reset origin x and y\r\n\t    var centerX = (evt.touches[0].pageX + evt.touches[1].pageX) / 2;\r\n\t    var centerY = (evt.touches[0].pageY + evt.touches[1].pageY) / 2;\r\n\t    var cr = self.img.getBoundingClientRect();\r\n\t    var img_centerX = cr.left + cr.width / 2;\r\n\t    var img_centerY = cr.top + cr.height / 2;\r\n\t    var offX = centerX - img_centerX;\r\n\t    var offY = centerY - img_centerY;\r\n\t    var preOriginX = self.img.originX;\r\n\t    var preOriginY = self.img.originY;\r\n\t    self.img.originX = offX / self.img.scaleX;\r\n\t    self.img.originY = offY / self.img.scaleY;\r\n\t    //reset translateX and translateY\r\n\t    self.img.translateX += offX - preOriginX * self.img.scaleX;\r\n\t    self.img.translateY += offY - preOriginY * self.img.scaleX;\r\n\t    self.initScale = self.img.scaleX;\r\n\t},\r\n\tpinch: function (evt) {\r\n\t    self.img.scaleX = self.img.scaleY = self.initScale * evt.zoom;\r\n\t},\r\n\tpressMove: function (evt) {\r\n\t    self.img.translateX += evt.deltaX;\r\n\t    self.img.translateY += evt.deltaY;\r\n\t    evt.preventDefault();\r\n\t}\r\n});\r\n```\r\n\r\n* 注意，translateX, translateY, translateZ, scaleX, scaleY, scaleZ, rotateX, rotateY, rotateZ, skewX, skewY, originX, originY, originZ 都是 [css3transform 类库](https://alloyteam.github.io/AlloyTouch/transformjs/) 注入到DOM元素上的属性。\r\n\r\n## Preview\r\n\r\n![Preview](http://images2017.cnblogs.com/blog/105416/201707/105416-20170731173956990-1895070647.jpg)\r\n\r\n## Install\r\n\r\nYou can install it via npm:\r\n\r\n```html\r\nnpm install o-crop\r\n```\r\n\r\n## Dependencies\r\n\r\n* [AlloyFinger](https://github.com/AlloyTeam/AlloyFinger)\r\n* [css3transform](https://alloyteam.github.io/AlloyTouch/transformjs/)\r\n\r\n\r\n## License\r\nThis content is released under the [MIT](http://opensource.org/licenses/MIT) License.","readmeFilename":"README.md","homepage":"https://gitee.com/327630285/o-crap#readme"}