UNPKG

react-clipper

Version:

A responsive image clipper tool for React.

335 lines (298 loc) 13.9 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _reactImageCrop = require('react-image-crop'); var _reactImageCrop2 = _interopRequireDefault(_reactImageCrop); require('react-image-crop/dist/ReactCrop.css'); require('../index.css'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var Clipper = function (_React$Component) { _inherits(Clipper, _React$Component); function Clipper(props) { _classCallCheck(this, Clipper); var _this = _possibleConstructorReturn(this, (Clipper.__proto__ || Object.getPrototypeOf(Clipper)).call(this, props)); _this.state = _extends({}, props); return _this; } _createClass(Clipper, [{ key: 'render', value: function render() { var _this2 = this; var _state = this.state, originUri = _state.originUri, clipWidth = _state.clipWidth, clipHeight = _state.clipHeight, crop = _state.crop, keepSelection = _state.keepSelection, disabled = _state.disabled, crossorigin = _state.crossorigin, maxWidth = _state.maxWidth, maxHeight = _state.maxHeight, minWidth = _state.minWidth, minHeight = _state.minHeight; return _react2.default.createElement( 'div', { className: 'clipper-wrap' }, _react2.default.createElement( 'div', { style: { width: 545 + clipWidth, height: 500 } }, _react2.default.createElement( 'div', { className: 'clipper-main', ref: 'imgWrap' }, this._renderUploadBtn(), _react2.default.createElement(_reactImageCrop2.default, { src: originUri, onImageLoaded: function onImageLoaded(crop, image, pixelCrop) { return _this2.onImageLoaded(crop, image, pixelCrop); }, onComplete: function onComplete(crop, pixelCrop) { return _this2.onCropComplete(crop, pixelCrop); }, onAspectRatioChange: function onAspectRatioChange(crop, pixelCrop) { return _this2.onAspectRatioChange(crop, pixelCrop); }, onChange: function onChange(crop, pixelCrop) { return _this2.onChange(crop, pixelCrop); }, onDragStart: function onDragStart(e) { return _this2.onDragStart(e); }, onDragEnd: function onDragEnd(e) { return _this2.onDragEnd(e); }, crop: crop, maxWidth: maxWidth, maxHeight: maxHeight, minWidth: minWidth, minHeight: minHeight, keepSelection: keepSelection, disabled: disabled, crossorigin: crossorigin }) ), _react2.default.createElement( 'div', { className: 'clipper-sub', style: { width: 30 + clipWidth } }, _react2.default.createElement( 'div', { className: 'preview' }, '\u9884\u89C8' ), _react2.default.createElement( 'div', { className: 'imgItem', style: { width: clipWidth, height: clipHeight } }, _react2.default.createElement('canvas', { id: 'clipped', ref: 'clipped', style: { width: clipWidth, height: clipHeight } }) ), _react2.default.createElement( 'div', { className: 'describe' }, clipWidth, 'px x ', clipHeight, 'px' ) ) ), this._renderReUploadBtn() ); } }, { key: 'onChange', value: function onChange(crop, pixelCrop) { var _this3 = this; var _state2 = this.state, originUri = _state2.originUri, clipWidth = _state2.clipWidth, clipHeight = _state2.clipHeight, onChange = _state2.onChange; var canvas = this.refs.clipped; var ctx = canvas.getContext('2d'); var img = new Image(); img.src = originUri; img.onload = function () { canvas.width = clipWidth; canvas.height = clipHeight; ctx.drawImage(img, pixelCrop.x, pixelCrop.y, pixelCrop.width, pixelCrop.height, 0, 0, clipWidth, clipHeight); var clippedUri = canvas.toDataURL(); _this3.setState({ clippedUri: clippedUri, crop: { x: crop.x, y: crop.y, width: crop.width, height: crop.height, aspect: _this3.state.crop.aspect } }); onChange(crop, pixelCrop, clippedUri); }; } }, { key: 'onDragStart', value: function onDragStart() { var onDragStart = this.state.onDragStart; onDragStart(); } }, { key: 'onDragEnd', value: function onDragEnd() { var _state3 = this.state, onDragEnd = _state3.onDragEnd, clippedUri = _state3.clippedUri, originUri = _state3.originUri; onDragEnd(clippedUri, originUri); } }, { key: 'onImageLoaded', value: function onImageLoaded(crop, image, pixelCrop) { var onImageLoaded = this.state.onImageLoaded; this.onChange(crop, pixelCrop); onImageLoaded(crop, image, pixelCrop); } }, { key: 'onCropComplete', value: function onCropComplete(crop, pixelCrop) { var onCropComplete = this.state.onCropComplete; onCropComplete(crop, pixelCrop); } }, { key: 'onAspectRatioChange', value: function onAspectRatioChange(crop, pixelCrop) { var onAspectRatioChange = this.state.onAspectRatioChange; onAspectRatioChange(crop, pixelCrop); } }, { key: '_renderUploadBtn', value: function _renderUploadBtn() { var _this4 = this; var originUri = this.state.originUri; if (!originUri) { return _react2.default.createElement( 'a', { href: 'javascript:;', className: 'upload-btn' }, _react2.default.createElement('input', { type: 'file', onChange: function onChange(e) { return _this4.upload(e); } }), '\u9009\u62E9\u56FE\u7247' ); } } }, { key: '_renderReUploadBtn', value: function _renderReUploadBtn() { var _this5 = this; var originUri = this.state.originUri; if (originUri) { return _react2.default.createElement( 'div', { className: 'clear' }, _react2.default.createElement( 'a', { href: 'javascript:;', className: 'upload-btn' }, _react2.default.createElement('input', { type: 'file', onChange: function onChange(e) { return _this5.upload(e); } }), '\u91CD\u65B0\u4E0A\u4F20' ) ); } } }, { key: 'upload', value: function upload(e) { var _this6 = this; var file = e.target.files[0]; var reader = new FileReader(); reader.onload = function (e) { var data = e.target.result; _this6.paintImg(data); }; reader.readAsDataURL(file); } //原图缩放 }, { key: 'paintImg', value: function paintImg(uri) { var _this7 = this; var canvas = document.createElement('canvas'); var ctx = canvas.getContext('2d'); var wrapWidth = this.refs.imgWrap.offsetWidth; var wrapHeight = this.refs.imgWrap.offsetHeight; var ctxImgWidth = void 0, ctxImgHeight = void 0; var img = new Image(); img.src = uri; img.onload = function () { //等比例缩放图片(如果图片宽高都比容器小,则绘制的图片宽高 = 原图片的宽高。) //如果图片的宽度或者高度比容器大,则宽度或者高度 = 容器的宽度或者高度,另一高度或者宽度则等比例缩放 if (img.width < wrapWidth && img.height < wrapHeight) { ctxImgWidth = img.width; ctxImgHeight = img.height; } else { var pWidth = img.width / (img.height / wrapHeight); var pHeight = img.height / (img.width / wrapWidth); ctxImgWidth = img.width > img.height ? wrapWidth : pWidth; ctxImgHeight = img.height > img.width ? wrapHeight : pHeight; } canvas.width = ctxImgWidth; canvas.height = ctxImgHeight; ctx.drawImage(img, 0, 0, ctxImgWidth, ctxImgHeight); var originUri = canvas.toDataURL(); _this7.setState({ originUri: originUri }); }; } }]); return Clipper; }(_react2.default.Component); Clipper.propTypes = { clipWidth: _react.PropTypes.number, clipHeight: _react.PropTypes.number, originUri: _react.PropTypes.string, crop: _react.PropTypes.shape({ x: _react.PropTypes.number, y: _react.PropTypes.number, width: _react.PropTypes.number, height: _react.PropTypes.number }), minWidth: _react.PropTypes.number, minHeight: _react.PropTypes.number, maxWidth: _react.PropTypes.number, maxHeight: _react.PropTypes.number, keepSelection: _react.PropTypes.bool, onChange: _react.PropTypes.func, onComplete: _react.PropTypes.func, onImageLoaded: _react.PropTypes.func, onAspectRatioChange: _react.PropTypes.func, onDragStart: _react.PropTypes.func, onDragEnd: _react.PropTypes.func, disabled: _react.PropTypes.bool, crossorigin: _react.PropTypes.string }; Clipper.defaultProps = { originUri: '', clipWidth: 100, clipHeight: 100, crop: undefined, crossorigin: undefined, disabled: false, maxWidth: 100, maxHeight: 100, minWidth: 0, minHeight: 0, keepSelection: false, onChange: function onChange() {}, onComplete: function onComplete() {}, onImageLoaded: function onImageLoaded() {}, onAspectRatioChange: function onAspectRatioChange() {}, onCropComplete: function onCropComplete() {}, onDragStart: function onDragStart() {}, onDragEnd: function onDragEnd() {} }; exports.default = Clipper;