1.简介
预览窗口根据父组件width,height压缩自身宽高,按比例放入div,根据宽高大小自适应撑满宽或者高
效果图
WeChata41099fb1f8cc9bcbd6cbcd1f3d5f2f2.jpg
2、组件代码
import React from 'react';
import { Layout, Select } from 'antd';
import { CloseOutlined } from '@ant-design/icons';
import styles from './index.less';
const { Content } = Layout;
interface ScreenProps {
width: number;
height: number;
}
const Screen: React.FC<ScreenProps> = ({ width, height }) => (
<div
style={{
width: '100%',
height: '100%',
background: '#fff',
border: '1px solid #ccc',
boxSizing: 'border-box',
maxWidth: `${width}px`,
maxHeight: `${height}px`,
}}
>
<img
crossOrigin="anonymous"
style={{ width: '100%', height: '100%' }}
src="https://img.zcool.cn/community/011f355df5e6dca801219ccefe034c.jpg@2o.jpg"
/>
</div>
);
const Apps: React.FC = () => {
const optionsdata = [
{
value: '16:9',
label: '16:9',
},
{
value: '32:9',
label: '32:9',
},
{
value: '4:3',
label: '4:3',
},
{
value: '自定义',
label: '自定义',
},
];
const [width, setWidth] = React.useState(1920);
const [height, setHeight] = React.useState(1080);
const [widthview, setWidthview] = React.useState(1920);
const [heightview, setHeightview] = React.useState(1080);
const [viewDisable, setviewDisable] = React.useState(true);
const onChange = (e: React.FormEvent<HTMLInputElement>, name: string): void => {
const value = Number(e.currentTarget.value);
if (name === 'width') {
setWidth(value);
}
if (name === 'height') {
setHeight(value);
}
};
const handleChange = (value: string) => {
console.log(`selected ${value}`);
switch (value) {
case '16:9':
setWidth(1920);
setHeight(1080);
setviewDisable(true);
break;
case '32:9':
setWidth(3840);
setHeight(1080);
setviewDisable(true);
break;
case '4:3':
setWidth(4000);
setHeight(3000);
setviewDisable(true);
break;
case '自定义':
setviewDisable(false);
break;
default:
break;
}
};
const handleResize = React.useCallback((width: number, height: number) => {
setWidthview(width);
setHeightview(height);
}, []);
const divRef = React.useRef<HTMLDivElement>(null);
React.useEffect(() => {
const handleWindowResize = () => {
if (divRef.current) {
// const divWidth = divRef.current.offsetWidth;
// console.log(divWidth);
const { offsetWidth, offsetHeight } = divRef.current;
const aspectRatio = offsetWidth / offsetHeight;
if (aspectRatio > width / height) {
handleResize(offsetHeight * (width / height), offsetHeight);
} else {
handleResize(offsetWidth, offsetWidth * (height / width));
}
if (width / height == 1) {
if (offsetHeight > offsetWidth) {
handleResize(offsetWidth, offsetWidth);
} else {
handleResize(offsetHeight, offsetHeight);
}
}
}
// const { innerWidth, innerHeight } = window;
};
handleWindowResize();
window.addEventListener('resize', handleWindowResize);
return () => {
window.removeEventListener('resize', handleWindowResize);
};
}, [width, height, handleResize]);
return (
<>
<Layout
style={{
minWidth: '1200px',
height: '100%',
width: '100%',
position: 'absolute',
background: '#0E1017 ',
overflow: 'hidden',
}}
>
<Content
style={{
height: '36px',
width: '100%',
background: '#1C1F2E',
position: 'fixed',
top: '0',
}}
>
<span className={styles.viewsize}>
尺寸:
<Select
defaultValue="16:9"
style={{ width: 90 }}
bordered={false}
options={optionsdata}
onChange={handleChange}
/>
<span>
<input
type="number"
disabled={viewDisable}
className={styles.sizeinput}
value={width}
onChange={(e) => {
onChange(e, 'width');
}}
></input>
<CloseOutlined style={{ fontSize: '14px', color: '#535560', margin: '0 8px' }} />
<input
type="number"
disabled={viewDisable}
className={styles.sizeinput}
value={height}
onChange={(e) => {
onChange(e, 'height');
}}
></input>
</span>
</span>
</Content>
<Content style={{ marginTop: '0px', overflow: 'hidden', height: 'calc(100% - 200px)' }}>
<p style={{ marginLeft: '16px', position: 'absolute', top: '60px' }}>总体运行情况</p>
<div id="mainLayout" className={styles.App}>
<div
style={{
height: 'calc(100vh - 200px)',
width: 'calc(100vw - 20px)',
background: '#ededed',
padding: '20px',
boxSizing: 'border-box',
}}
ref={divRef}
>
<div
style={{
position: 'relative',
width: '100%',
height: '100%',
}}
>
<div
style={{
position: 'absolute',
top: 0,
bottom: 0,
left: 0,
right: 0,
display: 'flex',
justifyContent:
width / height > window.innerWidth / window.innerHeight ? 'center' : 'center',
alignItems:
width / height < window.innerWidth / window.innerHeight ? 'center' : 'center',
}}
>
<Screen width={widthview} height={heightview}></Screen>
</div>
</div>
</div>
</div>
</Content>
</Layout>
</>
);
};
export default Apps;
indes.less
.header {
position: fixed;
top: 0;
width: 100%;
}
.xian {
width: 1px;
height: 12px;
margin-left: 16px;
border-right: 1px solid rgb(255, 255, 255);
}
.btn {
width: 42px;
margin-left: 15px;
background-color: #3b4460;
border: none;
}
.title {
position: absolute;
bottom: 50%;
left: 50%;
margin-bottom: -32px;
margin-left: -50px;
}
.viewsize {
position: absolute;
bottom: 50%;
left: 50%;
margin-bottom: -16px;
margin-left: -141px;
}
.sizeinput {
width: 60px;
height: 26px;
text-align: center;
background: #1c1f2e;
border: 1px solid rgba(255, 255, 255, 0.24);
border-radius: 2px;
}
.capture {
width: 100%;
height: calc(100% - 22px);
}
.pageView {
width: 100%;
height: 100%;
padding: 50px;
}
.container {
position: relative;
width: 100%;
height: 100%;
}
.content {
position: absolute;
top: 50%;
left: 50%;
max-width: 100%;
max-height: 100%;
object-fit: contain;
transform: translate(-50%, -50%);
}
.App {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
@media (max-width: 768px) {
.App {
height: 100%;
}
}