import React, { Component } from \'react\'
import { pages, ProductActions } from \'products-sdk\'
import Slider from \'react-slick\'
import classnames from \'classnames\';
import ShowDialogDom from \'../../components/showDialog\';
import ShowImgDom from \'../../components/showImg\';
import { connect } from \'react-redux\';
import styles from \'./index.scss\'
import * as utils from \'../../utils\'
const Loading = () => (
<div className="module-loader-wrap">
<div className="module-loader">
<div className="sk-folding-cube">
<div className="sk-cube1 sk-cube" />
<div className="sk-cube2 sk-cube" />
<div className="sk-cube4 sk-cube" />
<div className="sk-cube3 sk-cube" />
</div>
<div className="module-loader-message">初始化模块中 ...</div>
</div>
</div>
)
class Panorama extends Component {
constructor(props) {
super(props)
this.state = {
canAutoPlay: false,
factories: null,
playing: false,
showDialog: false,
showIntro: window.innerWidth > 768 ? true : false,
showGallery: false,
showhotDialog: false,
dubbing: false,
dubComplete: false,
show720: true,
currentPano: {},
hotspotId: \'\',
sliderIndex: 0,
scale: false
}
this.audioResource = process.env.PUBLIC_PATH + \'/static/music/bg.mp3\'
this.audio = new Audio(this.audioResource);
this.audio.volume = 0.3
this.audio.addEventListener(
\'ended\',
() => {
this.audio.currentTime = 0;
this.audio.play()
},
false
)
}
componentWillMount() {
const { api, match } = this.props;
const id = match.params.id;
const pano = document.createElement(\'div\');
pano.setAttribute(\'id\', \'pano\');
document.title = \'智能工厂\'
document.body.appendChild(pano);
api.get(`/catalog/categories/${id}`).then(data => {
this.setState({
factories: data.data.products
})
this.init(data.data.products)
this.audio.play().then(() => {
this.setState({
canAutoPlay: true,
playing: true
})
}).catch(err => {
this.setState({
canAutoPlay: false,
playing: false
})
})
this.audio.addEventListener(
\'ended\',
() => {
this.audio.currentTime = 0
this.audio.play();
this.setState({
canAutoPlay:true
})
},
false
)
})
}
componentDidMount() {
const { history, api } = this.props;
window.showModal = id => { //弹窗的图文信息
if (this.state.dubComplete || !this.state.dubbing) {
this.keepPause = true
} else {
this.keepPause = false
}
if (!this.state.playing) {
this.keepMusicPause = true
} else {
this.keepMusicPause = false
}
this.audio.pause()
this.pauseSound()
this.setState({
hotspotId: id,
showhotDialog: true,
playing: false,
dubbing: false,
show720: false
})
}
window.sceneTo = id => {
const parentId = \'e20c8539bc5844b1a5f1b0fe544eb553\'
window.sceneToPanoInAnotherCatagory(parentId, id)
}
window.screenToChild = id => {
const { showDialog, showhotDialog } = this.state;
if (id && (showhotDialog === false || showDialog === false)) {
history.push(`/factory/panorama/e20c8539bc5844b1a5f1b0fe544eb553/${id}`);
}
}
window.sceneToPanoInAnotherCatagory = (category, product) => {
history.push(`/factory/panorama/${category}/${product}`)
}
window.playDub = () => {
if (this.krpano) {
console.log(\'this.kepano====>>>\', this.krpano);
const xmlPath = this.krpano.get(\'network.currentxmlpath\')
const request = new XMLHttpRequest()
request.onload = this.playDub;
request.open(\'get\', xmlPath + \'files/dub.mp3\', true);
request.responseType = "arraybuffer";
request.send()
}
}
window.dubcomplete = () => {
this.setState({
dubbing: false,
dubComplete: true,
})
}
window.panoClicked = () => {
if (this.state.showGallery) {
this.setState({
showGallery: false
})
}
}
window.keepIntro = () => {
//keepIntro为xml加载完毕后调用,此时隐藏移动端的场景导航文字
if (window.innerWidth <= 768) {
this.krpano.set(\'layer[prev_text].visible\', \'false\')
this.krpano.set(\'layer[next_text].visible\', \'false\')
}
const { showIntro, currentPano } = this.state
if (showIntro && currentPano && currentPano.description) {
this.slideNext()
}
}
}
componentWillReceiveProps(nextProps, nextState) {
const { api, match } = this.props
if (nextProps.match.params.id !== match.params.id) {
api.get(`/catalog/categories/${nextProps.match.params.id}`).then(data => {
this.setState({
showDialog: false, // 通过面包屑进行场景跳转时,应该关闭上一个场景中的弹窗
showhotDialog: false,
showGallery: false,
factories: data.data.products
})
this.init(data.data.products)
})
} else if (nextProps.match.params.panoId !== match.params.panoId) {
this.setState({
showDialog: false, // 通过面包屑进行场景跳转时,应该关闭上一个场景中的弹窗
showhotDialog: false,
})
this.loadScene(nextProps.match.params.panoId)
}
return true
}
componentWillUnmount() {
if (this.krpano) removepano(\'krpanoSWFObject\')
const pano = document.getElementById(\'pano\')
document.body.removeChild(pano);
this.audio.pause()
this.pauseSound()
this.props.module.name = \'智能工厂\'
}
loadScene = id => {
this.pauseSound()
const pano = this.state.factories.filter(f => f._id === id)[0]
if (pano) {
this.krpano.call(`
loadpano(${pano.web3d.url}, null, MERGE, BLEND(0.75));
`)
this.setState({
currentPano: pano
})
}
}
customizationShareItems = (context) => {
return {
name: _.get(context, \'module.name\'),
href: window.location.href
}
}
togglePlayAndPause = (param) => {
const { playing, dubbing } = this.state;
if (param === \'play\') {
playing === false ? this.play() : this.pause()
this.setState((prevState, props) => ({
playing: !prevState.playing
}))
} else if (param === \'sound\') {
console.log(\'dubbing===>>>\',dubbing);
dubbing === false ? this.resumeSound() : this.pauseSound()
this.setState((prevState, props) => ({
dubbing: !dubbing
}))
}
}
play = () => {
this.audio.play();
this.audio.addEventListener(
\'ended\',
() => {
this.audio.currentTime = 0;
this.audio.play()
},
false
)
this.setState({ playing: false })
}
pause = () => {
this.audio.pause();
this.setState({ playing: true })
}
playDub = (event) => {
console.log(\'this.state.canAutoPlay===>>>\',!this.state.showDialog,!this.state.showhotDialog);
if (event && event.target.status == \'200\' && (this.state.showhotDialog === false && this.state.showDialog === false)) {
console.log(this.state.dubbing);
this.krpano.call(\'playsound(dub, dub.mp3, 1, dubcomplete)\');
this.setState({
dubbing: true
})
}
}
pauseSound = () => {
this.krpano.call(\'pausesound(dub)\');
this.setState({
dubbing: false
})
}
resumeSound = () => {
this.krpano.call(\'resumesound(dub)\');
this.krpano.call(\'playsound(dub, dub.mp3, 1, dubcomplete)\');
this.setState({
dubbing: true
})
}
init = (products) => {
const panoid = this.props.match.params.panoId;
_.map(products, (product, index) => {
if (product._id === panoid) {
const web3d = product[\'web3d\'];
if (web3d && web3d.type === \'web3d\' && web3d.url) {
this.initKrpano({
xml: web3d.url,
target: \'pano\',
html5: \'only\',
bgcolor: \'transparent\',
mobilescale: 1.0,
passQueryParameters: false,
initvars: {
skinPath: process.env.PUBLIC_PATH + \'/static/skin\'
}
})
}
this.setState({
currentPano: product
})
}
})
}
initKrpano = config => {
if (this.krpano) removepano(\'krpanoSWFObject\')
embedpano(config)
this.krpano = document.getElementById(\'krpanoSWFObject\');
}
closeImg = () => { //click inside the popover to enlarge the image
this.setState({
scale: false
})
}
close = () => { //close windows
if (!this.keepMusicPause) {
this.audio.play()
this.audio.addEventListener(
\'ended\',
() => {
this.audio.currentTime = 0
this.audio.play()
},
false
)
}
if (!this.keepPause) {
this.resumeSound()
}
this.setState({
showDialog: false,
showhotDialog: false,
show720: true,
playing: !this.keepMusicPause,
dubbing: !this.keepPause,
hotspotId: \'\'
})
}
toggleGallery = () => {
// 操作gallery时,Introduction将被关闭,“下一个场景”按钮需要恢复原位
this.resumeNext()
this.setState(prev => ({
showGallery: !prev.showGallery,
showIntro: false,
show720: !prev.show720
}))
}
toggleIntro = () => {
this.audio.pause()
this.pauseSound()
this.setState(prev => {
return {
showDialog: !prev.showDialog,
showhotDialog: !prev.showhotDialog,
}
})
}
resumeNext = () => {
this.krpano.set(\'layer[next_image].x\', \'0\')
this.krpano.set(\'layer[next_text].x\', \'26\')
}
handleScene = id => {
const categories = this.context.categories
const belongTo = Object.values(categories.byId).find(c => {
return c.products.some(p => p === id)
})
const categoryId = belongTo
? belongTo._id
: \'e20c8539bc5844b1a5f1b0fe544eb553\'
window.sceneToPanoInAnotherCatagory(categoryId, id)
this.setState({
showGallery: false
})
}
renderGallery = context => {
const { products, categories, currentPano, match } = context
const categoryId = match.params.id
const panoId = match.params.panoId || (currentPano && currentPano._id)
const currentProducts = categories.byId[categoryId].products
return currentProducts.map((f, i) => {
if (!f) return
const cover =
(f.cover &&
(f.cover.thumbnail ||
(f.cover.current && f.cover.current.thumbnail))) ||
\'\'
const isActive = f._id === (currentPano && currentPano._id)
if (isActive) {
this.slideGalleryToView(i + 1);
}
return (
<div
key={i}
onClick={e => {
this.handleScene(f._id)
}}
className={classnames(styles.item, isActive && styles.active)}
>
<img className={styles.cover} src={cover} alt={cover} />
<div className={styles.name}>{f.name}</div>
</div>
)
})
}
slideGalleryToView = i => {
const itemOffsetLeft = 10 + 170 * i
const halfGalleryWidth = window.innerWidth / 2
if (this.gallery) {
if (
itemOffsetLeft > halfGalleryWidth ||
itemOffsetLeft < this.gallery.scrollLeft
) {
this.gallery.scrollLeft = itemOffsetLeft - halfGalleryWidth
}
}
}
// 待重构
handleBreadcrumb = cid => {
let tmp = [];
const { currentPano } = this.state
const panoid = currentPano._id;
tmp.push({
to: `/factory/panorama/${cid}/${panoid}`,
name: `${currentPano.name}`
})
return tmp
}
renderPageContent = context => {
this.context = context;
let that = this;
const {
playing,
factories,
hotspotId,
showGallery,
showDialog,
dubbing,
showhotDialog,
currentPano,
show720
} = this.state
if (!factories) {
return <Loading />
}
const { match, categories, getCategoryItem } = context;
let hotId = \'f15b865cc35a4e80a6f3b668b0efc43a\';
let categoryHot = categories && categories.byId[hotId]; //热点的展示
if (categoryHot && !categoryHot.loaded) {
categoryHot = getCategoryItem(hotId);
}
const id = match.params.id;
const panoId = panoId || currentPano._id;
return (
<div className={classnames(styles.panoCon, window.orbitBridge && styles.orbitstyle)}
>
<div
className={classnames(
styles.bottom,
showGallery && styles.show,
showDialog || showhotDialog ? styles.pointEvent : styles.pointAuto
)}
>
{
show720 && <div className={styles.iconImg}></div>
}
<div
className={classnames(
styles.btns,
)}
>
{currentPano &&
currentPano.description && (
<div
className={classnames(styles.btn, styles.toggleIntro)}
onClick={() => this.toggleIntro()}
></div>
)}
<div
className={classnames(styles.btn, styles.toggleGallery)}
onClick={this.toggleGallery}
></div>
<div
className={classnames(styles.btn, dubbing ? styles.dubPlay : styles.dubPause)}
onClick={() => this.togglePlayAndPause(\'sound\')}
></div>
<div
className={classnames(styles.btn, playing ? styles.play : styles.pause)}
onClick={() => this.togglePlayAndPause(\'play\')}
></div>
</div>
<div className={styles.gallery} ref={el => (this.gallery = el)}>
<div className={styles.container}>
{this.renderGallery(context)}
</div>
</div>
</div>
<div
ref={
(ref) => {
if (ref) {
$(ref).find(\'img\').css({ \'width\': \'100%\', \'height\': \'auto\' });
$(ref).find(\'video\').css({ \'width\': \'100%\', \'height\': \'auto\' });
$(ref).find(\'img\').map((i, c) => {
$(c).unbind();
$(c).click(function () {
if (window.orbitBride) {
window.orbitBride.invoke({
method: \'openImges\',
params: {
items: [{ url: c.src }]
},
error: function (err) {
console.error(\'error:\', err);
},
success: function (result) {
console.log(\'result:\', result);
}
});
} else {
that.setState({
imageUrl: [c.src],
scale: true
})
}
})
})
}
}
}
>
{
(showDialog || showhotDialog) &&
<ShowDialogDom
id={showDialog === true ? panoId : showhotDialog && hotspotId}
productArray={showDialog === true ? factories : showhotDialog && categoryHot.products}
showDialog={showDialog}
close={() => { this.close() }}
/>
}
</div>
{
this.state.scale &&
<ShowImgDom scale={this.state.scale} imageUrl={this.state.imageUrl} closeImg={() => { this.closeImg() }} />
}
</div>
)
}
render() {
let addition = [];
document.title = this.state.currentPano.name;
// addition = this.handleBreadcrumb(this.props.match.params.id)
this.props.module.name = this.state.currentPano.name || \'\'
const parents = [
{ to: \'/\', name: utils.getString(\'HOME\', \'首页\') },
{ to: \'/factory/list/5c9354ef58d4bd6f02a71581\', name: \'智能工厂\' },
...addition,
]
return (
<pages.seriesInfo
{...this.props}
{...this.state}
ref={ref => {
this.page = ref
}}
hideSidebar={true}
parents={parents}
getResourceUrl={this.getResourceUrl}
renderPageContent={this.renderPageContent}
customizationShareItems={this.customizationShareItems}
title={this.state.currentPano.name}
/>
)
}
getResourceUrl = (item) => {
const { module } = this.props
const { id } = this.state;
const prefix = _.get(module, \'config.general.router.prefix\') || \'products\'
const _id = item._id;
return `${window.location.origin}/${prefix}/list/${_id}${window.location.search}`
}
}
const mapStateToProps = (state, ownProps) => {
const id = ownProps.match.params.id
return {
id
};
}
const mapDispatchToProps = (dispatch, ownProps) => {
return {
getCategoryItem: id => {
return dispatch(ProductActions.getCategoryItem(id))
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Panorama);