├── .gitignore ├── README.md ├── assets ├── airplane.svg ├── altitude_pressure.svg ├── altitude_ticks.svg ├── fi_box.svg ├── fi_circle.svg ├── fi_needle.svg ├── fi_needle_small.svg ├── fi_tc_airplane.svg ├── heading_mechanics.svg ├── heading_yaw.svg ├── horizon_back.svg ├── horizon_ball.svg ├── horizon_circle.svg ├── horizon_mechanics.svg ├── speed_mechanics.svg ├── turn_coordinator.svg └── vertical_mechanics.svg ├── package.json ├── src ├── Instrument │ ├── Instrument.js │ ├── InstrumentBox.js │ ├── StyledInstrumentBox.js │ ├── StyledInstrumentImg.js │ └── index.js └── components │ ├── Altimeter │ ├── Altimeter.js │ ├── Readme.md │ └── index.js │ └── Heading │ ├── Heading.js │ ├── Readme.md │ └── index.js └── styleguide.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .idea -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-flight-indicators 2 | 3 | ![jI2Y1VKr](https://user-images.githubusercontent.com/770632/133467060-e8355bb9-6040-436a-955b-0d080411a343.png) 4 | 5 | How to start locally: 6 | 7 | ``` 8 | git clone https://github.com/lookapanda/react-flight-indicators.git 9 | cd react-flight-indicators 10 | npm install 11 | npm run styleguide-server 12 | ``` 13 | 14 | Then open [http://localhost:3000](http://localhost:3000) in your browser. 15 | -------------------------------------------------------------------------------- /assets/airplane.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 13 | 15 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /assets/altitude_pressure.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 990 9 | 985 10 | 980 11 | 995 12 | 1000 13 | 1005 14 | 1010 15 | 1015 16 | 1020 17 | 1025 18 | 1030 19 | 20 | 1035 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /assets/altitude_ticks.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 0 69 | ALT 70 | 1 71 | 2 72 | 3 73 | 4 74 | 5 75 | 6 76 | 7 77 | 8 78 | 9 79 | 80 | 81 | 82 | 83 | 84 | 85 | 87 | 88 | 90 | 91 | 92 | FEET 93 | 100 94 | 1000 FEET 95 | CALIBRATEDTO25 000 FEET 96 | 97 | -------------------------------------------------------------------------------- /assets/fi_box.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 17 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /assets/fi_circle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 18 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /assets/fi_needle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 17 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /assets/fi_needle_small.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 18 | 20 | 21 | 22 | 24 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /assets/fi_tc_airplane.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15 | 19 | 20 | 24 | 28 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /assets/heading_mechanics.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /assets/heading_yaw.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 82 | 83 | 84 | 94 | 104 | 105 | 106 | 116 | 125 | 126 | 127 | 132 | 135 | 136 | 137 | 142 | 144 | 145 | 146 | 148 | 155 | 156 | 157 | 159 | 164 | 165 | 166 | 174 | 175 | 176 | 186 | 187 | 188 | 190 | 191 | 192 | 200 | 201 | 202 | 204 | 205 | 206 | -------------------------------------------------------------------------------- /assets/horizon_back.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /assets/horizon_ball.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 49 | 50 | 51 | 56 | 63 | 64 | 65 | 70 | 77 | 78 | 79 | 80 | 87 | 88 | 89 | 90 | 97 | 98 | 99 | 100 | 107 | 108 | 109 | 114 | 121 | 122 | 123 | 128 | 135 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /assets/horizon_circle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /assets/horizon_mechanics.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /assets/speed_mechanics.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 9 | 11 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 20 51 | 40 52 | 60 53 | 80 54 | 100 55 | 120 56 | 140 57 | 160 58 | KNOTS 59 | AIR SPEED 60 | 0 61 | 62 | -------------------------------------------------------------------------------- /assets/turn_coordinator.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15 | 17 | 19 | 23 | 27 | 28 | 30 | 34 | 38 | 39 | 41 | 45 | 49 | 50 | 52 | 56 | 60 | 61 | 68 | 71 | 72 | 79 | 82 | 83 | 90 | 93 | 94 | 97 | 100 | 101 | 108 | 111 | 112 | 119 | 122 | 123 | 126 | 129 | 130 | 137 | 140 | 141 | 148 | 151 | 152 | 162 | 171 | 180 | 189 | 196 | 199 | 200 | 201 | 205 | 209 | 213 | 218 | 222 | 227 | 231 | 235 | 240 | 244 | 245 | NO PITCHINFORMATION 258 | D.C.ELEC. 271 | TURN COORDINATOR 281 | 290 | 300 | 304 | 308 | 2 MIN. 318 | R 327 | L 336 | 346 | 356 | 360 | 364 | 368 | 373 | 377 | 381 | 382 | 383 | -------------------------------------------------------------------------------- /assets/vertical_mechanics.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 68 | 72 | 73 | 75 | 0 76 | 78 | 79 | 81 | 82 | UP 83 | DOWN 84 | 1 85 | 1 86 | .5 87 | .5 88 | 1.5 89 | 1.5 90 | 2 91 | VERTICAL SPEED 92 | 1000FT PER MIN 93 | 94 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-flight-indicators", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "lib/index.js", 6 | "scripts": { 7 | "styleguide-server": "styleguidist server", 8 | "styleguide-build": "styleguidist build" 9 | }, 10 | "babel": { 11 | "presets": [ 12 | "es2015", 13 | "react", 14 | "stage-0" 15 | ] 16 | }, 17 | "eslintConfig": { 18 | "parser": "babel-eslint", 19 | "extends": "airbnb", 20 | "env": { 21 | "browser": true, 22 | "node": true, 23 | "jest": true, 24 | "es6": true 25 | }, 26 | "plugins": [ 27 | "react", 28 | "jsx-a11y" 29 | ], 30 | "parserOptions": { 31 | "ecmaVersion": 6, 32 | "sourceType": "module", 33 | "ecmaFeatures": { 34 | "jsx": true 35 | } 36 | }, 37 | "rules": { 38 | "arrow-parens": [ 39 | "error", 40 | "always" 41 | ], 42 | "arrow-body-style": [ 43 | 2, 44 | "as-needed" 45 | ], 46 | "comma-dangle": [ 47 | 2, 48 | "always-multiline" 49 | ], 50 | "import/imports-first": 0, 51 | "import/newline-after-import": 0, 52 | "import/no-dynamic-require": 0, 53 | "import/no-extraneous-dependencies": 0, 54 | "import/no-named-as-default": 0, 55 | "import/no-unresolved": 2, 56 | "import/prefer-default-export": 0, 57 | "indent": [ 58 | 2, 59 | 2, 60 | { 61 | "SwitchCase": 1 62 | } 63 | ], 64 | "jsx-a11y/aria-props": 2, 65 | "jsx-a11y/heading-has-content": 0, 66 | "jsx-a11y/href-no-hash": 2, 67 | "jsx-a11y/label-has-for": 2, 68 | "jsx-a11y/mouse-events-have-key-events": 2, 69 | "jsx-a11y/role-has-required-aria-props": 2, 70 | "jsx-a11y/role-supports-aria-props": 2, 71 | "max-len": 0, 72 | "newline-per-chained-call": 0, 73 | "no-confusing-arrow": 0, 74 | "no-console": 1, 75 | "no-use-before-define": 0, 76 | "prefer-template": 2, 77 | "class-methods-use-this": 0, 78 | "react/forbid-prop-types": 0, 79 | "react/jsx-first-prop-new-line": [ 80 | 2, 81 | "multiline" 82 | ], 83 | "react/jsx-filename-extension": 0, 84 | "react/jsx-no-target-blank": 0, 85 | "react/require-extension": 0, 86 | "react/self-closing-comp": 0, 87 | "require-yield": 0, 88 | "import/no-webpack-loader-syntax": 0 89 | } 90 | }, 91 | "author": "", 92 | "license": "ISC", 93 | "devDependencies": { 94 | "babel-cli": "^6.23.0", 95 | "babel-core": "^6.23.1", 96 | "babel-eslint": "^7.1.1", 97 | "babel-loader": "^6.3.0", 98 | "babel-preset-react": "^6.23.0", 99 | "babel-preset-stage-0": "^6.22.0", 100 | "eslint": "^3.15.0", 101 | "eslint-config-airbnb": "^14.1.0", 102 | "eslint-config-airbnb-base": "^11.1.0", 103 | "eslint-import-resolver-webpack": "^0.8.1", 104 | "eslint-plugin-import": "^2.2.0", 105 | "eslint-plugin-jsx-a11y": "^4.0.0", 106 | "eslint-plugin-react": "^6.9.0", 107 | "file-loader": "^0.10.0", 108 | "node-sass": "^4.5.0", 109 | "react": "^15.4.2", 110 | "react-dom": "^15.4.2", 111 | "react-styleguidist": "^4.6.3", 112 | "react-svg-loader": "^1.1.1", 113 | "styled-components": "^1.4.3", 114 | "webpack": "^2.2.1" 115 | }, 116 | "dependencies": {} 117 | } 118 | -------------------------------------------------------------------------------- /src/Instrument/Instrument.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export default styled.div` 4 | width: 250px; 5 | height: 250px; 6 | position: relative; 7 | display: inline-block; 8 | overflow: hidden; 9 | `; -------------------------------------------------------------------------------- /src/Instrument/InstrumentBox.js: -------------------------------------------------------------------------------- 1 | import React, { PureComponent, PropTypes } from 'react'; 2 | import StyledInstrumentBox from './StyledInstrumentBox'; 3 | import StyledInstrumentImg from './StyledInstrumentImg'; 4 | import FiBox from '../../assets/fi_box.svg'; 5 | import FiCircle from '../../assets/fi_circle.svg'; 6 | import FiNeedle from '../../assets/fi_needle.svg'; 7 | import FiNeedleSmall from '../../assets/fi_needle_small.svg'; 8 | import AltitudePressure from '../../assets/altitude_pressure.svg'; 9 | import AltitudeTicks from '../../assets/altitude_ticks.svg'; 10 | import Yaw from '../../assets/heading_yaw.svg'; 11 | import HeadingMechanics from '../../assets/heading_mechanics.svg'; 12 | 13 | export default function InstrumentBox({ type, values, rotation }) { 14 | switch (type) { 15 | case 'pressure': 16 | return ( 17 | 18 | 19 | 20 | 21 | 22 | ); 23 | case 'needleSmall': 24 | return ( 25 | 26 | 27 | 28 | 29 | 30 | ); 31 | case 'needle': 32 | return ( 33 | 34 | 35 | 36 | 37 | 38 | ); 39 | case 'circle': 40 | return ( 41 | 42 | 43 | 44 | 45 | 46 | ); 47 | case 'yaw': 48 | return ( 49 | 50 | 51 | 52 | 53 | 54 | ); 55 | case 'headingMechanics': 56 | return ( 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | ); 66 | case 'ticks': 67 | return ( 68 | 69 | 70 | 71 | ); 72 | default: 73 | return ( 74 | 75 | 76 | 77 | ); 78 | } 79 | } 80 | 81 | InstrumentBox.propTypes = { 82 | type: PropTypes.string, 83 | values: PropTypes.shape(PropTypes.oneOfType([PropTypes.number])), 84 | rotation: PropTypes.number, 85 | }; 86 | -------------------------------------------------------------------------------- /src/Instrument/StyledInstrumentBox.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export default styled.div` 4 | position: absolute; 5 | top: 0; 6 | left: 0; 7 | width: 100%; 8 | height: 100%; 9 | transition: transform .2s linear; 10 | `; 11 | -------------------------------------------------------------------------------- /src/Instrument/StyledInstrumentImg.js: -------------------------------------------------------------------------------- 1 | import React, { PropTypes } from 'react'; 2 | import styled from 'styled-components'; 3 | 4 | export default function InstrumentImg({ children }) { 5 | const Wrapper = styled.div` 6 | position: absolute; 7 | top: 0; 8 | left: 0; 9 | width: 100%; 10 | height: 100%; 11 | 12 | .svg { 13 | position: absolute; 14 | top: 0; 15 | left: 0; 16 | width: 100%; 17 | height: 100%; 18 | } 19 | `; 20 | return ( 21 | 22 | {children} 23 | 24 | ); 25 | } 26 | 27 | InstrumentImg.propTypes = { 28 | children: PropTypes.node.isRequired, 29 | }; 30 | -------------------------------------------------------------------------------- /src/Instrument/index.js: -------------------------------------------------------------------------------- 1 | 2 | export Instrument from './Instrument'; 3 | export InstrumentBox from './InstrumentBox'; 4 | export StyledInstrumentBox from './StyledInstrumentBox'; 5 | export StyledInstrumentImg from './StyledInstrumentImg'; 6 | -------------------------------------------------------------------------------- /src/components/Altimeter/Altimeter.js: -------------------------------------------------------------------------------- 1 | import React, { PropTypes } from 'react'; 2 | import { Instrument, InstrumentBox } from '../../Instrument'; 3 | 4 | export default function Altimeter({ altitude, pressure }) { 5 | pressure = (2 * pressure) - 1980; 6 | const needle = 90 + altitude % 1000 * 360 / 1000; 7 | const needleSmall = altitude / 10000 * 360; 8 | return ( 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | ); 18 | }; 19 | 20 | Altimeter.propTypes = { 21 | altitude: PropTypes.number.isRequired, 22 | pressure: PropTypes.number.isRequired, 23 | }; 24 | 25 | Altimeter.defaultProps = { 26 | altitude: 10000, 27 | pressure: 1000, 28 | }; -------------------------------------------------------------------------------- /src/components/Altimeter/Readme.md: -------------------------------------------------------------------------------- 1 | Altimeter: 2 | 3 | -------------------------------------------------------------------------------- /src/components/Altimeter/index.js: -------------------------------------------------------------------------------- 1 | 2 | export { default } from './Altimeter'; 3 | -------------------------------------------------------------------------------- /src/components/Heading/Heading.js: -------------------------------------------------------------------------------- 1 | import React, { PropTypes } from 'react'; 2 | import { Instrument, InstrumentBox } from '../../Instrument'; 3 | 4 | export default function Heading({ heading }) { 5 | return ( 6 | 7 | 8 | 9 | 10 | 11 | 12 | ) 13 | }; 14 | 15 | Heading.propTypes = { 16 | heading: PropTypes.number.isRequired, 17 | }; 18 | 19 | Heading.defaultProps = { 20 | heading: 45, 21 | }; 22 | -------------------------------------------------------------------------------- /src/components/Heading/Readme.md: -------------------------------------------------------------------------------- 1 | Heading: 2 | 3 | -------------------------------------------------------------------------------- /src/components/Heading/index.js: -------------------------------------------------------------------------------- 1 | 2 | export { default } from './Heading'; 3 | -------------------------------------------------------------------------------- /styleguide.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | module.exports = { 3 | title: 'React Flight Indicators', 4 | components: './src/components/**/*.js', 5 | updateWebpackConfig(webpackConfig) { 6 | // Your source files folder or array of folders, should not include node_modules 7 | const dir = path.join(__dirname, 'src'); 8 | webpackConfig.module.loaders.push( 9 | { 10 | test: /\.jsx?$/, 11 | include: dir, 12 | loader: 'babel-loader' 13 | }, 14 | { 15 | test: /\.svg$/, 16 | include: path.join(__dirname, 'assets'), 17 | loaders: [ 'babel', 18 | { 19 | loader: 'react-svg', 20 | query: { 21 | svgo: { 22 | plugins: [{removeTitle: false}], 23 | floatPrecision: 2 24 | } 25 | } 26 | } 27 | ] 28 | } 29 | ); 30 | return webpackConfig; 31 | }, 32 | }; --------------------------------------------------------------------------------