Skip to content

Commit 9e4b00b

Browse files
Support scaling of slide when browser resizes (#721)
* Support scaling of slide when browser resizes * Added manual scale ratio prop
1 parent cf39438 commit 9e4b00b

File tree

5 files changed

+77
-23
lines changed

5 files changed

+77
-23
lines changed

mdx-slides/index.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
11
import React from 'react';
22
import { render } from 'react-dom';
33
import { MDXProvider } from '@mdx-js/react';
4-
import Deck from '../src/components/deck';
5-
import Slide from '../src/components/slide';
4+
import { Deck, Slide } from '../src/components';
65

76
// See the webpack config to see how this import alias is made
87
import slides, { notes } from 'spectacle-user-mdx';
9-
10-
const components = {};
8+
import mdxComponentMap from '../src/utils/mdx-component-mapper';
119

1210
const MDXSlides = () => (
1311
<Deck loop>
1412
{slides.map((MDXSlide, i) => {
1513
const NotesForSlide = notes[i];
1614
return (
1715
<Slide key={`slide-${i}`} slideNum={i}>
18-
<MDXProvider components={components}>
16+
<MDXProvider components={mdxComponentMap}>
1917
<MDXSlide />
2018
<div
2119
style={{ height: 5, width: '100%', backgroundColor: 'black' }}

src/components/deck.js

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,11 @@ import searchChildrenForAppear from '../utils/search-children-appear';
2727
*/
2828

2929
const AnimatedDeckDiv = styled(animated.div)`
30+
height: 100%;
3031
display: flex;
3132
align-items: center;
3233
justify-content: center;
33-
height: 100%;
34+
position: fixed;
3435
`;
3536

3637
const initialState = {
@@ -44,18 +45,15 @@ const initialState = {
4445

4546
const defaultSlideEffect = {
4647
from: {
47-
width: '100%',
48-
position: 'absolute',
48+
position: 'fixed',
4949
transform: 'translate(100%, 0%)'
5050
},
5151
enter: {
52-
width: '100%',
53-
position: 'absolute',
52+
position: 'fixed',
5453
transform: 'translate(0, 0%)'
5554
},
5655
leave: {
57-
width: '100%',
58-
position: 'absolute',
56+
position: 'fixed',
5957
transform: 'translate(-100%, 0%)'
6058
},
6159
config: { precision: 0 }

src/components/slide.js

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,18 @@ import React from 'react';
22
import PropTypes from 'prop-types';
33
import useSlide, { SlideContext } from '../hooks/use-slide';
44
import { DeckContext } from '../hooks/use-deck';
5-
import styled from 'styled-components';
5+
import styled, { ThemeContext } from 'styled-components';
66
import { color } from 'styled-system';
77

88
const SlideContainer = styled('div')`
99
${color};
1010
position: relative;
11-
width: 100%;
12-
padding-top: 56.25%;
11+
transform-origin: left center;
12+
width: ${({ theme }) => theme.size.width || 1366}px;
13+
height: ${({ theme }) => theme.size.height || 768}px;
1314
`;
1415
const SlideWrapper = styled('div')`
1516
${color};
16-
top: 0;
17-
left: 0;
18-
right: 0;
19-
bottom: 0;
20-
position: absolute;
2117
overflow-y: scroll;
2218
`;
2319
const TemplateWrapper = styled('div')`
@@ -40,19 +36,47 @@ const Slide = props => {
4036
backgroundColor,
4137
textColor,
4238
template,
43-
numberOfSlides
39+
numberOfSlides,
40+
scaleRatio
4441
} = props;
42+
const theme = React.useContext(ThemeContext);
4543
const { slideElementMap, keyboardControls } = React.useContext(DeckContext);
4644
const initialState = { currentSlideElement: 0, immediate: false };
4745
const numberOfSlideElements = slideElementMap[slideNum];
46+
const [ratio, setRatio] = React.useState(scaleRatio || 1);
47+
48+
const transformForWindowSize = React.useCallback(() => {
49+
const slideWidth = theme.size.width || 1366;
50+
const clientWidth = Math.max(
51+
document.documentElement.clientWidth,
52+
window.innerWidth || 0
53+
);
54+
const ratio = clientWidth / slideWidth;
55+
setRatio(ratio);
56+
}, [theme]);
57+
58+
React.useEffect(() => {
59+
if (!isNaN(scaleRatio)) {
60+
return;
61+
}
62+
transformForWindowSize();
63+
window.addEventListener('resize', transformForWindowSize);
64+
return () => {
65+
window.removeEventListener('resize', transformForWindowSize);
66+
};
67+
}, [transformForWindowSize, scaleRatio]);
68+
4869
const value = useSlide(
4970
initialState,
5071
slideNum,
5172
numberOfSlideElements,
5273
keyboardControls
5374
);
5475
return (
55-
<SlideContainer backgroundColor={backgroundColor}>
76+
<SlideContainer
77+
backgroundColor={backgroundColor}
78+
style={{ transform: `scale(${ratio})` }}
79+
>
5680
<TemplateWrapper>
5781
{typeof template === 'function' &&
5882
template({ slideNumber: slideNum, numberOfSlides })}
@@ -67,8 +91,9 @@ const Slide = props => {
6791
Slide.propTypes = {
6892
backgroundColor: PropTypes.string,
6993
children: PropTypes.node.isRequired,
70-
slideNum: PropTypes.number,
7194
numberOfSlides: PropTypes.number,
95+
scaleRatio: PropTypes.number,
96+
slideNum: PropTypes.number,
7297
template: PropTypes.func,
7398
textColor: PropTypes.string
7499
};

src/theme/default-theme.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
export default {
2+
size: {
3+
width: 1366,
4+
height: 768
5+
},
26
colors: {
37
primary: '#ebe5da',
48
secondary: '#f04d21',

src/utils/mdx-component-mapper.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import * as React from 'react';
2+
import {
3+
CodePane,
4+
Image,
5+
OrderedList,
6+
Quote,
7+
Heading,
8+
UnorderedList,
9+
Text,
10+
ListItem
11+
} from '../components';
12+
13+
const LeftAlignedHeading = props => <Heading {...props} textAlign="left" />;
14+
15+
const mdxComponentMap = {
16+
p: Text,
17+
h1: LeftAlignedHeading,
18+
h2: LeftAlignedHeading,
19+
h3: LeftAlignedHeading,
20+
blockquote: Quote,
21+
ul: UnorderedList,
22+
ol: OrderedList,
23+
li: ListItem,
24+
img: Image,
25+
codeblock: CodePane,
26+
code: CodePane
27+
};
28+
29+
export default mdxComponentMap;

0 commit comments

Comments
 (0)