UNPKG

@zhuxiaozy/clipimg

Version:
362 lines 13.8 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import Mouse from "./mouse.js"; ``; let mouse; export default class ClipImg { constructor(config) { this.reviewSrc = ''; this.controllerIsDown = false; this.el = config.el; this.reviewCall = config.reviewCall; this.canvas = document.createElement("canvas"); this.controllerBox = document.createElement("div"); this.context = this.canvas.getContext("2d"); this.imgCtx = { x: 0, y: 0, width: 0, height: 0, n: 0, img: document.createElement("img"), draw: () => { this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); this.context.drawImage(this.imgCtx.img, this.imgCtx.x, this.imgCtx.y, this.imgCtx.width, this.imgCtx.height); this.getClipView(); }, }; mouse = new Mouse(); this.init(); } init() { this.el.style.position = "relative"; this.el.appendChild(this.canvas); this.canvas.width = this.el.clientWidth; this.canvas.height = this.el.clientHeight; this.getEvent(); this.createControlBox(); this.createControlBoxImg(); } createControlBoxImg() { if (this.reviewSrc) { this.controllerBox.style.backgroundImage = `url('${this.reviewSrc}')`; this.controllerBox.style.backgroundSize = '100% 100%'; this.controllerBox.style.backgroundPosition = '0 0'; } } getEvent() { let isDown = false; let lx; let ly; this.el.addEventListener("mousedown", (e) => { if (this.controllerIsDown) { return; } const offsetX = e.pageX - this.el.getBoundingClientRect().x; const offsetY = e.pageY - this.el.getBoundingClientRect().y; lx = this.imgCtx.x - offsetX; ly = this.imgCtx.y - offsetY; isDown = true; }); this.el.addEventListener("mousemove", (e) => { if (this.controllerIsDown) { return; } const offsetX = e.pageX - this.el.getBoundingClientRect().x; const offsetY = e.pageY - this.el.getBoundingClientRect().y; if (offsetX > this.imgCtx.x && offsetX < this.imgCtx.x + this.imgCtx.width && offsetY > this.imgCtx.y && offsetY < this.imgCtx.y + this.imgCtx.height) { if (isDown) { this.imgCtx.x = offsetX + lx; this.imgCtx.y = offsetY + ly; this.imgCtx.draw(); } } }); this.el.addEventListener("mouseleave", () => { isDown = false; }); this.el.addEventListener("mouseup", () => { isDown = false; }); const n = 8; mouse.scrollDown = () => { this.imgCtx.width += n; if (this.imgCtx.width <= this.canvas.width * 3) { this.imgCtx.height = this.imgCtx.width / this.imgCtx.n; this.imgCtx.x -= n / 2; this.imgCtx.y -= n / 2; } else { this.imgCtx.width = this.canvas.width * 3; this.imgCtx.height = this.imgCtx.width / this.imgCtx.n; } this.imgCtx.draw(); }; mouse.scrollUp = () => { this.imgCtx.width -= n; if (this.imgCtx.width >= 50) { this.imgCtx.height = this.imgCtx.width / this.imgCtx.n; this.imgCtx.x += n / 2; this.imgCtx.y += n / 2; } else { this.imgCtx.width = 50; this.imgCtx.height = this.imgCtx.width / this.imgCtx.n; } this.imgCtx.draw(); }; } setImg(file) { const img = new Image(); img.src = URL.createObjectURL(file); img.onload = () => { const imgWidth = img.width; const imgHeight = img.height; const n = imgWidth / imgHeight; let width = this.canvas.width; let height = this.canvas.height; if (n > 1.7777777) { width = this.canvas.width; height = width / n; } else if (n < 1.7777777) { height = this.canvas.height; width = height * n; } const x = (this.canvas.width - width) / 2; const y = (this.canvas.height - height) / 2; this.imgCtx.x = x; this.imgCtx.y = y; this.imgCtx.width = width; this.imgCtx.height = height; this.imgCtx.n = n; this.imgCtx.img = img; this.imgCtx.draw(); }; } setSize(width = 160, height = 90) { this.controllerBox.style.width = width + "px"; this.controllerBox.style.height = height + "px"; } createControlBox() { this.controllerBox.style.cssText = ` position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%); border: 1px solid #5c5c5c; `; this.setSize(160, 90); const pointBtn = [ this.createControlBtn(8, 8, "lt"), this.createControlBtn(8, 8, "rt"), this.createControlBtn(8, 8, "lb"), this.createControlBtn(8, 8, "rb"), ]; pointBtn.forEach((btn) => { this.controllerBox.appendChild(btn); }); this.el.appendChild(this.controllerBox); } createControlBtn(width, height, type) { const div = document.createElement("div"); div.style.cssText = ` width: ${width}px; height: ${height}px; position: absolute; cursor: pointer; background: #cccccc; `; div.setAttribute("type", type); if (type === "lt" || type === "rt") { div.style.top = -height / 2 + "px"; } if (type === "lt" || type === "lb") { div.style.left = -width / 2 + "px"; } if (type === "lb" || type === "rb") { div.style.bottom = -height / 2 + "px"; } if (type === "rt" || type === "rb") { div.style.right = -width / 2 + "px"; } let divType = ""; let n = 0; div.addEventListener("mousedown", () => { n = this.controllerBox.offsetWidth / this.controllerBox.offsetHeight; divType = div.getAttribute("type"); this.controllerIsDown = true; }); this.el.addEventListener("mouseup", () => { divType = ""; this.controllerIsDown = false; }); this.el.addEventListener("mouseleave", () => { divType = ""; this.controllerIsDown = false; }); this.el.addEventListener("mousemove", (e) => { if (this.controllerIsDown) { const parent = div.parentNode; const x = e.pageX - this.el.getBoundingClientRect().x; if (divType === "lt" || divType === "lb") { let width = this.canvas.width - x * 2; width = width > this.canvas.width ? this.canvas.width : width; width = width < 100 ? 100 : width; if (width / n > this.canvas.height) { parent.style.width = this.canvas.height * n + "px"; parent.style.height = this.canvas.height + "px"; return; } parent.style.width = width + "px"; parent.style.height = width / n + "px"; this.getClipView(); } if (divType === "rt" || divType === "rb") { let width = this.canvas.width - (this.canvas.width - x) * 2; width = width > this.canvas.width ? this.canvas.width : width; width = width < 100 ? 100 : width; if (width / n > this.canvas.height) { parent.style.width = this.canvas.height * n + "px"; parent.style.height = this.canvas.height + "px"; return; } parent.style.width = width + "px"; parent.style.height = width / n + "px"; this.getClipView(); } } }, true); return div; } computeSize(width) { } getClipView() { if (!this.context) { return; } const opt = this.controllerBox.getBoundingClientRect(); const x = this.controllerBox.offsetLeft - opt.width / 2; const y = this.controllerBox.offsetTop - opt.height / 2; const width = opt.width; const height = opt.height; const data = this.context.getImageData(x, y, width, height); const canvas = document.createElement("canvas"); canvas.width = width; canvas.height = height; const ctx = canvas.getContext("2d"); ctx.putImageData(data, 0, 0); this.reviewSrc = canvas.toDataURL('image/jpeg'); this.createControlBoxImg(); if (this.reviewCall) { this.reviewCall(this.reviewSrc); } } getClipData(size = 4096) { return new Promise((resolve) => { document.body.appendChild(this.imgCtx.img); const opt = this.controllerBox.getBoundingClientRect(); const x = this.controllerBox.offsetLeft - opt.width / 2; const y = this.controllerBox.offsetTop - opt.height / 2; const width = opt.width; const height = opt.height; const n = this.imgCtx.img.offsetWidth / this.imgCtx.width; const canvas = document.createElement("canvas"); const ctx = canvas.getContext("2d"); canvas.width = this.imgCtx.img.offsetWidth; canvas.height = this.imgCtx.img.offsetHeight; document.body.removeChild(this.imgCtx.img); ctx.drawImage(this.imgCtx.img, 0, 0, canvas.width, canvas.height); const data = ctx.getImageData((x - this.imgCtx.x) * n, (y - this.imgCtx.y) * n, width * n, height * n); const canvas2 = document.createElement("canvas"); const ctx2 = canvas2.getContext("2d"); canvas2.width = width * n; canvas2.height = height * n; ctx2.putImageData(data, 0, 0); canvas2.toBlob((blob) => __awaiter(this, void 0, void 0, function* () { let blobs = yield this.compress(blob); while (blobs.size / 1024 > size) { blobs = yield this.compress(blobs); } const url = URL.createObjectURL(blobs); resolve({ url: url, blob: blobs, }); })); }); } compress(blob) { return new Promise((resolve) => { const canvas = document.createElement("canvas"); const ctx = canvas.getContext("2d"); const img = new Image(); img.style.cssText = ` position:absolute; top:-9999999px; left:-99999999; `; document.body.appendChild(img); img.onload = () => { canvas.width = img.width * 0.9; canvas.height = img.height * 0.9; document.body.removeChild(img); ctx.drawImage(img, 0, 0, canvas.width, canvas.height); canvas.toBlob((blobs) => { resolve(blobs); }, "image/jpeg"); }; img.src = URL.createObjectURL(blob); }); } clientX(el) { return this.pageX(el) - this.scrollX(); } clientY(el) { return this.pageY(el) - this.scrollY(); } pageX(el) { let parent = el; let x = 0; while (parent) { x += parent.offsetLeft; parent = parent.offsetParent; } return x; } pageY(el) { let parent = el; let y = 0; while (parent) { y += parent.offsetTop; parent = parent.offsetParent; } return y; } scrollX(elOrWindow) { let x = 0; if (elOrWindow) { x = elOrWindow.scrollLeft; } return x; } scrollY(elOrWindow) { let y = 0; if (elOrWindow) { y = elOrWindow.scrollTop; } return y; } } window['ClipImg'] = ClipImg; //# sourceMappingURL=imgClip.js.map