mirror of
https://github.com/ant-design/ant-design.git
synced 2024-11-27 20:49:53 +08:00
recalculate width while resize (#4676)
+ close #4645 + throttleByAnimationFrameDecorator as a function decorator
This commit is contained in:
parent
879bc9320c
commit
5cd111d486
@ -1,3 +1,14 @@
|
||||
function requestAnimationFramePolyfill() {
|
||||
let lastTime = 0;
|
||||
return function(callback) {
|
||||
const currTime = new Date().getTime();
|
||||
const timeToCall = Math.max(0, 16 - (currTime - lastTime));
|
||||
const id = window.setTimeout(function() { callback(currTime + timeToCall); }, timeToCall);
|
||||
lastTime = currTime + timeToCall;
|
||||
return id;
|
||||
};
|
||||
}
|
||||
|
||||
export default function getRequestAnimationFrame() {
|
||||
if (typeof window === 'undefined') {
|
||||
return () => {};
|
||||
@ -8,5 +19,5 @@ export default function getRequestAnimationFrame() {
|
||||
const prefix = ['moz', 'ms', 'webkit'].filter(key => `${key}RequestAnimationFrame` in window)[0];
|
||||
return prefix
|
||||
? window[`${prefix}RequestAnimationFrame`]
|
||||
: callback => setTimeout(callback, 1000 / 60);
|
||||
: requestAnimationFramePolyfill();
|
||||
}
|
||||
|
42
components/_util/throttleByAnimationFrame.tsx
Normal file
42
components/_util/throttleByAnimationFrame.tsx
Normal file
@ -0,0 +1,42 @@
|
||||
import getRequestAnimationFrame from '../_util/getRequestAnimationFrame';
|
||||
|
||||
const reqAnimFrame = getRequestAnimationFrame();
|
||||
|
||||
export default function throttleByAnimationFrame(fn, threshhold = 250) {
|
||||
let last;
|
||||
return function() {
|
||||
const self = this;
|
||||
const args = arguments;
|
||||
reqAnimFrame(timestamp => {
|
||||
if (!last || timestamp - last > threshhold) {
|
||||
last = timestamp;
|
||||
fn.apply(self, args);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export function throttleByAnimationFrameDecorator(threshhold = 250) {
|
||||
return function(target, key, descriptor) {
|
||||
let fn = descriptor.value;
|
||||
let definingProperty = false;
|
||||
return {
|
||||
configurable: true,
|
||||
get() {
|
||||
if (definingProperty || this === target.prototype || this.hasOwnProperty(key)) {
|
||||
return fn;
|
||||
}
|
||||
|
||||
let boundFn = throttleByAnimationFrame(fn.bind(this), threshhold);
|
||||
definingProperty = true;
|
||||
Object.defineProperty(this, key, {
|
||||
value: boundFn,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
});
|
||||
definingProperty = false;
|
||||
return boundFn;
|
||||
},
|
||||
};
|
||||
};
|
||||
}
|
@ -5,6 +5,7 @@ import classNames from 'classnames';
|
||||
import shallowequal from 'shallowequal';
|
||||
import omit from 'omit.js';
|
||||
import getScroll from '../_util/getScroll';
|
||||
import { throttleByAnimationFrameDecorator } from '../_util/throttleByAnimationFrame';
|
||||
|
||||
function getTargetRect(target): ClientRect {
|
||||
return target !== window ?
|
||||
@ -96,18 +97,16 @@ export default class Affix extends React.Component<AffixProps, any> {
|
||||
});
|
||||
}
|
||||
|
||||
setPlaceholderStyle(e, placeholderStyle) {
|
||||
setPlaceholderStyle(placeholderStyle) {
|
||||
const originalPlaceholderStyle = this.state.placeholderStyle;
|
||||
if (e.type === 'resize') {
|
||||
return;
|
||||
}
|
||||
if (shallowequal(placeholderStyle, originalPlaceholderStyle)) {
|
||||
return;
|
||||
}
|
||||
this.setState({ placeholderStyle });
|
||||
}
|
||||
|
||||
updatePosition = (e) => {
|
||||
@throttleByAnimationFrameDecorator(250)
|
||||
updatePosition(e) {
|
||||
let { offsetTop, offsetBottom, offset, target = getDefaultTarget } = this.props;
|
||||
const targetNode = target();
|
||||
|
||||
@ -145,7 +144,7 @@ export default class Affix extends React.Component<AffixProps, any> {
|
||||
left: targetRect.left + elemOffset.left,
|
||||
width: affixNode.offsetWidth,
|
||||
});
|
||||
this.setPlaceholderStyle(e, {
|
||||
this.setPlaceholderStyle({
|
||||
width: affixNode.offsetWidth,
|
||||
height: affixNode.offsetHeight,
|
||||
});
|
||||
@ -161,13 +160,18 @@ export default class Affix extends React.Component<AffixProps, any> {
|
||||
left: targetRect.left + elemOffset.left,
|
||||
width: affixNode.offsetWidth,
|
||||
});
|
||||
this.setPlaceholderStyle(e, {
|
||||
this.setPlaceholderStyle({
|
||||
width: affixNode.offsetWidth,
|
||||
height: affixNode.offsetHeight,
|
||||
});
|
||||
} else {
|
||||
this.setAffixStyle(e, null);
|
||||
this.setPlaceholderStyle(e, null);
|
||||
const { affixStyle } = this.state;
|
||||
if (e.type === 'resize' && affixStyle && affixStyle.position === 'fixed' && affixNode.offsetWidth) {
|
||||
this.setAffixStyle(e, {...affixStyle, width: affixNode.offsetWidth });
|
||||
} else {
|
||||
this.setAffixStyle(e, null);
|
||||
}
|
||||
this.setPlaceholderStyle(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
"strictNullChecks": true,
|
||||
"moduleResolution": "node",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"experimentalDecorators": true,
|
||||
"jsx": "preserve",
|
||||
"target": "es6"
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user