We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
/* * 图片预览组件 * @Author: Jiang * @since: 2018-12-21 13:54:00 */ import React from 'react'; import { Modal, Icon } from 'antd'; import PropTypes from 'prop-types'; import config from 'Common/config'; import { redirect } from 'Common/util'; import './index.less'; // 判断游览器 const USER_AGENT = navigator.userAgent; export default class PreviewImage extends React.Component { constructor(props) { super(props); // 是否按下 this.isDown = false; this.IMG_WIDTH = 300; this.IMG_HEIGHT = 300; // 放大或缩小比例 this.zoomOut = 0; this.state = { // 移动的时候,更改距离和放大缩小 imgStyle: { position: 'relative', left: '0px', top: '0px' }, // 放大缩小比例 num: 0, // 是否显示缩小放大比例 isShowRate: false, // true 为图片模式, false为pdf|word|xls预览模式 isShowPreView: false }; // 图片按下事件 this.handlerImgDown = this.handlerImgDown.bind(this); // 图片加载 this.onload = this.onload.bind(this); } componentDidMount() { const { url, destruction } = this.props; // true 打开弹窗 false 预览pdf or xls or word if(this.getType(url)) { const getType = this.getType(url); if(document.addEventListener && USER_AGENT.indexOf('Firefox') > -1) { document.addEventListener('DOMMouseScroll', this.onScroll, false); } else { document.body.onmousewheel = this.onScroll; } this.setState({ isShowPreView: getType }); } else { this.openUrl(url); destruction(); } } // 销毁 componentWillUnmount() { document.onmousemove = null; document.onmouseup = null; document.body.onmousewheel = null; document.removeEventListener('DOMMouseScroll', this.onScroll, false); } // 取得文件后缀名 getFileSuffix = url => { const fileArr = url.split('.'); return fileArr[fileArr.length - 1].toLocaleLowerCase(); } // 根据文件类型是跳转页面还是预览图片 getType = url => { if(url) { let suffix = this.getFileSuffix(url); if(suffix.indexOf('?') > -1) { suffix = suffix.split('?')[0]; } return config.FILE_TYPE.IMAGE.indexOf(suffix) > -1; } } // 缩小或放大 onScroll = (e) => { const { num, imgStyle } = this.state; const event = e || window.event; let style = {}; let wheelDelta; let wheelDeltaNumber; let rate; // firefox and safari 的滚动轴值不一样,其余的都是1200 if(USER_AGENT.indexOf('Firefox') > -1) { // wheelDelta = 3 or -3 wheelDelta = event.detail; wheelDeltaNumber = 30; } else if(USER_AGENT.indexOf('Safari') > -1) { // wheelDelta = 360 or -360 wheelDelta = event.wheelDelta; wheelDeltaNumber = 3600; } else { // wheelDelta = 120 or -120 wheelDelta = event.wheelDelta; wheelDeltaNumber = 1200; } // 如果比例达到100或者为1的时候,停止继续放大或缩小 > 0 放大, < 0 缩小 if((num === 100 && wheelDelta > 0) || (num === 1 && wheelDelta < 0)) { return; } // 计算放大或缩小比例 this.zoomOut = (this.zoomOut + wheelDelta / wheelDeltaNumber); style.width = this.IMG_WIDTH * (1 + this.zoomOut) + 'px'; style.height = this.IMG_HEIGHT * (1 + this.zoomOut) + 'px'; style.top = imgStyle.top; style.left = imgStyle.left; style.position = 'relative'; // 换算成百分比,显示 if(this.zoomOut.toFixed(1) * 100 < 0) { rate = 10 + (this.zoomOut.toFixed(1) * 100) / 10; } else { rate = parseInt(this.zoomOut.toFixed(1) * 100); } // 不允许出现百分之0 rate = rate === 0 ? rate = 10 : rate; this.setState({ imgStyle: style, num: rate, isShowRate: true }); } // 打开pdf、xls、word等文件 openUrl = url => { if(url) { redirect(url, '_blank'); } } // 图片按下事件 handlerImgDown = (e) => { e.preventDefault(); const previewImg = document.getElementsByClassName('preview-image'); this.isDown = true; this.currentX = e.clientX; this.currentY = e.clientY; this.offsetLeft = parseInt(previewImg[0].offsetLeft); this.offsetTop = parseInt(previewImg[0].offsetTop); this.handlerImgMove(); // 移除事件 document.onmouseup = () => { document.onmousemove = null; document.onmouseup = null; this.isDown = false; }; } // 图片移动 handlerImgMove = () => { document.onmousemove = (e) => { if(this.isDown) { const { imgStyle } = this.state; let style = {}; style.width = imgStyle.width + 'px'; style.height = imgStyle.height + 'px'; style.left = e.clientX - (this.currentX - this.offsetLeft) + 'px'; style.top = e.clientY - (this.currentY - this.offsetTop) + 'px'; style.position = 'relative'; this.setState({ imgStyle: style }); } }; } // 获取图片真实宽高 onload = (e) => { this.IMG_WIDTH = e.target.width; this.IMG_HEIGHT = e.target.height; } render() { const { imgStyle, isShowRate, num } = this.state; const { url, hideModal } = this.props; const { isShowPreView } = this.state; return ( <div className="c-c-preview-image"> { isShowPreView && <Modal wrapClassName="c-c-preview-image-modal" visible={true} centered={true} closable={false} width="100%" onCancel={hideModal} footer={null} > <img draggable="false" alt="img" className="preview-image select-cursor" onMouseDown={this.handlerImgDown} src={url} onLoad={this.onload} style={imgStyle} /> { isShowRate && <div className="viewer-tooltip">{num}%</div> } </Modal> } <Icon onClick={hideModal} className="close" type="close" /> </div> ); } } PreviewImage.propTypes = { // src or pdf or xls or word url: PropTypes.string, };
@import "../../../common/asset/variable.less"; .c-c-preview-image { .close { position: fixed; padding: 15px; top: 0px; right: 0px; font-size: 32px; color: #333; cursor: pointer; z-index: 1002; } } .c-c-preview-image-modal { overflow: hidden; user-select: none; .viewer-tooltip { background-color: rgba(0,0,0,.8); border-radius: 10px; color: #fff; font-size: 12px; height: 20px; left: 50%; line-height: 20px; margin-left: -25px; margin-top: -10px; position: absolute; text-align: center; top: 50%; width: 50px; z-index: 1001; } .ant-modal-close-x { font-size: 32px; } .select-cursor { cursor: move; cursor: grab; } .ant-modal-close { position: fixed; color: #333; } .ant-modal-body { padding: 0px; } .ant-modal-content { background-color: transparent; box-shadow: none; position: absolute; user-select: none; left: 50%; top: 50%; transform: translate(-50%, -50%); } }
The text was updated successfully, but these errors were encountered:
No branches or pull requests
源码
less
The text was updated successfully, but these errors were encountered: