fix(style): image size cache'

This commit is contained in:
jialin
2024-12-02 22:15:43 +08:00
parent 50c740d219
commit b1d13f5a71
15 changed files with 195 additions and 79 deletions
@@ -11,3 +11,9 @@
image-rendering: crisp-edges;
}
}
.scroller-wrapper {
width: 100%;
height: 100%;
overflow: hidden;
}
+27 -33
View File
@@ -1,5 +1,5 @@
import useResizeObserver from '@/components/logs-viewer/use-size';
import React, { useEffect } from 'react';
import React, { useEffect, useState } from 'react';
import './index.less';
interface AudioAnimationProps {
@@ -7,6 +7,7 @@ interface AudioAnimationProps {
height: number;
scaleFactor?: number;
maxBarCount?: number;
fixedHeight?: boolean;
analyserData: {
data: Uint8Array;
analyser: any;
@@ -17,20 +18,22 @@ const AudioAnimation: React.FC<AudioAnimationProps> = (props) => {
const {
scaleFactor = 1.2,
maxBarCount = 128,
fixedHeight = true,
analyserData,
width,
height
width: initialWidth,
height: initialHeight
} = props;
const canvasRef = React.useRef<HTMLCanvasElement>(null);
const animationId = React.useRef<number>(0);
const isScaled = React.useRef<boolean>(false);
const oscillationOffset = React.useRef(0);
const direction = React.useRef(1);
// const [width, setWidth] = useState(props.width);
// const [height, setHeight] = useState(props.height);
const scrollerRef = React.useRef<HTMLDivElement>(null);
const [width, setWidth] = useState(initialWidth);
const [height, setHeight] = useState(initialHeight);
const containerRef = React.useRef<any>(null);
const size = useResizeObserver(containerRef);
const size = useResizeObserver(scrollerRef);
const calculateJitter = (
i: number,
@@ -128,26 +131,14 @@ const AudioAnimation: React.FC<AudioAnimationProps> = (props) => {
draw(performance.now());
};
// const handleResizeThrottle = React.useCallback(
// throttle(() => {
// console.log('size:', size);
// if (size.width && size.width !== width) {
// setWidth(size.width);
// }
// if (size.height && size.height !== height) {
// setHeight(size.height);
// }
// }, 100),
// [size, width, height]
// );
// useEffect(() => {
// handleResizeThrottle();
// window.addEventListener('resize', handleResizeThrottle);
// return () => {
// handleResizeThrottle.cancel();
// };
// }, [size, width, height]);
React.useEffect(() => {
if (size) {
setWidth(size?.width || 0);
if (!fixedHeight) {
setHeight(size?.height || 0);
}
}
}, [size]);
useEffect(() => {
if (!canvasRef.current) return;
@@ -175,14 +166,17 @@ const AudioAnimation: React.FC<AudioAnimationProps> = (props) => {
return (
<div
ref={containerRef}
className="canvas-wrap"
style={{
width: '100%',
height: height
}}
className="scroller-wrapper"
ref={scrollerRef}
style={{ width: '100%', height: '100%' }}
>
<canvas ref={canvasRef} style={{ width, height }}></canvas>
<div
ref={containerRef}
className="canvas-wrap"
style={{ width: '100%', height: '100%' }}
>
<canvas ref={canvasRef} style={{ display: 'block' }}></canvas>
</div>
</div>
);
};
+14 -18
View File
@@ -3,7 +3,7 @@ import { Progress } from 'antd';
import classNames from 'classnames';
import * as Vibrant from 'node-vibrant';
import ResizeObserver from 'rc-resize-observer';
import React from 'react';
import React, { useCallback } from 'react';
import AutoImage from './index';
import './single-image.less';
@@ -20,6 +20,7 @@ interface SingleImageProps {
onDelete: (uid: number) => void;
autoBgColor?: boolean;
editable?: boolean;
style?: React.CSSProperties;
}
const SingleImage: React.FC<SingleImageProps> = (props) => {
@@ -35,6 +36,7 @@ const SingleImage: React.FC<SingleImageProps> = (props) => {
maxHeight,
maxWidth,
dataUrl,
style,
autoBgColor
} = props;
@@ -49,36 +51,29 @@ const SingleImage: React.FC<SingleImageProps> = (props) => {
return loading ? { width: '100%', height: '100%' } : {};
}, [loading, imgSize]);
const handleResize = React.useCallback(
async (size: { width: number; height: number }) => {
if (!autoSize || !dataUrl) return;
const handleResize = useCallback(
(size: { width: number; height: number }) => {
if (!autoSize) return;
const { width: containerWidth, height: containerHeight } = size;
const { width: originalWidth, height: originalHeight } = props;
console.log('size:', size, originalWidth, originalHeight);
if (!originalWidth || !originalHeight) return;
const imageAspectRatio = originalWidth / originalHeight;
const containerAspectRatio = containerWidth / containerHeight;
const widthRatio = containerWidth / originalWidth;
const heightRatio = containerHeight / originalHeight;
let newWidth, newHeight;
const scale = Math.min(widthRatio, heightRatio, 1);
const newWidth = originalWidth * scale;
const newHeight = originalHeight * scale;
if (containerAspectRatio > imageAspectRatio) {
newHeight = containerHeight;
newWidth = containerHeight * imageAspectRatio;
} else {
newWidth = containerWidth;
newHeight = containerWidth / imageAspectRatio;
}
console.log('size++++++++=', size, newWidth, newHeight);
setImgSize({
width: newWidth,
height: newHeight
});
},
[autoSize, dataUrl, props]
[autoSize, props.width, props.height]
);
const handleOnLoad = React.useCallback(async () => {
@@ -129,6 +124,7 @@ const SingleImage: React.FC<SingleImageProps> = (props) => {
return (
<ResizeObserver onResize={handleResize}>
<div
style={{ ...style }}
key={uid}
className={classNames('single-image', {
'auto-bg-color': autoBgColor,
+15 -2
View File
@@ -106,6 +106,12 @@ const AudioPlayer: React.FC<
}
};
const seekTo = (value: number) => {
if (wavesurfer.current) {
wavesurfer.current.seekTo(value);
}
};
const duration = () => {
if (wavesurfer.current) {
return wavesurfer.current.getDuration();
@@ -123,7 +129,8 @@ const AudioPlayer: React.FC<
return {
play,
pause,
duration
duration,
seekTo
};
});
@@ -135,7 +142,13 @@ const AudioPlayer: React.FC<
destroyWavesurfer();
};
}, [audioUrl, container.current]);
return <div ref={container} className="audio-container"></div>;
return (
<div
ref={container}
className="audio-container"
style={{ display: 'none' }}
></div>
);
});
export default React.memo(AudioPlayer);
+34 -12
View File
@@ -1,3 +1,4 @@
import AudioAnimation from '@/components/audio-animation';
import useResizeObserver from '@/components/logs-viewer/use-size';
import {
DownloadOutlined,
@@ -5,12 +6,13 @@ import {
PlayCircleOutlined
} from '@ant-design/icons';
import { useIntl } from '@umijs/max';
import { Button, Tooltip } from 'antd';
import { Button, Slider, Tooltip } from 'antd';
import dayjs from 'dayjs';
import _ from 'lodash';
import _, { throttle } from 'lodash';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import AudioPlayer from './audio-player';
import './styles/index.less';
import './styles/slider-progress.less';
const audioFormat = {
'audio/mpeg': 'mp3',
@@ -72,10 +74,18 @@ const SpeechItem: React.FC<SpeechContentProps> = (props) => {
setIsPlay(false);
}, []);
const handleOnAudioprocess = useCallback((current: number) => {
setCurrentTime(() => current);
console.log('current:', current, duration);
}, []);
const throttleUpdateCurrentTime = throttle((current: number) => {
setCurrentTime(current);
}, 100);
const handleOnAudioprocess = useCallback(
(current: number) => {
console.log('current:', current);
// setCurrentTime(() => current);
throttleUpdateCurrentTime(current);
},
[throttleUpdateCurrentTime]
);
const handleReay = useCallback((duration: number) => {
setIsPlay(props.autoplay);
@@ -87,13 +97,17 @@ const SpeechItem: React.FC<SpeechContentProps> = (props) => {
}, []);
const handleAnimationResize = useCallback((size: any) => {
console.log('size:=======', size);
setAnimationSize({
width: size.width,
height: size.height
});
}, []);
const handleSliderChange = (value: number) => {
ref.current?.seekTo(value);
setCurrentTime(value);
};
useEffect(() => {
console.log('width:', size);
}, [size]);
@@ -112,7 +126,6 @@ const SpeechItem: React.FC<SpeechContentProps> = (props) => {
return (
<div>
<div className="speech-item">
<div style={{}}></div>
<div
className="wrapper"
style={{ height: 82, width: '100%' }}
@@ -128,22 +141,31 @@ const SpeechItem: React.FC<SpeechContentProps> = (props) => {
onAudioprocess={handleOnAudioprocess}
ref={ref}
></AudioPlayer>
{/* {!isPlay && (
{isPlay && (
<AudioAnimation
maxBarCount={180}
fixedHeight={true}
height={82}
width={800}
analyserData={audioChunks}
></AudioAnimation>
)} */}
)}
</div>
</div>
{/* <Slider value={currentTime} max={duration} step={0.01}></Slider> */}
<Slider
className="slider-progress"
value={currentTime}
max={duration}
step={0.01}
onChange={handleSliderChange}
></Slider>
<div className="speech-actions">
<span className="tags">
<span className="item">{props.format}</span>
</span>
<span className="duration">{_.round(duration, 2)}</span>
<span className="duration">
{_.round(currentTime, 2) || _.round(duration, 2)}
</span>
<div className="actions">
<Tooltip
title={
@@ -69,6 +69,12 @@
}
}
.duration {
display: flex;
justify-content: center;
width: 100px;
}
.tags {
display: flex;
justify-content: flex-start;
@@ -0,0 +1,21 @@
.slider-progress {
&:hover {
.ant-slider-track {
background-color: var(--ant-blue-5);
}
}
.ant-slider-rail {
border-radius: var(--border-radius-base);
height: 2px;
}
.ant-slider-track {
background-color: var(--ant-blue-5);
height: 2px;
}
.ant-slider-handle {
display: none;
}
}