import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { TransitionGroup, CSSTransition } from 'react-transition-group'; import WhiteboardOverlayContainer from '/imports/ui/components/whiteboard/whiteboard-overlay/container'; import WhiteboardToolbarContainer from '/imports/ui/components/whiteboard/whiteboard-toolbar/container'; import PollingContainer from '/imports/ui/components/polling/container'; import CursorWrapperContainer from './cursor/cursor-wrapper-container/container'; import AnnotationGroupContainer from '../whiteboard/annotation-group/container'; import PresentationToolbarContainer from './presentation-toolbar/container'; import PresentationOverlayContainer from './presentation-overlay/container'; import Slide from './slide/component'; import { styles } from './styles.scss'; export default class PresentationArea extends Component { constructor() { super(); this.state = { presentationWidth: 0, presentationHeight: 0, showSlide: false, }; this.getSvgRef = this.getSvgRef.bind(this); } componentDidMount() { // adding an event listener to scale the whiteboard on 'resize' events sent by chat/userlist etc window.addEventListener('resize', () => { setTimeout(this.handleResize.bind(this), 0); }); this.getInitialPresentationSizes(); } componentWillUnmount() { window.removeEventListener('resize', () => { setTimeout(this.handleResize.bind(this), 0); }); } // returns a ref to the svg element, which is required by a WhiteboardOverlay // to transform screen coordinates to svg coordinate system getSvgRef() { return this.svggroup; } getPresentationSizesAvailable() { const { refPresentationArea, refWhiteboardArea } = this; const presentationSizes = {}; if (refPresentationArea && refWhiteboardArea) { // By default presentation sizes are equal to the sizes of the refPresentationArea // direct parent of the svg wrapper let { clientWidth, clientHeight } = refPresentationArea; // if a user is a presenter - this means there is a whiteboard toolbar on the right // and we have to get the width/height of the refWhiteboardArea // (inner hidden div with absolute position) if (this.props.userIsPresenter || this.props.multiUser) { ({ clientWidth, clientHeight } = refWhiteboardArea); } presentationSizes.presentationHeight = clientHeight; presentationSizes.presentationWidth = clientWidth; } return presentationSizes; } getInitialPresentationSizes() { // determining the presentationWidth and presentationHeight (available space for the svg) // on the initial load const presentationSizes = this.getPresentationSizesAvailable(); if (Object.keys(presentationSizes).length > 0) { // setting the state of the available space for the svg // and set the showSlide to true to start rendering the slide this.setState({ presentationHeight: presentationSizes.presentationHeight, presentationWidth: presentationSizes.presentationWidth, showSlide: true, }); } } handleResize() { const presentationSizes = this.getPresentationSizesAvailable(); if (Object.keys(presentationSizes).length > 0) { // updating the size of the space available for the slide this.setState(presentationSizes); } } calculateSize() { const originalWidth = this.props.currentSlide.calculatedData.width; const originalHeight = this.props.currentSlide.calculatedData.height; const { presentationHeight, presentationWidth } = this.state; let adjustedWidth; let adjustedHeight; // Slide has a portrait orientation if (originalWidth <= originalHeight) { adjustedWidth = (presentationHeight * originalWidth) / originalHeight; if (presentationWidth < adjustedWidth) { adjustedHeight = (presentationHeight * presentationWidth) / adjustedWidth; adjustedWidth = presentationWidth; } else { adjustedHeight = presentationHeight; } // Slide has a landscape orientation } else { adjustedHeight = (presentationWidth * originalHeight) / originalWidth; if (presentationHeight < adjustedHeight) { adjustedWidth = (presentationWidth * presentationHeight) / adjustedHeight; adjustedHeight = presentationHeight; } else { adjustedWidth = presentationWidth; } } return { width: adjustedWidth, height: adjustedHeight, }; } // renders the whole presentation area renderPresentationArea() { // sometimes tomcat publishes the slide url, but the actual file is not accessible (why?) if (!this.props.currentSlide || !this.props.currentSlide.calculatedData) { return null; } // to control the size of the svg wrapper manually // and adjust cursor's thickness, so that svg didn't scale it automatically const adjustedSizes = this.calculateSize(); // a reference to the slide object const slideObj = this.props.currentSlide; // retrieving the pre-calculated data from the slide object const { x, y, width, height, viewBoxWidth, viewBoxHeight, imageUri, } = slideObj.calculatedData; return (