diff --git a/examples/website/quick-start/app.jsx b/examples/website/quick-start/app.jsx
index 79323952..28397936 100644
--- a/examples/website/quick-start/app.jsx
+++ b/examples/website/quick-start/app.jsx
@@ -7,7 +7,7 @@ import {anticipate, easeIn, reverseEasing} from 'popmotion';
const INITIAL_VIEW_STATE = {
longitude: -122.402,
latitude: 37.79,
- zoom: 11
+ zoom: 14
};
const TIMECODE = {
@@ -17,10 +17,23 @@ const TIMECODE = {
};
const RESOLUTION = {
- width: 640,
- height: 480
+ width: 1920,
+ height: 1080
};
+const FORMAT_CONFIGS = {
+ webm: {
+ quality: 0.99
+ },
+ gif: {
+ width: 480,
+ height: 270
+ }
+};
+
+const BACKGROUND = [30 / 255, 30 / 255, 30 / 255, 1];
+const BLUE = [37, 80, 129];
+
const Container = ({children}) => (
d.color,
getRadius: d => d.radius,
- opacity: 0.1,
- radiusScale: 0.01
+ opacity: 1,
+ radiusScale: 1
}),
new TextLayer({
id: 'text',
data: [{position: [-122.402, 37.79], text: 'Hello World'}],
- opacity: 0.1,
- getAngle: -90
+ opacity: 1,
+ getPixelOffset: [0, -64],
+ getSize: 64
})
]),
layerKeyframes: [
@@ -89,10 +103,14 @@ export default function App() {
- {
- setCameraFrame(vs as MapViewState);
- }}
- controller={true}
- width={resolution.width}
- height={resolution.height}
- layers={layers}
- {...adapter.getProps({deck, onNextFrame, extraProps: deckProps})}
- />
+
+ {deckglStyle => (
+ {
+ setCameraFrame(vs as MapViewState);
+ }}
+ controller={true}
+ width={resolution.width}
+ height={resolution.height}
+ layers={layers}
+ {...adapter.getProps({deck, onNextFrame, extraProps: deckProps})}
+ />
+ )}
+
{
+ const aspect = internalCanvasResolution.width / internalCanvasResolution.height;
+ if (aspect > 1) {
+ // horizontal
+ return {width: Math.round(minAxis * aspect), height: minAxis};
+ } else if (aspect < 1) {
+ // vertical
+ return {width: minAxis, height: Math.round(minAxis / aspect)};
+ }
+ // square
+ return {width: minAxis, height: minAxis};
+};
+
+export const DeckGLRender = ({renderResolution, previewPadding = 0, overlay = null, children}) => {
+ const canvasClientSize = getCanvasClientSize(renderResolution);
+ return (
+
+ {previewSize => {
+ const scalar = scale(previewSize, canvasClientSize);
+ const deckglStyle = {
+ width: `${canvasClientSize.width}px`,
+ height: `${canvasClientSize.height}px`,
+ transform: `scale(${scalar})`,
+ transformOrigin: 'top left'
+ };
+ return (
+
+ {children(deckglStyle)}
+
+ );
+ }}
+
+ );
+};
diff --git a/modules/react/src/renderer/pillarbox.js b/modules/react/src/renderer/pillarbox.js
new file mode 100644
index 00000000..1f080269
--- /dev/null
+++ b/modules/react/src/renderer/pillarbox.js
@@ -0,0 +1,75 @@
+import React, {useCallback} from 'react';
+import styled from 'styled-components';
+import AutoSizer from 'react-virtualized-auto-sizer';
+import {nearestEven, scale} from './utils';
+
+const AutoSizePillarbox = ({children, internalCanvasResolution, previewPadding}) => {
+ const getPreviewSize = useCallback(
+ ({width, height}) => {
+ // padding
+ if (width > height) {
+ width = width - previewPadding;
+ } else {
+ height = height - previewPadding;
+ }
+ const scalar = scale({width, height}, internalCanvasResolution);
+ return {
+ width: nearestEven(internalCanvasResolution.width * scalar, 0),
+ height: nearestEven(internalCanvasResolution.height * scalar, 0)
+ };
+ },
+ [internalCanvasResolution, previewPadding]
+ );
+
+ return (
+
+ {({width, height}) => {
+ const previewSize = getPreviewSize({width, height});
+ return children({
+ previewSize,
+ pillarboxSize: {width: nearestEven(width, 0), height: nearestEven(height, 0)}
+ });
+ }}
+
+ );
+};
+
+const PillarboxBackground = styled.div`
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ width: ${props => props.size.width}px;
+ height: ${props => props.size.height}px;
+`;
+
+const PillarboxOverlay = styled.div`
+ position: absolute;
+ width: ${props => props.size.width}px;
+ height: ${props => props.size.height}px;
+`;
+
+export const Pillarbox = ({children, overlay, internalCanvasResolution, previewPadding}) => {
+ return (
+
+ {({previewSize, pillarboxSize}) => (
+
+ {children ? (
+ children(previewSize)
+ ) : (
+
+ )}
+ {overlay && {overlay}}
+
+ )}
+
+ );
+};
diff --git a/modules/react/src/renderer/utils.js b/modules/react/src/renderer/utils.js
new file mode 100644
index 00000000..b39ddec4
--- /dev/null
+++ b/modules/react/src/renderer/utils.js
@@ -0,0 +1,10 @@
+export const nearestEven = (num, decimalPlaces = 3) => {
+ const factorTen = Math.pow(10, decimalPlaces);
+ num = num * factorTen;
+ num = 2 * Math.round(num / 2);
+ return num / factorTen;
+};
+
+export function scale(startingSize, targetSize) {
+ return Math.min(startingSize.width / targetSize.width, startingSize.height / targetSize.height);
+}
diff --git a/yarn.lock b/yarn.lock
index e97f2914..37dc57af 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3317,9 +3317,9 @@ camelize@^1.0.0:
integrity sha512-W2lPwkBkMZwFlPCXhIlYgxu+7gC/NUlCtdK652DAJ1JdgV0sTrvuPFshNPrFa1TY2JOkLhgdeEBplB4ezEa+xg==
caniuse-lite@^1.0.30001370:
- version "1.0.30001374"
- resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001374.tgz"
- integrity sha512-mWvzatRx3w+j5wx/mpFN5v5twlPrabG8NqX2c6e45LCpymdoGqNvRkRutFUqpRTXKFQFNQJasvK0YT7suW6/Hw==
+ version "1.0.30001414"
+ resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001414.tgz"
+ integrity sha512-t55jfSaWjCdocnFdKQoO+d2ct9C59UZg4dY3OnUlSZ447r8pUtIKdp0hpAzrGFultmTC+Us+KpKi4GZl/LXlFg==
caseless@~0.12.0:
version "0.12.0"