zoom calc based in flash
This commit is contained in:
parent
0ed7c45ec0
commit
25834dd4f8
@ -1,7 +1,9 @@
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import mapToAcl from '/imports/startup/mapToAcl';
|
||||
import switchSlide from './methods/switchSlide';
|
||||
import zoomSlide from './methods/zoomSlide';
|
||||
|
||||
Meteor.methods(mapToAcl(['methods.switchSlide'], {
|
||||
Meteor.methods(mapToAcl(['methods.switchSlide', 'methods.zoomSlide'], {
|
||||
switchSlide,
|
||||
zoomSlide,
|
||||
}));
|
||||
|
@ -148,7 +148,8 @@ export default class PresentationArea extends Component {
|
||||
viewBoxHeight,
|
||||
imageUri,
|
||||
} = slideObj.calculatedData;
|
||||
|
||||
console.log(x, y);
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
@ -229,9 +230,14 @@ export default class PresentationArea extends Component {
|
||||
|
||||
return (
|
||||
<PresentationOverlayContainer
|
||||
podId={this.props.podId}
|
||||
currentSlideNum={this.props.currentSlide.num}
|
||||
presentationId={this.props.currentSlide.presentationId}
|
||||
slide={slideObj}
|
||||
whiteboardId={slideObj.id}
|
||||
slideWidth={width}
|
||||
slideHeight={height}
|
||||
adjustedSizes={adjustedSizes}
|
||||
getSvgRef={this.getSvgRef}
|
||||
>
|
||||
<WhiteboardOverlayContainer
|
||||
@ -242,7 +248,7 @@ export default class PresentationArea extends Component {
|
||||
viewBoxX={x}
|
||||
viewBoxY={y}
|
||||
viewBoxWidth={viewBoxWidth}
|
||||
viewBoxHeight={viewBoxHeight}
|
||||
viewBoxHeight={viewBoxHeight}
|
||||
physicalSlideWidth={(adjustedSizes.width / slideObj.widthRatio) * 100}
|
||||
physicalSlideHeight={(adjustedSizes.height / slideObj.heightRatio) * 100}
|
||||
/>
|
||||
|
@ -2,6 +2,8 @@ import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const CURSOR_INTERVAL = 16;
|
||||
const MYSTERY_NUM = 2;
|
||||
const HUNDRED_PERCENT = 100;
|
||||
|
||||
export default class PresentationOverlay extends Component {
|
||||
constructor(props) {
|
||||
@ -17,6 +19,9 @@ export default class PresentationOverlay extends Component {
|
||||
|
||||
// id of the setInterval()
|
||||
this.intervalId = 0;
|
||||
this.state = {
|
||||
zoomValue: 100,
|
||||
};
|
||||
|
||||
// Mobile Firefox has a bug where e.preventDefault on touchstart doesn't prevent
|
||||
// onmousedown from triggering right after. Thus we have to track it manually.
|
||||
@ -35,6 +40,7 @@ export default class PresentationOverlay extends Component {
|
||||
this.mouseOutHandler = this.mouseOutHandler.bind(this);
|
||||
this.getTransformedSvgPoint = this.getTransformedSvgPoint.bind(this);
|
||||
this.svgCoordinateToPercentages = this.svgCoordinateToPercentages.bind(this);
|
||||
this.mouseZoomHandler = this.mouseZoomHandler.bind(this);
|
||||
}
|
||||
// transforms the coordinate from window coordinate system
|
||||
// to the main svg coordinate system
|
||||
@ -46,6 +52,7 @@ export default class PresentationOverlay extends Component {
|
||||
|
||||
// transform a screen point to svg point
|
||||
const CTM = svgObject.getScreenCTM();
|
||||
|
||||
return screenPoint.matrixTransform(CTM.inverse());
|
||||
}
|
||||
|
||||
@ -56,6 +63,7 @@ export default class PresentationOverlay extends Component {
|
||||
const { currentClientX, currentClientY } = this;
|
||||
// retrieving a transformed coordinate
|
||||
let transformedSvgPoint = this.getTransformedSvgPoint(currentClientX, currentClientY);
|
||||
|
||||
// determining the cursor's coordinates as percentages from the slide's width/height
|
||||
transformedSvgPoint = this.svgCoordinateToPercentages(transformedSvgPoint);
|
||||
// updating last sent raw coordinates
|
||||
@ -82,6 +90,78 @@ export default class PresentationOverlay extends Component {
|
||||
}
|
||||
|
||||
|
||||
mouseZoomHandler(e) {
|
||||
// calc for sliderZoom
|
||||
// zoomSlide(zoom, (((slideLoader.content.width/2)*SlideViewModel.HUNDRED_PERCENT)/zoom), (((slideLoader.content.height/2)*SlideViewModel.HUNDRED_PERCENT)/zoom));
|
||||
const {
|
||||
zoomSlide,
|
||||
podId,
|
||||
currentSlideNum,
|
||||
slideWidth,
|
||||
slideHeight,
|
||||
adjustedSizes
|
||||
} = this.props;
|
||||
|
||||
const mouseX = e.clientX;
|
||||
const mouseY = e.clientY;
|
||||
|
||||
// console.error('event', x,y);
|
||||
const _pageOrigW = slideWidth;
|
||||
const _pageOrigH = slideHeight;
|
||||
const viewportW = adjustedSizes.width;
|
||||
const viewportH = adjustedSizes.height;
|
||||
|
||||
let _calcPageW = viewportW/(100/HUNDRED_PERCENT);
|
||||
let _calcPageH = viewportH/(100/HUNDRED_PERCENT);
|
||||
let _calcPageX = (0/HUNDRED_PERCENT) * _calcPageW;
|
||||
let _calcPageY = (0/HUNDRED_PERCENT) * _calcPageH;
|
||||
|
||||
const svgPosition = this.getTransformedSvgPoint(mouseX, mouseY);
|
||||
const svgPercentage = this.svgCoordinateToPercentages(svgPosition);
|
||||
|
||||
// console.error('svgPosition', svgPosition.x, svgPosition.y);
|
||||
// console.error('svgPercentage', svgPercentage.x, svgPercentage.y);
|
||||
|
||||
const relXcoordInPage = (svgPercentage.x) / 100;
|
||||
const relYcoordInPage = (svgPercentage.y) / 100;
|
||||
|
||||
const zoomValue = this.state.zoomValue + 5;
|
||||
|
||||
console.error(zoomValue);
|
||||
console.error(mouseX, mouseY);
|
||||
|
||||
_calcPageW = viewportW * zoomValue / HUNDRED_PERCENT;
|
||||
_calcPageH = (_calcPageW / _pageOrigW) * _pageOrigH;
|
||||
|
||||
console.error(_calcPageW, _calcPageH);
|
||||
|
||||
const absXcoordInPage = relXcoordInPage * _calcPageW;
|
||||
const absYcoordInPage = relYcoordInPage * _calcPageH;
|
||||
|
||||
console.error(mouseX, mouseY);
|
||||
console.error(svgPosition.x, svgPosition.y);
|
||||
console.error(relXcoordInPage, relYcoordInPage);
|
||||
console.error(absXcoordInPage, absYcoordInPage);
|
||||
|
||||
_calcPageX = (absXcoordInPage - mouseX) / MYSTERY_NUM;
|
||||
_calcPageY = (absYcoordInPage - mouseY) / MYSTERY_NUM;
|
||||
|
||||
const offsetX = (_calcPageX * 100) / _calcPageW;
|
||||
const offsetY = (_calcPageX * 100) / _calcPageW;
|
||||
console.error(`(${_calcPageX} * 100) / ${_calcPageW}`, offsetX);
|
||||
console.error(`(${_calcPageY} * 100) / ${_calcPageH}`, offsetY);
|
||||
|
||||
this.setState(
|
||||
{ zoomValue },
|
||||
() => zoomSlide(currentSlideNum, podId,
|
||||
(this.state.zoomValue - 100) - 100,
|
||||
offsetX,
|
||||
offsetY
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
handleTouchStart(event) {
|
||||
// to prevent default behavior (scrolling) on devices (in Safari), when you draw a text box
|
||||
event.preventDefault();
|
||||
@ -201,6 +281,8 @@ export default class PresentationOverlay extends Component {
|
||||
onMouseOut={this.mouseOutHandler}
|
||||
onMouseEnter={this.mouseEnterHandler}
|
||||
onMouseMove={this.mouseMoveHandler}
|
||||
onWheel={this.mouseZoomHandler}
|
||||
onBlur={() => {}}
|
||||
style={{ width: '100%', height: '100%', touchAction: 'none' }}
|
||||
>
|
||||
{this.props.children}
|
||||
|
@ -2,6 +2,7 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withTracker } from 'meteor/react-meteor-data';
|
||||
import PresentationOverlayService from './service';
|
||||
import PresentationToolbarService from '../presentation-toolbar/service';
|
||||
import PresentationOverlay from './component';
|
||||
|
||||
const PresentationOverlayContainer = ({ children, ...rest }) => (
|
||||
@ -10,8 +11,12 @@ const PresentationOverlayContainer = ({ children, ...rest }) => (
|
||||
</PresentationOverlay>
|
||||
);
|
||||
|
||||
export default withTracker(() => ({
|
||||
export default withTracker(({ podId, currentSlideNum, slide }) => ({
|
||||
slide,
|
||||
podId,
|
||||
currentSlideNum,
|
||||
updateCursor: PresentationOverlayService.updateCursor,
|
||||
zoomSlide: PresentationToolbarService.zoomSlide,
|
||||
}))(PresentationOverlayContainer);
|
||||
|
||||
PresentationOverlayContainer.propTypes = {
|
||||
|
@ -125,6 +125,7 @@ class PresentationToolbar extends Component {
|
||||
this.state = { sliderValue: 100 };
|
||||
this.handleValuesChange = this.handleValuesChange.bind(this);
|
||||
this.handleSkipToSlideChange = this.handleSkipToSlideChange.bind(this);
|
||||
this.handleZoom = this.handleZoom.bind(this);
|
||||
}
|
||||
|
||||
handleSkipToSlideChange(event) {
|
||||
@ -133,7 +134,10 @@ class PresentationToolbar extends Component {
|
||||
}
|
||||
|
||||
handleValuesChange(event) {
|
||||
this.setState({ sliderValue: event.target.value });
|
||||
this.setState({ sliderValue: event.target.value }, () => this.handleZoom(this.state.sliderValue));
|
||||
}
|
||||
handleZoom(value) {
|
||||
this.props.actions.zoomSlideHandler(value);
|
||||
}
|
||||
|
||||
fitToWidthClickHandler() {
|
||||
@ -216,6 +220,25 @@ class PresentationToolbar extends Component {
|
||||
hideLabel
|
||||
className={styles.skipSlide}
|
||||
/>
|
||||
<div className={styles.zoomMinMax}> 100% </div>
|
||||
<input
|
||||
role="slider"
|
||||
aria-labelledby="zoomLabel"
|
||||
aria-describedby="zoomDesc"
|
||||
aria-valuemax="100"
|
||||
aria-valuemin="25"
|
||||
aria-valuenow={this.state.sliderValue}
|
||||
value={this.state.sliderValue}
|
||||
step="5"
|
||||
type="range"
|
||||
min="25"
|
||||
max="100"
|
||||
onChange={this.handleValuesChange}
|
||||
onInput={this.handleValuesChange}
|
||||
className={styles.zoomSlider}
|
||||
/>
|
||||
<div className={styles.zoomMinMax}> 400% </div>
|
||||
|
||||
|
||||
{/* Fit to width button
|
||||
<Button
|
||||
|
@ -45,6 +45,8 @@ export default withTracker((params) => {
|
||||
PresentationToolbarService.previousSlide(params.currentSlideNum, podId),
|
||||
skipToSlideHandler: requestedSlideNum =>
|
||||
PresentationToolbarService.skipToSlide(requestedSlideNum, podId),
|
||||
zoomSlideHandler: value =>
|
||||
PresentationToolbarService.zoomSlide(params.currentSlideNum, podId, value),
|
||||
},
|
||||
};
|
||||
})(PresentationToolbarContainer);
|
||||
|
@ -40,6 +40,11 @@ const nextSlide = (currentSlideNum, numberOfSlides, podId) => {
|
||||
}
|
||||
};
|
||||
|
||||
const zoomSlide = (currentSlideNum, podId, value, xOffset, yOffset) => {
|
||||
makeCall('zoomSlide', currentSlideNum, podId, value, xOffset, yOffset);
|
||||
};
|
||||
|
||||
|
||||
const skipToSlide = (requestedSlideNum, podId) => {
|
||||
makeCall('switchSlide', requestedSlideNum, podId);
|
||||
};
|
||||
@ -49,4 +54,5 @@ export default {
|
||||
nextSlide,
|
||||
previousSlide,
|
||||
skipToSlide,
|
||||
zoomSlide,
|
||||
};
|
||||
|
@ -88,6 +88,7 @@ $controls-background: $color-white !default;
|
||||
|
||||
.zoomSlider {
|
||||
width: 50%;
|
||||
direction: rtl;
|
||||
}
|
||||
|
||||
.zoomMinMax {
|
||||
|
@ -140,7 +140,8 @@
|
||||
"moveCursor",
|
||||
"sendAnnotation",
|
||||
"removePresentation",
|
||||
"setPresentation"
|
||||
"setPresentation",
|
||||
"zoomSlide"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user