principles-ui-components
Version:
Supporting UI controller for Tizen TV web application, which developed base on React Framework.
244 lines (217 loc) • 8.54 kB
JavaScript
/**
* @author Xiuliang Li (xiuliang.li@samsung.com)
* @fileoverview This module manages Image item.
* @date 2017/06/9 (last modified date)
*
* Copyright 2017 by Samsung Electronics, Inc.,
*
* This software is the confidential and proprietary information
* of Samsung Electronics, Inc. ("Confidential Information"). You
* shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement
* you entered into with Samsung.
*/
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { is, Map, fromJS } from 'immutable'; // List and Map imparts the immutability feature to only the level-1 members of the List/Map
import ScrollText from './common/ScrollText';
import Image from './common/Image';
import TTS from './common/TTS';
import BreathMotion from './common/BreathMotion';
import PressFeedback from './common/PressFeedback';
import ProgressBar from './ProgressBar';
import { AnimationEffect, VOICE_GUIDE_DELAY } from './common/CommonDefine';
const ShadowImage = {
NORMAL: 'images/shadowbg/r_highlight_bg_focus_9patch.png',
HIGHCONTRAST: 'images/shadowbg/c_imageitem_highlight_bg_focus_9patch.png',
};
export default class ImageItem extends Component {
constructor(props) {
super(props);
// bind function
this.getBGComponent = this.getBGComponent.bind(this);
}
componentDidMount() {
}
componentWillReceiveProps(nextProps) {
}
shouldComponentUpdate(nextProps, nextState) {
return (JSON.stringify(nextProps) !== JSON.stringify(this.props));
}
componentDidUpdate(prevProps, prevState) {
}
componentWillUnmount() {
}
/**
* get Shadow Component
* @name getShadowComponent
* @method
* @memberof todo, make a component for background.
*/
getBGComponent() {
const { OSD, highContrast, focus } = this.props;
const shadowStyle = {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
borderStyle: 'solid',
margin: '-11px -6px -13px -6px',
borderWidth: '20px 14px',
borderImage: highContrast ?
`url(${ShadowImage.HIGHCONTRAST}) 20 14 fill stretch` :
`url(${ShadowImage.NORMAL}) 20 14 fill stretch`,
};
const normalStyle = {
// todo, normal bg strech
};
return (<div style={focus ? shadowStyle : normalStyle} />);
}
/**
* voice guide play
* @name playTTS
* @method
* @param
* @memberof
*/
playTTS() {
if (this.props.ttsEnable && this.props.focus) {
this.TTSnode.playTTS();
}
}
render() {
const { enlarge, highContrast, scaleFactor, ttsEnable, focus, OSD, enter, enterCB } = this.props;
const bgComponent = this.getBGComponent();
let TTSComponent = null;
if (ttsEnable) {
TTSComponent = <TTS ref={(TTSnode) => { this.TTSnode = TTSnode; }} ttsEnable={ttsEnable} ttsText={OSD.ttsText} />;
}
let idx;
let len;
const imageComponentList = [];
if (typeof OSD.image !== 'undefined') {
len = OSD.image.length;
for (idx = 0; idx < len; idx++) {
imageComponentList.push(<Image key={`image${idx}`} OSD={OSD.image[idx]} />);
}
}
const iconComponentList = [];
if (typeof OSD.icon !== 'undefined') {
len = OSD.icon.length;
for (idx = 0; idx < len; idx++) {
iconComponentList.push(<Image key={`icon${idx}`} OSD={OSD.icon[idx]} />);
}
}
const textComponentList = [];
if (typeof OSD.text !== 'undefined') {
len = OSD.text.length;
for (idx = 0; idx < len; idx++) {
textComponentList.push(<ScrollText
key={`text${idx}`}
top={OSD.text[idx].t}
left={OSD.text[idx].l}
width={OSD.text[idx].w}
height={OSD.text[idx].h}
lineHeight={`${OSD.text[idx].h}px`}
scroll={focus && !highContrast && !enlarge}// In a High Contrast || enlarge mode, do not support sliding text feature.
fontSize={enlarge ? OSD.text[idx].fontSizel : OSD.text[idx].fontSize}
fontFamily={OSD.text[idx].fontType}
textGap={OSD.text[idx].scrollGap}
textAlign={OSD.text[idx].textAlign}
verticalAlign={OSD.text[idx].verticalAlign}
color={(focus || enlarge) ? '#000000' : '#262626'}
>
{OSD.text[idx].text}
</ScrollText>);
}
}
let progressComponent = null;
if (typeof OSD.progress !== 'undefined') {
progressComponent = (<ProgressBar
ref={(progress) => { this.progress = progress; }}
top={OSD.progress.t}
left={OSD.progress.l}
progressRate={OSD.progress.rate}
bgWidth={OSD.progress.w}
bgHeight={OSD.progress.h}
highContarstValue={highContrast}
/>);
}
const layoutStyle = {
position: 'relative',
zIndex: focus ? 2 : 1,
left: OSD.layout.l,
top: OSD.layout.t,
width: OSD.layout.w,
height: OSD.layout.h,
borderRadius: '3px',
overflow: 'visible',
backgroundColor: focus ? 'hsla(0,0%,100%,1)' : 'hsla(0,0%,100%,0.5)',
transform: `scale(${focus ? scaleFactor : 1.0}) translateZ(10px)`,
transition: focus ? `all 1.1s ${AnimationEffect.Elastic}` : `all 0.3s ${AnimationEffect.Basic}`,
};
return (
<BreathMotion doBreath={focus}>
<PressFeedback start={enter} animationDoneCB={enterCB}>
<div style={layoutStyle}>
{bgComponent}
{TTSComponent}
{imageComponentList}
{iconComponentList}
{textComponentList}
{progressComponent}
</div>
</PressFeedback>
</BreathMotion>
);
}
}
ImageItem.defaultProps = {
enter: false, // enter key flag
enterCB: null, // enter key callback function
enlarge: false,
highContrast: false,
scaleFactor: 1.2,
ttsEnable: false,
};
ImageItem.propTypes = {
focus: PropTypes.bool.isRequired, // The item is focus or not
enter: PropTypes.bool, // PressFeedBack animation flag
enterCB: PropTypes.func, // Animation done callback
enlarge: PropTypes.bool, // enlarge title and SubTitle font size flag
highContrast: PropTypes.bool, // Background image, false use r_highlight_bg_focus_9patch.png ,true use c_imageitem_highlight_bg_focus_9patch.png
scaleFactor: PropTypes.number, // focus scale size.
ttsEnable: PropTypes.bool,
OSD: PropTypes.shape({ // UI content
layout: PropTypes.shape({
l: PropTypes.number,
t: PropTypes.number,
w: PropTypes.number,
h: PropTypes.number,
}),
image: PropTypes.array,
icon: PropTypes.array,
text: PropTypes.arrayOf(PropTypes.shape({
l: PropTypes.number,
t: PropTypes.number,
w: PropTypes.number,
h: PropTypes.number,
fontSize: PropTypes.number,
fontSizel: PropTypes.number,
fontType: PropTypes.string,
textAlign: PropTypes.oneOf(['left', 'center', 'right']),
verticalAlign: PropTypes.oneOf(['top', 'middle', 'bottom']),
scrollGap: PropTypes.number,
text: PropTypes.string,
})),
ttsText: PropTypes.string,
progress: PropTypes.shape({
l: PropTypes.number,
t: PropTypes.number,
w: PropTypes.number,
h: PropTypes.number,
rate: PropTypes.number,
}),
}).isRequired,
};