zoom calc based in flash

This commit is contained in:
Tainan Felipe 2018-08-13 16:29:38 -03:00
parent 0ed7c45ec0
commit 25834dd4f8
9 changed files with 134 additions and 6 deletions

View File

@ -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,
}));

View File

@ -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}
/>

View File

@ -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}

View File

@ -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 = {

View File

@ -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

View File

@ -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);

View File

@ -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,
};

View File

@ -88,6 +88,7 @@ $controls-background: $color-white !default;
.zoomSlider {
width: 50%;
direction: rtl;
}
.zoomMinMax {

View File

@ -140,7 +140,8 @@
"moveCursor",
"sendAnnotation",
"removePresentation",
"setPresentation"
"setPresentation",
"zoomSlide"
]
}
},