weex-nuke
Version:
基于 Rax 、Weex 的高性能组件体系 ~~
151 lines (139 loc) • 3.43 kB
JSX
/* @jsx createElement */
;
import { Component, createElement, PropTypes } from 'rax';
const isWeb =
typeof navigator === 'object' &&
(navigator.appCodeName === 'Mozilla' || navigator.product === 'Gecko');
const WIDTH_ORIGINAL = 1;
const HEIGHT_ORIGINAL = 1;
/**
* Image
* @description 图片
*/
class Image extends Component {
constructor(props) {
super(props);
this.state = {
width: WIDTH_ORIGINAL,
height: HEIGHT_ORIGINAL,
};
this.load = this.load.bind(this);
}
convertToRem(num) {
let pxWidth;
if (isWeb) {
pxWidth = document.documentElement.clientWidth * devicePixelRatio;
} else {
pxWidth = WXEnvironment.deviceWidth;
}
return Math.round(num * 750 / pxWidth);
}
load(e) {
let width;
let height;
if (!isWeb) {
if (e.size && e.size.naturalWidth > 0 && e.size.naturalHeight > 0) {
width = this.convertToRem(e.size.naturalWidth);
height = this.convertToRem(e.size.naturalHeight);
}
} else if (e.target) {
width = this.convertToRem(e.target.naturalWidth);
height = this.convertToRem(e.target.naturalHeight);
e.size = {
naturalWidth: width,
naturalHeight: height,
};
}
if (this.props.autoFit && width && height) {
this.setState({
width,
height,
});
}
this.props.onLoad && this.props.onLoad(e);
}
render() {
const {
style,
autoFit,
src,
source = {},
resizeMode,
onLoad,
onPress,
onClick,
...others
} = this.props;
const {
uri,
width: sourceWidth = WIDTH_ORIGINAL,
height: sourceHeight = HEIGHT_ORIGINAL,
} = source;
if (!src && !uri) {
return null;
}
let ImageElement;
if (isWeb) {
ImageElement = 'img';
} else {
ImageElement = 'image';
}
/**
* compatible with source props
*/
const nativeProps = {
src: src || uri,
quality: 'original',
style: {
width: autoFit ? this.state.width : sourceWidth,
height: autoFit ? this.state.height : sourceHeight,
...style,
},
onLoad: this.load,
...others,
};
if (onPress || onClick) {
nativeProps.onClick = onPress || onClick;
}
/**
* if flex is defined, delete width 1, height 1
*/
if (nativeProps.style.flex) {
if (nativeProps.style.width === WIDTH_ORIGINAL) {
delete nativeProps.style.width;
}
if (nativeProps.style.height === HEIGHT_ORIGINAL) {
delete nativeProps.style.height;
}
}
// for cover and contain
const propsResizeMode = resizeMode || nativeProps.style.resizeMode;
if (propsResizeMode) {
if (isWeb) {
delete nativeProps.style.flex;
nativeProps.style.width = nativeProps.style.width || '100%';
nativeProps.style.height = nativeProps.style.height || '100%';
nativeProps.style.objectFit = propsResizeMode;
} else {
nativeProps.resize = propsResizeMode;
nativeProps.style.resizeMode = propsResizeMode;
}
}
return <ImageElement {...nativeProps} />;
}
}
Image.propTypes = {
/**
* 资源地址 source url
*/
src: PropTypes.string,
/**
* style 样式
*/
style: PropTypes.object,
};
Image.defaultProps = {
style: {},
autoFit: false,
};
export default Image;