123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267 |
- // 宽高比
- const aspectRatio = 1 / 1;
- // 自动裁剪区域, 默认为 50%
- const autoCropAre = 0.5;
- // 裁剪宽度
- const croppedWidth = 200;
- // 裁剪高度
- const croppedHeight = croppedWidth * aspectRatio;
- // 是否裁剪为圆形
- const roundedCrop = true;
- const fileUploadBox = document.querySelector(".file-upload-box");
- const saveBtn = document.querySelector("#save");
- const previews = document.querySelectorAll(".preview");
- let previewReady = false;
- let croppable = false;
- document.addEventListener("UniAppJSBridgeReady", Init);
- async function Init(params) {
- console.log(`uniAppSDK loaded`);
- const env = await getEnv();
- console.log("当前环境:" + JSON.stringify(env));
- const imgDataUrl = await selectFile(env);
- // hidden input box
- fileUploadBox.style.display = "none";
- // create image
- const image = new Image();
- image.src = imgDataUrl;
- image.crossorigin = true;
- document.querySelector(".img-crop-area").appendChild(image);
- image.onload = function () {
- const options = {
- aspectRatio: aspectRatio,
- autoCropAre: autoCropAre,
- viewMode: 1,
- ready: function () {
- let clone = this.cloneNode();
- clone.className = "";
- clone.style.cssText =
- "display: block;" +
- "width: 100%;" +
- "min-width: 0;" +
- "min-height: 0;" +
- "max-width: none;" +
- "max-height: none;";
- each(previews, function (elem) {
- elem.appendChild(clone.cloneNode());
- });
- croppable = true;
- previewReady = true;
- saveBtn.classList.remove("disabled");
- if (roundedCrop) {
- const elements = document.querySelectorAll(
- ".cropper-view-box, .cropper-face"
- );
- for (let item of elements) {
- item.style.borderRadius = "50%";
- }
- }
- },
- crop: function (event) {
- if (!previewReady) {
- return;
- }
- let data = event.detail;
- let cropper = this.cropper;
- let imageData = cropper.getImageData();
- let previewAspectRatio = data.width / data.height;
- each(previews, function (elem) {
- let previewImage = elem.getElementsByTagName("img").item(0);
- let previewWidth = elem.offsetWidth;
- let previewHeight = previewWidth / previewAspectRatio;
- let imageScaledRatio = data.width / previewWidth;
- if (roundedCrop) {
- elem.style.borderRadius = "50%";
- }
- elem.style.height = previewHeight + "px";
- previewImage.style.width =
- imageData.naturalWidth / imageScaledRatio + "px";
- previewImage.style.height =
- imageData.naturalHeight / imageScaledRatio + "px";
- previewImage.style.marginLeft = -data.x / imageScaledRatio + "px";
- previewImage.style.marginTop = -data.y / imageScaledRatio + "px";
- });
- },
- };
- const cropper = new Cropper(image, options);
- save.addEventListener("click", () => {
- if (!croppable) {
- return;
- }
- let croppedCanvas = cropper.getCroppedCanvas({
- width: croppedWidth,
- height: croppedHeight,
- });
- if (roundedCrop) {
- croppedCanvas = getRoundedCanvas(croppedCanvas);
- }
- const postData = {
- data: {
- type: "croppedData",
- dataUrl: croppedCanvas.toDataURL(),
- },
- };
- // console.log(`postData`, postData);
- if (env.plus) {
- uni.postMessage(postData);
- } else if (env.h5) {
- top.postMessage(postData);
- } else if (env.miniprogram) {
- // 小程序
- top.postMessage(postData);
- }
- // back to previous page
- uni.navigateBack({
- delta: 1,
- });
- });
- };
- }
- function getRoundedCanvas(sourceCanvas) {
- let canvas = document.createElement("canvas");
- let context = canvas.getContext("2d");
- let width = sourceCanvas.width;
- let height = sourceCanvas.height;
- canvas.width = width;
- canvas.height = height;
- context.imageSmoothingEnabled = true;
- context.drawImage(sourceCanvas, 0, 0, width, height);
- context.globalCompositeOperation = "destination-in";
- context.beginPath();
- context.arc(
- width / 2,
- height / 2,
- Math.min(width, height) / 2,
- 0,
- 2 * Math.PI,
- true
- );
- context.fill();
- return canvas;
- }
- function each(arr, callback) {
- let length = arr.length;
- let i;
- for (i = 0; i < length; i++) {
- callback.call(arr, arr[i], i, arr);
- }
- return arr;
- }
- async function selectFile(env) {
- const fileInput = document.querySelector("#my-input");
- return new Promise((resolve, reject) => {
- fileInput.addEventListener("change", async (event) => {
- let result;
- result = await getDataUrlFromReader(event);
- resolve(result);
- });
- });
- }
- async function getDataUrlFromReader(event) {
- const files = event.target.files;
- return new Promise((resolve, reject) => {
- const reader = new FileReader();
- reader.addEventListener("loadend", () => {
- resolve(reader.result);
- });
- reader.readAsDataURL(files[0]);
- });
- }
- async function getEnv() {
- return new Promise((resolve, reject) => {
- uni.getEnv((res) => {
- resolve(res);
- });
- });
- }
- // TODO:
- async function chooseWithPlusApi() {
- const btnArray = [
- {
- title: "拍照",
- },
- {
- title: "从手机相册选择",
- },
- ];
- return new Promise((resolve, reject) => {
- plus.nativeUI.actionSheet(
- {
- cancel: "取消",
- buttons: btnArray,
- },
- function (e) {
- let index = e.index;
- switch (index) {
- case 0:
- break;
- case 1:
- let camera = plus.camera.getCamera();
- camera.captureImage(
- function (file) {
- resolve(file);
- },
- function () {
- console.log("从相机获取照片失败");
- reject("从相机获取照片失败");
- },
- {
- filename: "_doc/photo/",
- index: 1,
- }
- );
- break;
- case 2:
- plus.gallery.pick(
- function (file) {
- resolve(file);
- },
- function () {
- console.log("取消图片选择");
- reject("取消图片选择");
- },
- {
- multiple: false,
- }
- );
- break;
- }
- }
- );
- });
- }
|