diff --git a/dist/perspectivets.min.js b/dist/perspectivets.min.js index c40d675..5ab640e 100644 --- a/dist/perspectivets.min.js +++ b/dist/perspectivets.min.js @@ -1,7 +1,9 @@ -!function(t,a){"object"==typeof exports&&"undefined"!=typeof module?module.exports=a():"function"==typeof define&&define.amd?define(a):(t="undefined"!=typeof globalThis?globalThis:t||self).Perspective=a()}(this,(function(){"use strict"; +!function(t,o){"object"==typeof exports&&"undefined"!=typeof module?module.exports=o():"function"==typeof define&&define.amd?define(o):(t="undefined"!=typeof globalThis?globalThis:t||self).Perspective=o()}(this,(function(){"use strict"; /*! - Copyright 2021 Adonmo https://www.adonmo.com/ - Copyright 2010 futomi http://www.html5.jp/ + Copyright 2010 futomi + Copyright 2014 Fabien LOISON + Copyright 2021 Adonmo + Copyright 2021 Aarni Koskela Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,9 +16,5 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - - This file was modified by Fabien LOISON - - This file was further modified by Adonmo https://www.adonmo.com/ - */return function(){function t(t,a){if(t&&t.strokeStyle&&a&&a.width&&a.height){var e=document.createElement("canvas");e.width=Math.round(a.width),e.height=Math.round(a.height);var o=e.getContext("2d");o.drawImage(a,0,0,e.width,e.height);var i=document.createElement("canvas");i.width=t.canvas.width,i.height=t.canvas.height;var h=i.getContext("2d");this.ctxd=t,this.cvso=e,this.ctxo=o,this.ctxt=h}}return t.prototype.draw=function(t){for(var a=t.topLeftX,e=t.topLeftY,o=t.topRightX,i=t.topRightY,h=t.bottomRightX,n=t.bottomRightY,s=t.bottomLeftX,r=t.bottomLeftY,c=[Math.sqrt(Math.pow(a-o,2)+Math.pow(e-i,2)),Math.sqrt(Math.pow(o-h,2)+Math.pow(i-n,2)),Math.sqrt(Math.pow(h-s,2)+Math.pow(n-r,2)),Math.sqrt(Math.pow(s-a,2)+Math.pow(r-e,2))],p=this.cvso.width,d=this.cvso.height,f=0,v=0,g=0,l=0;l<4;l++){var m=0;(m=l%2?c[l]/p:c[l]/d)>v&&(f=l,v=m),0==c[l]&&g++}if(!(g>1)){var w=this.ctxo,M=this.ctxt;if(M.clearRect(0,0,M.canvas.width,M.canvas.height),f%2==0){(Y=this.create_canvas_context(p,10)).globalCompositeOperation="copy";for(var u=Y.canvas,x=0;xv&&(u=w,v=C),0==y&&b++}if(!(b>1)){var M,R=5*a,x=this,L=x.originalCanvas,T=x.transformedContext,X=x.destinationContext,Y=T.canvas;if(T.clearRect(0,0,Y.width,Y.height),u%2==0)(M=t(c,R)).globalCompositeOperation="copy",e(L,M,T,!0,c,m,a,i,d,n,g,r,s,h,f);else(M=t(R,m)).globalCompositeOperation="copy",e(L,M,T,!1,c,m,a,i,r,n,h,d,s,g,f);X.save(),X.drawImage(Y,0,0),function(t,o){var e=o.bottomLeftX,a=o.bottomLeftY,i=o.bottomRightX,n=o.bottomRightY,r=o.topLeftX,h=o.topLeftY,s=o.topRightX,f=o.topRightY;t.beginPath(),t.moveTo(r,h),t.lineTo(s,f),t.lineTo(i,n),t.lineTo(e,a),t.closePath(),t.globalCompositeOperation="destination-in",t.fill(),t.globalCompositeOperation="source-over"}(X,o),X.restore()}},o}()})); //# sourceMappingURL=perspectivets.min.js.map diff --git a/dist/perspectivets.min.js.map b/dist/perspectivets.min.js.map index 921c281..dcc6a46 100644 --- a/dist/perspectivets.min.js.map +++ b/dist/perspectivets.min.js.map @@ -1 +1 @@ -{"version":3,"file":"perspectivets.min.js","sources":["../src/index.ts"],"sourcesContent":["/*!\nCopyright 2021 Adonmo https://www.adonmo.com/\nCopyright 2010 futomi http://www.html5.jp/\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\nThis file was modified by Fabien LOISON \n\nThis file was further modified by Adonmo https://www.adonmo.com/\n*/\n\ninterface Quadrilateral {\n topLeftX: number;\n topLeftY: number;\n topRightX: number;\n topRightY: number;\n bottomRightX: number;\n bottomRightY: number;\n bottomLeftX: number;\n bottomLeftY: number;\n}\n\nexport default class Perspective {\n // Context for destination (output will go here)\n private ctxd: CanvasRenderingContext2D;\n\n // Canvas for original image\n private cvso: HTMLCanvasElement;\n\n // Context for original image\n private ctxo: CanvasRenderingContext2D;\n\n // Context for transformed image\n private ctxt: CanvasRenderingContext2D;\n\n constructor(ctxd: CanvasRenderingContext2D, image: HTMLImageElement) {\n // check the arguments\n if (!ctxd || !ctxd.strokeStyle) {\n return;\n }\n if (!image || !image.width || !image.height) {\n return;\n }\n // prepare a for the image\n let cvso = document.createElement(\"canvas\");\n cvso.width = Math.round(image.width);\n cvso.height = Math.round(image.height);\n let ctxo = cvso.getContext(\"2d\");\n ctxo.drawImage(image, 0, 0, cvso.width, cvso.height);\n // prepare a for the transformed image\n let cvst = document.createElement(\"canvas\");\n cvst.width = ctxd.canvas.width;\n cvst.height = ctxd.canvas.height;\n let ctxt = cvst.getContext(\"2d\");\n\n this.ctxd = ctxd;\n this.cvso = cvso;\n this.ctxo = ctxo;\n this.ctxt = ctxt;\n }\n\n draw(q: Quadrilateral) {\n let {\n topLeftX,\n topLeftY,\n topRightX,\n topRightY,\n bottomRightX,\n bottomRightY,\n bottomLeftX,\n bottomLeftY,\n } = q;\n\n // compute the dimension of each side\n let dims = [\n Math.sqrt(\n Math.pow(topLeftX - topRightX, 2) + Math.pow(topLeftY - topRightY, 2)\n ), // top side\n Math.sqrt(\n Math.pow(topRightX - bottomRightX, 2) +\n Math.pow(topRightY - bottomRightY, 2)\n ), // right side\n Math.sqrt(\n Math.pow(bottomRightX - bottomLeftX, 2) +\n Math.pow(bottomRightY - bottomLeftY, 2)\n ), // bottom side\n Math.sqrt(\n Math.pow(bottomLeftX - topLeftX, 2) +\n Math.pow(bottomLeftY - topLeftY, 2)\n ), // left side\n ];\n //\n let ow = this.cvso.width;\n let oh = this.cvso.height;\n // specify the index of which dimension is longest\n let base_index = 0;\n let max_scale_rate = 0;\n let zero_num = 0;\n for (let i = 0; i < 4; i++) {\n let rate = 0;\n if (i % 2) {\n rate = dims[i] / ow;\n } else {\n rate = dims[i] / oh;\n }\n if (rate > max_scale_rate) {\n base_index = i;\n max_scale_rate = rate;\n }\n if (dims[i] == 0) {\n zero_num++;\n }\n }\n if (zero_num > 1) {\n return;\n }\n //\n let step = 2;\n let cover_step = step * 5;\n //\n let ctxo = this.ctxo;\n let ctxt = this.ctxt;\n ctxt.clearRect(0, 0, ctxt.canvas.width, ctxt.canvas.height);\n if (base_index % 2 == 0) {\n // top or bottom side\n let ctxl = this.create_canvas_context(ow, cover_step);\n ctxl.globalCompositeOperation = \"copy\";\n let cvsl = ctxl.canvas;\n for (let y = 0; y < oh; y += step) {\n let r = y / oh;\n let sx = topLeftX + (bottomLeftX - topLeftX) * r;\n let sy = topLeftY + (bottomLeftY - topLeftY) * r;\n let ex = topRightX + (bottomRightX - topRightX) * r;\n let ey = topRightY + (bottomRightY - topRightY) * r;\n let ag = Math.atan((ey - sy) / (ex - sx));\n let sc = Math.sqrt(Math.pow(ex - sx, 2) + Math.pow(ey - sy, 2)) / ow;\n ctxl.setTransform(1, 0, 0, 1, 0, -y);\n ctxl.drawImage(ctxo.canvas, 0, 0);\n //\n ctxt.translate(sx, sy);\n ctxt.rotate(ag);\n ctxt.scale(sc, sc);\n ctxt.drawImage(cvsl, 0, 0);\n //\n ctxt.setTransform(1, 0, 0, 1, 0, 0);\n }\n } else if (base_index % 2 == 1) {\n // right or left side\n let ctxl = this.create_canvas_context(cover_step, oh);\n ctxl.globalCompositeOperation = \"copy\";\n let cvsl = ctxl.canvas;\n for (let x = 0; x < ow; x += step) {\n let r = x / ow;\n let sx = topLeftX + (topRightX - topLeftX) * r;\n let sy = topLeftY + (topRightY - topLeftY) * r;\n let ex = bottomLeftX + (bottomRightX - bottomLeftX) * r;\n let ey = bottomLeftY + (bottomRightY - bottomLeftY) * r;\n let ag = Math.atan((sx - ex) / (ey - sy));\n let sc = Math.sqrt(Math.pow(ex - sx, 2) + Math.pow(ey - sy, 2)) / oh;\n ctxl.setTransform(1, 0, 0, 1, -x, 0);\n ctxl.drawImage(ctxo.canvas, 0, 0);\n //\n ctxt.translate(sx, sy);\n ctxt.rotate(ag);\n ctxt.scale(sc, sc);\n ctxt.drawImage(cvsl, 0, 0);\n //\n ctxt.setTransform(1, 0, 0, 1, 0, 0);\n }\n }\n // set a clipping path and draw the transformed image on the destination canvas.\n this.ctxd.save();\n this.ctxd.drawImage(ctxt.canvas, 0, 0);\n this._applyMask(this.ctxd, q);\n this.ctxd.restore();\n }\n\n private create_canvas_context(w: number, h: number) {\n let canvas = document.createElement(\"canvas\");\n canvas.width = w;\n canvas.height = h;\n let ctx = canvas.getContext(\"2d\");\n return ctx;\n }\n\n private _applyMask(ctx: CanvasRenderingContext2D, q: Quadrilateral) {\n ctx.beginPath();\n ctx.moveTo(q.topLeftX, q.topLeftY);\n ctx.lineTo(q.topRightX, q.topRightY);\n ctx.lineTo(q.bottomRightX, q.bottomRightY);\n ctx.lineTo(q.bottomLeftX, q.bottomLeftY);\n ctx.closePath();\n ctx.globalCompositeOperation = \"destination-in\";\n ctx.fill();\n ctx.globalCompositeOperation = \"source-over\";\n }\n}\n"],"names":["ctxd","image","strokeStyle","width","height","cvso","document","createElement","Math","round","ctxo","getContext","drawImage","cvst","canvas","ctxt","this","Perspective","q","topLeftX","topLeftY","topRightX","topRightY","bottomRightX","bottomRightY","bottomLeftX","bottomLeftY","dims","sqrt","pow","ow","oh","base_index","max_scale_rate","zero_num","i","rate","clearRect","ctxl","create_canvas_context","step","globalCompositeOperation","cvsl","y","sx","r","sy","ex","ey","ag","atan","sc","setTransform","translate","rotate","scale","x","save","_applyMask","restore","w","h","ctx","beginPath","moveTo","lineTo","closePath","fill"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"perspectivets.min.js","sources":["../src/index.ts"],"sourcesContent":["/*!\nCopyright 2010 futomi \nCopyright 2014 Fabien LOISON \nCopyright 2021 Adonmo \nCopyright 2021 Aarni Koskela \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport interface Quadrilateral {\n topLeftX: number;\n topLeftY: number;\n topRightX: number;\n topRightY: number;\n bottomRightX: number;\n bottomRightY: number;\n bottomLeftX: number;\n bottomLeftY: number;\n}\n\n\nfunction createCanvasContext(width: number, height: number): CanvasRenderingContext2D {\n const canvas = document.createElement(\"canvas\");\n canvas.width = width;\n canvas.height = height;\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return canvas.getContext(\"2d\")!;\n}\n\nfunction applyMask(ctx: CanvasRenderingContext2D, {\n bottomLeftX,\n bottomLeftY,\n bottomRightX,\n bottomRightY,\n topLeftX,\n topLeftY,\n topRightX,\n topRightY\n}: Quadrilateral): void {\n ctx.beginPath();\n ctx.moveTo(topLeftX, topLeftY);\n ctx.lineTo(topRightX, topRightY);\n ctx.lineTo(bottomRightX, bottomRightY);\n ctx.lineTo(bottomLeftX, bottomLeftY);\n ctx.closePath();\n ctx.globalCompositeOperation = \"destination-in\";\n ctx.fill();\n ctx.globalCompositeOperation = \"source-over\";\n}\n\nfunction drawSlice(\n originalCanvas: HTMLCanvasElement,\n tempContext: CanvasRenderingContext2D,\n targetContext: CanvasRenderingContext2D,\n tx: number,\n ty: number,\n sx: number,\n sy: number,\n ag: number,\n sc: number,\n) {\n tempContext.setTransform(1, 0, 0, 1, tx, ty);\n tempContext.drawImage(originalCanvas, 0, 0);\n targetContext.translate(sx, sy);\n targetContext.rotate(ag);\n targetContext.scale(sc, sc);\n targetContext.drawImage(tempContext.canvas, 0, 0);\n targetContext.setTransform(1, 0, 0, 1, 0, 0);\n}\n\nfunction drawSlices(\n originalCanvas: HTMLCanvasElement,\n tempContext: CanvasRenderingContext2D,\n transformedContext: CanvasRenderingContext2D,\n isYDirection: boolean,\n width: number,\n height: number,\n step: number,\n sx0: number,\n sx1: number,\n sy0: number,\n sy1: number,\n ex0: number,\n ex1: number,\n ey0: number,\n ey1: number,\n): void {\n const extent = (isYDirection ? height : width);\n for (let i = 0; i < extent; i += step) {\n const r = i / extent;\n const sx = sx0 + (sx1 - sx0) * r;\n const sy = sy0 + (sy1 - sy0) * r;\n const ex = ex0 + (ex1 - ex0) * r;\n const ey = ey0 + (ey1 - ey0) * r;\n const ag = isYDirection ? Math.atan((ey - sy) / (ex - sx)) : Math.atan((sx - ex) / (ey - sy));\n const sc = Math.hypot(ex - sx, ey - sy) / width;\n const tx = isYDirection ? 0 : -i;\n const ty = isYDirection ? -i : 0;\n drawSlice(originalCanvas, tempContext, transformedContext, tx, ty, sx, sy, ag, sc);\n }\n}\n\nexport default class Perspective {\n // Context for destination (output will go here)\n private readonly destinationContext: CanvasRenderingContext2D;\n\n // Canvas for original image\n private readonly originalCanvas: HTMLCanvasElement;\n\n // Context for transformed image\n private readonly transformedContext: CanvasRenderingContext2D;\n\n constructor(destinationContext: CanvasRenderingContext2D, image: HTMLImageElement) {\n // check the arguments\n if (!destinationContext || !destinationContext.strokeStyle || !image || !image.width || !image.height) {\n throw new Error(\"Invalid arguments\");\n }\n this.destinationContext = destinationContext;\n // prepare a for the image\n const cvso = document.createElement(\"canvas\");\n cvso.width = Math.round(image.width);\n cvso.height = Math.round(image.height);\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const ctxo = cvso.getContext(\"2d\")!;\n ctxo.drawImage(image, 0, 0, cvso.width, cvso.height);\n this.originalCanvas = cvso;\n // prepare a for the transformed image\n const destinationCanvas = destinationContext.canvas;\n this.transformedContext = createCanvasContext(destinationCanvas.width, destinationCanvas.height);\n }\n\n public draw(q: Quadrilateral, step = 2): void {\n const {\n topLeftX,\n topLeftY,\n topRightX,\n topRightY,\n bottomRightX,\n bottomRightY,\n bottomLeftX,\n bottomLeftY,\n } = q;\n\n // compute the dimension of each side\n const dims = [\n Math.hypot(topLeftX - topRightX, topLeftY - topRightY), // top side\n Math.hypot(topRightX - bottomRightX, topRightY - bottomRightY), // right side\n Math.hypot(bottomRightX - bottomLeftX, bottomRightY - bottomLeftY), // bottom side\n Math.hypot(bottomLeftX - topLeftX, bottomLeftY - topLeftY), // left side\n ];\n const { width, height } = this.originalCanvas;\n // specify the index of which dimension is longest\n let base_index = 0;\n let max_scale_rate = 0;\n let zero_num = 0;\n for (let i = 0; i < 4; i++) {\n const dim = dims[i];\n const rate = i % 2 ? dim / width : dim / height;\n if (rate > max_scale_rate) {\n base_index = i;\n max_scale_rate = rate;\n }\n if (dim == 0) {\n zero_num++;\n }\n }\n if (zero_num > 1) {\n return;\n }\n const coverStep = step * 5;\n const { originalCanvas, transformedContext, destinationContext } = this;\n const transformedCanvas = transformedContext.canvas;\n transformedContext.clearRect(0, 0, transformedCanvas.width, transformedCanvas.height);\n if (base_index % 2 == 0) {\n // top or bottom side\n const ctxl = createCanvasContext(width, coverStep);\n ctxl.globalCompositeOperation = \"copy\";\n drawSlices(originalCanvas, ctxl, transformedContext, true, width, height, step, topLeftX, bottomLeftX, topLeftY, bottomLeftY, topRightX, bottomRightX, topRightY, bottomRightY);\n } else {\n // right or left side\n const ctxl = createCanvasContext(coverStep, height);\n ctxl.globalCompositeOperation = \"copy\";\n drawSlices(originalCanvas, ctxl, transformedContext, false, width, height, step, topLeftX, topRightX, topLeftY, topRightY, bottomLeftX, bottomRightX, bottomLeftY, bottomRightY);\n }\n // set a clipping path and draw the transformed image on the destination canvas.\n destinationContext.save();\n destinationContext.drawImage(transformedCanvas, 0, 0);\n applyMask(destinationContext, q);\n destinationContext.restore();\n }\n}\n"],"names":["createCanvasContext","width","height","canvas","document","createElement","getContext","drawSlice","originalCanvas","tempContext","targetContext","tx","ty","sx","sy","ag","sc","setTransform","drawImage","translate","rotate","scale","drawSlices","transformedContext","isYDirection","step","sx0","sx1","sy0","sy1","ex0","ex1","ey0","ey1","extent","i","r","ex","ey","Math","atan","hypot","destinationContext","image","strokeStyle","Error","this","cvso","round","destinationCanvas","Perspective","q","topLeftX","topLeftY","topRightX","topRightY","bottomRightX","bottomRightY","bottomLeftX","bottomLeftY","dims","_a","base_index","max_scale_rate","zero_num","dim","rate","ctxl","coverStep","_b","transformedCanvas","clearRect","globalCompositeOperation","save","ctx","beginPath","moveTo","lineTo","closePath","fill","applyMask","restore"],"mappings":"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"} \ No newline at end of file