Skip to content

Commit d7f6147

Browse files
committed
Whoop! Managed to get it to a usable stage
1 parent 72c7707 commit d7f6147

File tree

11 files changed

+7635
-9
lines changed

11 files changed

+7635
-9
lines changed

components/Inspector/Transforms.js

+692
Large diffs are not rendered by default.

containers/Root/index.js

+32-2
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,47 @@
11
import 'css/Root.css';
22
import React from 'react';
3-
import Preview from 'components/Preview/Page.js';
3+
import TransformsInspector from 'components/inspector/Transforms.js';
4+
import AutosizeInput from 'react-input-autosize';
5+
46

57

68
export default class Root extends React.Component {
79
constructor(props) {
810
super(props);
11+
this.state = {
12+
transform:
13+
// 'rotate(45deg) scaleY(0.5) rotate(-45deg)',
14+
'rotate(50deg) translateY(50%) rotate(-75deg) translateY(-60%) rotate(30deg) scale(0.5)',
15+
// 'rotate(50deg) translateY(-100%) scale(0.5) rotate(30deg) translateY(100%) scaleY(0.4) translate(4em, 4em) rotate(-30deg)',
16+
reference: null
17+
};
18+
}
19+
20+
componentDidMount() {
21+
this.setState({
22+
reference: this.foo
23+
});
24+
}
25+
26+
handleInput(event) {
27+
this.setState({ transform: event.target.value });
928
}
1029

1130
render() {
1231
return (
1332
<div className="app-root">
14-
33+
<nav className="controls">
34+
<span className="foo"><span className="selector">.foo</span>{' { '}<span className="property">transform</span>: <span className="value"><AutosizeInput type="text" spellCheck="false" onChange={::this.handleInput} value={this.state.transform}/></span>{'; }'}</span>
35+
</nav>
36+
<div
37+
ref={c => this.foo = c}
38+
className="foo"
39+
style={{ transform: this.state.transform }}
40+
/>
41+
<TransformsInspector
42+
transform={this.state.transform}
43+
reference={this.state.reference}
44+
/>
1545
</div>
1646
);
1747
}

css/Root.css

+66
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,69 @@ html, body {
77
* {
88
box-sizing: border-box;
99
}
10+
11+
.app-root {
12+
display: flex;
13+
flex-flow: column nowrap;
14+
justify-content: center;
15+
align-items: center;
16+
width: 100%;
17+
height: 100%;
18+
background: hsl(0, 0%, 90%);
19+
}
20+
21+
nav.controls {
22+
position: absolute;
23+
top: 0;
24+
left: 0;
25+
right: 0;
26+
padding: 20px 10px;
27+
border-bottom: 1px solid hsl(0, 0%, 80%);
28+
background: hsl(0, 0%, 100%);
29+
font: 12px/1.2 monospace;
30+
color: hsl(210, 15%, 20%)
31+
}
32+
33+
span.selector { color: hsl(0, 0%, 10%); }
34+
span.property { color: hsl(0, 100%, 39%); }
35+
span.value { }
36+
37+
nav.controls input {
38+
border: 1px solid transparent;
39+
padding: 4px 2px;
40+
margin: -4px -2px;
41+
border-radius: 3px;
42+
font: 12px/1.2 monospace;
43+
background: none;
44+
color: currentColor;
45+
}
46+
47+
nav.controls input:focus {
48+
color: black;
49+
border: 1px solid hsl(0, 0%, 70%);
50+
background: white;
51+
box-shadow: 0 2px 1px -1px hsla(0, 0%, 10%, 0.05);
52+
outline: none;
53+
}
54+
55+
56+
.app-root canvas.overlay {
57+
position: absolute;
58+
top: 0;
59+
left: 0;
60+
right: 0;
61+
bottom: 0;
62+
display: block;
63+
width: 100%;
64+
height: 100%;
65+
pointer-events: none;
66+
}
67+
68+
69+
div.foo {
70+
width: 180px;
71+
height: 300px;
72+
border-radius: 4px;
73+
background: white;
74+
box-shadow: 0 2px 3px 1px hsla(0, 0%, 0%, 0.2);
75+
}

index.dev.js

-3
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@ import React from 'react';
22
import { render } from 'react-dom';
33
import { AppContainer } from 'react-hot-loader';
44
import Root from './containers/Root';
5-
import FileSystem from 'systems/FileSystem.js';
6-
import 'polyfills/passive-scroll.js';
75

8-
window.fs = FileSystem;
96

107
render(
118
<AppContainer>

index.prod.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from 'react';
22
import { render } from 'react-dom';
33
import Root from './containers/Root';
4-
import 'polyfills/passive-scroll.js';
4+
55

66
render(
77
<Root/>,

package.json

+5
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,16 @@
2222
"license": "MIT",
2323
"dependencies": {
2424
"classnames": "^2.1.2",
25+
"gl-mat4": "^1.1.4",
26+
"gl-quat": "^1.0.0",
27+
"gl-vec3": "^1.0.3",
2528
"localforage": "^1.4.2",
29+
"mat4-decompose": "^1.0.4",
2630
"react": "^15.0.1",
2731
"react-codemirror": "^0.2.6",
2832
"react-dom": "^15.0.1",
2933
"react-hot-loader": "^3.0.0-beta.1",
34+
"react-input-autosize": "^1.0.0",
3035
"react-notification-center": "^1.2.1"
3136
},
3237
"devDependencies": {

polyfills/canvas.js

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
CanvasRenderingContext2D.prototype.dashedLine = function (x0, y0, x1, y1, dash, gap) {
2+
if(dash == undefined) dash = 2;
3+
if(gap == undefined) gap = 2;
4+
var dashgap = dash + gap;
5+
6+
var dx = x1 - x0;
7+
var dy = y1 - y0;
8+
var dist = Math.sqrt(dx * dx + dy * dy);
9+
var nx = dx / dist;
10+
var ny = dy / dist;
11+
var dashX = nx * dash;
12+
var dashY = ny * dash;
13+
var gapX = nx * gap;
14+
var gapY = ny * gap;
15+
16+
var approx = dist / dashgap;
17+
var total = Math.floor(approx);
18+
var expose = approx - total;
19+
20+
x0 += nx * dashgap * expose * 0.5;
21+
y0 += ny * dashgap * expose * 0.5;
22+
23+
x0 -= gapX * 0.5;
24+
y0 -= gapY * 0.5;
25+
26+
while (total-->0)
27+
{
28+
x0 += gapX;
29+
y0 += gapY;
30+
this.moveTo(x0, y0);
31+
x0 += dashX;
32+
y0 += dashY;
33+
this.lineTo(x0, y0);
34+
}
35+
};
36+
37+
CanvasRenderingContext2D.prototype.roundedRect = function (x, y, w, h, r) {
38+
this.moveTo(x + r, y);
39+
this.arcTo(x + w, y, x + w, y + r, r);
40+
this.arcTo(x + w, y + h, x + w - r, y + h, r);
41+
this.arcTo(x, y + h, x, y + h - r, r);
42+
this.arcTo(x, y, x + r, y, r);
43+
};

polyfills/css-parser.js

+138
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
2+
class CSSParser {
3+
static transform(string) {
4+
if(!string) return null;
5+
6+
var number = '[+-]?\\d+?(?:\\.\\d+)?';
7+
8+
var length = `${number}(px|em|ex|rem|vw|vh|vmin|vmax|in|cm|mm|pt|pc)`;
9+
var percent = `${number}(%)`;
10+
var dimension = `${number}(%|px|em|ex|rem|vw|vh|vmin|vmax|in|cm|mm|pt|pc)`;
11+
var angle = `${number}(deg|rad|turn)`;
12+
13+
var translate = new RegExp(`\\s*(${dimension}|0)\\s*(?:,\\s*(${dimension}|0)\\s*)?`);
14+
var translateXYZ = new RegExp(`\\s*(${dimension}|0)\\s*`);
15+
var translate3d = new RegExp(`\\s*(${dimension}|0)\\s*,\\s*(${dimension}|0)\\s*,\\s*(${dimension}|0)\\s*`);
16+
17+
var rotate = new RegExp(`\\s*(${angle}|0)\\s*`);
18+
var rotate3d = new RegExp(`\\s*${number}\\s*,\\s*${number}\\s*,\\s*${number}\\s*,\\s*(${angle}|0)\\s*`);
19+
20+
var skew = new RegExp(`\\s*(${angle}|0)\\s*(?:,\\s*(${angle}|0)\\s*)?`);
21+
var skewXY = new RegExp(`\\s*(${angle}|0)\\s*`);
22+
23+
var perspective = new RegExp(`\\s*(${length}|0)\\s*`);
24+
25+
var functions = /\b((?:matrix|translate|scale|rotate|skew|perspective)(?:X|Y|Z|3d)?)\((.*?)\)/g;
26+
27+
var results = [];
28+
var result;
29+
while(result = functions.exec(string))
30+
{
31+
var name = result[1];
32+
var args = result[2];
33+
var values;
34+
switch(name) {
35+
case 'matrix': values = args.split(','); if(values.length !== 6) return null; break;
36+
case 'matrix3d': values = args.split(','); if(values.length !== 16) return null; break;
37+
case 'translate': values = args.match(translate); break;
38+
case 'translateX':
39+
case 'translateY':
40+
case 'translateZ': values = args.match(translateXYZ); break;
41+
case 'translate3d': values = args.match(translate3d); break;
42+
case 'scale':
43+
case 'scaleX':
44+
case 'scaleY':
45+
case 'scaleZ':
46+
case 'scale3d': values = args.split(','); break;
47+
case 'rotate':
48+
case 'rotateX':
49+
case 'rotateY':
50+
case 'rotateZ': values = args.match(rotate); break;
51+
case 'rotate3d': values = args.match(rotate3d); break;
52+
case 'skew': values = args.match(skew); break;
53+
case 'skewX':
54+
case 'skewY': values = args.match(skewXY); break;
55+
case 'perspective': values = args.match(perspective); break;
56+
default: return null; // An invalid or unimplemented transform function? (E.g. skewZ, perspectiveX)
57+
}
58+
59+
// Parse values into floats
60+
if(/^(matrix|scale)/.test(name)) // unit-less
61+
{
62+
values = values.map(value => parseFloat(value));
63+
}
64+
65+
else // Some functions have tuples of [value, unit]
66+
{
67+
values = values.slice(1).reduce((prev, value, index) => {
68+
if(index%2) prev[prev.length - 1].push(value);
69+
else prev.push([parseFloat(value)]);
70+
return prev;
71+
}, []);
72+
// .map((value, index) => index%2? value : parseFloat(value));
73+
74+
switch(name) {
75+
case 'translate':
76+
values[0].push('width');
77+
if(values[1]) values[1].push('height');
78+
break;
79+
case 'translateX': values[0].push('width'); break;
80+
case 'translateY': values[0].push('height'); break;
81+
case 'translate3d':
82+
values[0].push('width');
83+
values[1].push('height');
84+
break;
85+
}
86+
}
87+
88+
results.push({
89+
name,
90+
values
91+
});
92+
}
93+
94+
return results;
95+
}
96+
97+
static value(input) {
98+
if(!input || !input.length) return null;
99+
var cardinal = input[2] || 'width';
100+
101+
if(typeof input === 'string')
102+
{
103+
input = input.match(/([+-]?\d+?(?:\.\d+)?)(px|em|rem|ex|%|vw|vh|vmin|vmax|in|cm|mm|pt|pc|deg|rad|turn)?/);
104+
var value = parseFloat(input[1]);
105+
var unit = input[2];
106+
}
107+
108+
else
109+
{
110+
var [value, unit] = input;
111+
}
112+
113+
switch (unit) {
114+
case 'em': return value * CSSParser.base.fontSize;
115+
case 'rem': return value * parseFloat(getComputedStyle(document.documentElement).fontSize);
116+
case 'ch': return value * CSSParser.base.fontSize * 0.5;
117+
case 'ex': return value * CSSParser.base.fontSize * 0.45;
118+
case '%': return value * CSSParser.base[cardinal] / 100;
119+
case 'vw': return value * window.innerWidth / 100;
120+
case 'vh': return value * window.innerHeight / 100;
121+
case 'vmin': return value * Math.min(window.innerWidth, window.innerHeight) / 100;
122+
case 'vmax': return value * Math.max(window.innerWidth, window.innerHeight) / 100;
123+
case 'in': return value * 72;
124+
case 'cm': return value / 2.54 * 72;
125+
case 'mm': return value / 2.54 * 72 / 10;
126+
case 'pt': return value * 96 / 72;
127+
case 'pc': return value * CSSParser.base[cardinal];
128+
case 'deg': return value * 0.017453292519943295;
129+
case 'rad': return value;
130+
case 'turn': return value * 6.283185307179586;
131+
default: return value;
132+
}
133+
}
134+
}
135+
136+
CSSParser.base = { width: 1, height: 1, fontSize: 16 };
137+
138+
export default CSSParser;

0 commit comments

Comments
 (0)