UNPKG

vue3-signature-pad

Version:
504 lines (433 loc) 15.8 kB
'use strict';var vue=require('vue'),OriginalSignaturePad=require('signature_pad'),mergeImages=require('merge-images');function _interopDefaultLegacy(e){return e&&typeof e==='object'&&'default'in e?e:{'default':e}}var OriginalSignaturePad__default=/*#__PURE__*/_interopDefaultLegacy(OriginalSignaturePad);var mergeImages__default=/*#__PURE__*/_interopDefaultLegacy(mergeImages);function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread2(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); } function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }var ImageTypesEnum; (function (ImageTypesEnum) { ImageTypesEnum["PNG"] = "image/png"; ImageTypesEnum["JPEG"] = "image/jpeg"; ImageTypesEnum["SVG"] = "image/svg+xml"; })(ImageTypesEnum || (ImageTypesEnum = {})); var SaveOutputsEnum; (function (SaveOutputsEnum) { SaveOutputsEnum["FILE"] = "file"; SaveOutputsEnum["DATA_URL"] = "data_url"; })(SaveOutputsEnum || (SaveOutputsEnum = {})); function binaryStringToFile(bstr, filename, mimeType) { var lastModified = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : Date.now(); var n = bstr.length; var u8arr = new Uint8Array(n); while (n--) { u8arr[n] = bstr.charCodeAt(n); } return new File([u8arr], filename, { type: mimeType, lastModified: lastModified }); } function dataURLtoFile(dataUrl, filename) { var lastModified = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : Date.now(); var arr = dataUrl.split(','); var leftSideArr = arr[0]; var parts = leftSideArr.match(/:(.*?);/); if (!parts) { throw new Error('Invalid data url'); } var mimeType = parts[1]; var bstr = atob(arr[1]); return binaryStringToFile(bstr, filename, mimeType, lastModified); } // eslint-disable-next-line var convert2NonReactive = function convert2NonReactive(observerValue) { return JSON.parse(JSON.stringify(observerValue)); }; var TRANSPARENT_PNG = { x: 0, y: 0, src: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=" };var DEFAULT_OPTIONS = { dotSize: (0.5 + 2.5) / 2, minWidth: 0.5, maxWidth: 2.5, throttle: 16, minDistance: 5, backgroundColor: "rgba(0,0,0,0)", penColor: "black", velocityFilterWeight: 0.7 // onBegin: (event) => {}, // onEnd: (event) => {}, }; var script = /*#__PURE__*/vue.defineComponent({ name: "VueSignaturePad", props: { modelValue: { type: [String, File], required: false }, width: { type: Number, default: 250, validator: function validator(value) { return 0 <= value && value <= 99999; } }, height: { type: Number, default: 150, validator: function validator(value) { return 0 <= value && value <= 99999; } }, saveType: { type: String, default: ImageTypesEnum.PNG, validator: function validator(value) { var allowedValues = Object.values(ImageTypesEnum); if (!allowedValues.includes(value)) { console.warn("The Image type is incorrect! Supported ones are ".concat(allowedValues.join(", "), ".")); return false; } return true; } }, saveOutput: { type: String, default: SaveOutputsEnum.DATA_URL, validator: function validator(value) { var allowedValues = Object.values(SaveOutputsEnum); if (!allowedValues.includes(value)) { console.warn("The save output is incorrect! Supported ones are ".concat(allowedValues.join(", "), ".")); return false; } return true; } }, customStyle: { type: Object, default: function _default() { return {}; } }, options: { type: Object, default: function _default() { return DEFAULT_OPTIONS; } }, images: { type: Array, default: function _default() { return []; } } }, setup: function setup(props, context) { // state var state = vue.reactive({ cacheImages: [], onResizeHandler: null, signaturePad: {}, signatureData: TRANSPARENT_PNG }); // ref: signaturePadCanvas var signaturePadCanvas = vue.ref(null); // computed properties var signaturePadCanvasElement = vue.computed(function () { if (!signaturePadCanvas.value) { throw new Error('No canvas could be found with this "ref" in the template'); } return signaturePadCanvas.value; }); var propsImagesAndCustomImages = vue.computed(function () { var nonReactiveProrpImages = Array.from(convert2NonReactive(props.images)); var nonReactiveCachImages = Array.from(convert2NonReactive(state.cacheImages)); return [].concat(_toConsumableArray(nonReactiveProrpImages), _toConsumableArray(nonReactiveCachImages)); }); // watch vue.watch(function () { return props.options; }, function (nextOptions) { Object.keys(nextOptions).forEach(function (option) { if (Object.prototype.hasOwnProperty.call(state.signaturePad, option)) { state.signaturePad[option] = nextOptions[option]; } }); }); // methods function resizeCanvas() { var canvas = signaturePadCanvasElement.value; var data = state.signaturePad.toData(); var ratio = Math.max(window.devicePixelRatio || 1, 1); canvas.width = canvas.offsetWidth * ratio; canvas.height = canvas.offsetHeight * ratio; var context = canvas.getContext("2d"); if (context) { context.scale(ratio, ratio); } state.signaturePad.clear(); state.signatureData = TRANSPARENT_PNG; state.signaturePad.fromData(data); } function saveSignature() { var type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : props.saveType; var encoderOptions = arguments.length > 1 ? arguments[1] : undefined; if (state.signaturePad.isEmpty()) { if (props.saveOutput === SaveOutputsEnum.FILE) { return { isEmpty: true, file: null, output: SaveOutputsEnum.FILE }; } else if (props.saveOutput === SaveOutputsEnum.DATA_URL) { return { isEmpty: true, data: null, output: SaveOutputsEnum.DATA_URL }; } else { throw new Error("This saveOutput ".concat(props.saveOutput, " is not supported")); } } var dataURL = state.signaturePad.toDataURL(type, encoderOptions); state.signatureData.src = dataURL; if (props.saveOutput === SaveOutputsEnum.FILE) { return { isEmpty: false, file: dataURLtoFile(dataURL, 'signature'), output: SaveOutputsEnum.FILE }; } else if (props.saveOutput === SaveOutputsEnum.DATA_URL) { return { isEmpty: false, data: dataURL, output: SaveOutputsEnum.DATA_URL }; } else { throw new Error("This saveOutput ".concat(props.saveOutput, " is not supported")); } } function undoSignature() { var record = state.signaturePad.toData(); if (record) { state.signaturePad.fromData(record.slice(0, -1)); } } function completedSignature() { var savedSignature = saveSignature(); var inputData = null; if (savedSignature.output === SaveOutputsEnum.FILE) { inputData = savedSignature.file; } else if (savedSignature.output === SaveOutputsEnum.DATA_URL) { inputData = savedSignature.data; } context.emit("input", inputData); } function mergeImageAndSignature(customSignature) { state.signatureData = customSignature; return mergeImages__default['default']([].concat(_toConsumableArray(props.images), _toConsumableArray(state.cacheImages), [state.signatureData])); } function addImages() { var images = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; state.cacheImages = [].concat(_toConsumableArray(state.cacheImages), _toConsumableArray(images)); return mergeImages__default['default']([].concat(_toConsumableArray(props.images), _toConsumableArray(state.cacheImages), [state.signatureData])); } function fromDataURL(dataURL) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var callback = arguments.length > 2 ? arguments[2] : undefined; state.signaturePad.fromDataURL(dataURL, options, callback); } function fromData(data) { state.signaturePad.fromData(data); } function toDataURL() { var type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ImageTypesEnum.PNG; var encoderOptions = arguments.length > 1 ? arguments[1] : undefined; return state.signaturePad.toDataURL(type, encoderOptions); } function toData() { return state.signaturePad.toData(); } function lockSignaturePad() { state.signaturePad.off(); } function openSignaturePad() { state.signaturePad.on(); } function isEmpty() { return state.signaturePad.isEmpty(); } function getPropImagesAndCacheImages() { return propsImagesAndCustomImages.value; } function clearCacheImages() { state.cacheImages = []; return state.cacheImages; } function clearSignature() { state.signaturePad.clear(); context.emit("input", null); } // hooks vue.onMounted(function () { var canvas = signaturePadCanvasElement.value; var signaturePad = new OriginalSignaturePad__default['default'](canvas, _objectSpread2({ onEnd: completedSignature }, props.options)); state.signaturePad = signaturePad; state.onResizeHandler = resizeCanvas; window.addEventListener("resize", state.onResizeHandler, false); resizeCanvas(); }); vue.onBeforeUnmount(function () { if (state.onResizeHandler) { window.removeEventListener("resize", state.onResizeHandler, false); } }); return _objectSpread2(_objectSpread2({}, vue.toRefs(state)), {}, { signaturePadCanvas: signaturePadCanvas, // computed properties propsImagesAndCustomImages: propsImagesAndCustomImages, // methods resizeCanvas: resizeCanvas, saveSignature: saveSignature, undoSignature: undoSignature, mergeImageAndSignature: mergeImageAndSignature, addImages: addImages, fromDataURL: fromDataURL, toDataURL: toDataURL, fromData: fromData, toData: toData, lockSignaturePad: lockSignaturePad, openSignaturePad: openSignaturePad, isEmpty: isEmpty, getPropImagesAndCacheImages: getPropImagesAndCacheImages, clearCacheImages: clearCacheImages, clearSignature: clearSignature }); }, render: function render() { var width = this.width, height = this.height, customStyle = this.customStyle; var baseStyle = { width: "".concat(width, "px"), height: "".concat(height, "px") }; return vue.h("div", { style: _objectSpread2(_objectSpread2({}, baseStyle), customStyle) }, [vue.h("canvas", { style: { width: "100%", height: "100%" }, ref: "signaturePadCanvas" })]); } });// Import vue component // Default export is installable instance of component. // IIFE injects install function into component, allowing component // to be registered via Vue.use() as well as Vue.component(), var component = /*#__PURE__*/(function () { // Assign InstallableComponent type var installable = script; // Attach install function executed by Vue.use() installable.install = function (app) { app.component('SignaturePad', installable); }; return installable; })(); // It's possible to expose named exports when writing components that can // also be used as directives, etc. - eg. import { RollupDemoDirective } from 'rollup-demo'; // export const RollupDemoDirective = directive; var namedExports=/*#__PURE__*/Object.freeze({__proto__:null,'default': component});// only expose one global var, with named exports exposed as properties of // that global var (eg. plugin.namedExport) Object.entries(namedExports).forEach(function (_ref) { var _ref2 = _slicedToArray(_ref, 2), exportName = _ref2[0], exported = _ref2[1]; if (exportName !== 'default') component[exportName] = exported; });module.exports=component;