Skip to content

Instantly share code, notes, and snippets.

@zachj0hnston
Created August 15, 2018 21:34
Show Gist options
  • Save zachj0hnston/1cac336632d96647ae826e463487096f to your computer and use it in GitHub Desktop.
Save zachj0hnston/1cac336632d96647ae826e463487096f to your computer and use it in GitHub Desktop.
Framer X Browser component
import * as React from "react";
import { Frame, PropertyControls, ControlType } from "framer";
import { FrameProps } from "framer/types/src/render/presentation/Frame";
export class Browser extends React.Component {
static defaultProps = {
width: 1600,
height: 1200,
wallpaper: true,
background: "#FFA1D0",
browser: true
url: "framer.com"
};
static propertyControls = {
wallpaper: {
type: ControlType.Boolean,
title: "Wallpaper"
},
background: {
type: ControlType.Color,
title: "Background"
},
browser: {
type: ControlType.Boolean,
title: "Browser"
},
url: {
type: ControlType.String,
title: "URL"
}
}
state = {
url: null
};
componentDidMount() {
this.setImage();
}
setImage() {
// Credit to Floris Verloop for this Unsplash code
const url = `https://source.unsplash.com/random/1200x800?/desktop+wallpaper`;
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if (xhr.readyState == XMLHttpRequest.HEADERS_RECEIVED) {
this.setState({ url: xhr.responseURL });
}
};
xhr.open("GET", url, true);
xhr.send(null);
}
render() {
// Check if a child has been connected and resize browser
let content = (
<div style={{
textAlign: "center",
paddingTop: "180px",
}}>
<svg width='450' height='232' viewBox='0 0 450 232' xmlns='http://www.w3.org/2000/svg'>
<g id='Page-1' fill='none' fillRule='evenodd'>
<g id='Artboard' transform='translate(-104 -84)' fill='#AAA8AD' fillRule='nonzero'>
<path d='M200.739015,193.477121 L201.260985,190.522879 L294.448485,206.987723 L293.926515,209.941965 L200.739015,193.477121 Z M198.025126,202.593009 C193.395269,201.295468 190,197.044238 190,192 C190,186.955762 193.395269,182.704532 198.025126,181.406991 L198.025126,89 L104,89 L104,84 L203,84 L203,181.181376 C208.120236,182.121889 212,186.607861 212,192 C212,197.392139 208.120236,201.878111 203,202.818624 L203,316 L104,316 L104,311 L198.025126,311 L198.025126,202.593009 Z M297,219 C290.924868,219 286,214.075132 286,208 C286,201.924868 290.924868,197 297,197 C303.075132,197 308,201.924868 308,208 C308,214.075132 303.075132,219 297,219 Z M299,128 L299,289 L549,289 L549,128 L299,128 Z M294,123 L554,123 L554,294 L294,294 L294,123 Z'
id='diagram' />
</g>
</g>
</svg>
<div style={{
paddingTop: "60px",
fontSize: "20px",
color: "#AAA8AD",
}}>
Drag a line to display your design in this browser
</div>
</div>
);
// Show or hide the browser header
let headerHeight = 0;
let header = "";
if (this.props.browser) {
headerHeight = 40;
header = (
<div style={{
width: "100%",
height: headerHeight,
position: "absolute",
top: "0",
left: "0",
display: "flex",
justifyContent: "space-between",
alignItems: "center",
background: "linear-gradient(0deg, rgb(214, 213, 215), rgb(241, 241, 242))",
boxShadow: "inset 0 -1px 0 0 rgba(0, 0, 0, 0.2)",
}}>
{/* Traffic light controller */}
<div style={{
marginLeft: "4px",
display: "flex",
}}>
<div style={{
width: "12px",
height: "12px",
marginLeft: "8px",
backgroundColor: "rgb(255, 95, 87)",
borderRadius: "50%",
border: "0.5px solid rgba(0, 0, 0, 0.15)",
}}></div>
<div style={{
width: "12px",
height: "12px",
marginLeft: "8px",
backgroundColor: "rgb(255, 189, 45)",
borderRadius: "50%",
border: "0.5px solid rgba(0, 0, 0, 0.15)",
}}></div>
<div style={{
width: "12px",
height: "12px",
marginLeft: "8px",
backgroundColor: "rgb(40, 201, 64)",
borderRadius: "50%",
border: "0.5px solid rgba(0, 0, 0, 0.15)",
}}></div>
</div>
{/* URL bar */}
<div style={{
width: "400px",
height: "23px",
background: "linear-gradient(0deg, rgb(241, 241, 241), rgb(249, 249, 249))",
borderRadius: "5px",
boxShadow: "0px 1px 0.5px 0px rgba(0, 0, 0, 0.1)",
border: "0.5px solid rgba(34, 34, 34, 0.25)",
textAlign: "center",
fontSize: "12px",
lineHeight: "1.8em",
fontFamily: ".SFNSText-Medium"
}}>
{this.props.url}
</div>
{/* TODO: Add new tab button */}
<div style={{}}></div>
</div>
)
}
// Resize the browser based on the child size
let contentHeight = 700 + headerHeight;
let contentWidth = 1200;
if (this.props.children[0]) {
content = this.props.children;
contentHeight = content[0].props.height + headerHeight;
contentWidth = content[0].props.width;
};
// If wallpaper is enabled, place an image and tweak the drop shadow
let wallpaperUrl = "";
let browserShadow = "0 22px 70px 4px rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(0, 0, 0, 0.1)";
if (this.props.wallpaper) {
wallpaperUrl = `url(${this.state.url})`;
browserShadow = "0 22px 70px 4px rgba(0, 0, 0, 0.56), 0 0 0 1px rgba(0, 0, 0, 0.1)";
}
return (
<div style={{
height: "100%",
width: "100%",
display: "flex",
justifyContent: "center",
alignItems: "center",
background: this.props.background,
backgroundImage: wallpaperUrl,
backgroundSize: "cover",
backgroundPosition: "center",
}}>
{/* Container */}
<div style={{
position: "relative",
height: contentHeight,
width: contentWidth,
paddingTop: headerHeight,
boxShadow: browserShadow,
borderRadius: "5px",
background: "white",
overflow: "hidden",
}}>
{header}
{content}
</div>
</div>
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment