Compare commits

...

21 commits

Author SHA1 Message Date
dbroqua
ddf3223f58 Updated build command 2021-03-28 16:41:18 +02:00
dbroqua
ba536a3d78 Lint 2021-03-21 18:42:57 +01:00
dbroqua
4dc1d30012 Added eslintrc config 2019-06-25 14:58:57 +02:00
dbroqua
b5538ee287 Replaced npm with yarn 2019-06-25 14:58:35 +02:00
dbroqua
89a480fe55 Added lint 2019-06-25 14:58:08 +02:00
dbroqua
4fc4b14fe7 Added svg resistor 2018-08-18 21:31:06 +02:00
dbroqua
50e1eaa1ee Added Resistor code 2018-08-15 20:08:14 +02:00
dbroqua
3a812d985d Updated lint 2018-08-15 20:08:05 +02:00
dbroqua
5bacf24b97 Added Home readme 2018-08-15 18:40:32 +02:00
dbroqua
dd992ad37b Removed useless console.log() 2018-08-15 18:39:36 +02:00
dbroqua
113f1880f7 Updated navbar and renamed Leds to Resistor 2018-07-31 21:12:16 +02:00
dbroqua
3d861bab52 Removed commented code 2018-07-31 09:54:32 +02:00
dbroqua
14270e9dc6 Updated build task 2018-07-31 09:54:13 +02:00
dbroqua
39252eee22 Debug .gitlab-ci.yml 2018-07-31 08:22:43 +02:00
dbroqua
b7aa94ecce Add .gitlab-ci.yml 2018-07-31 08:20:52 +02:00
dbroqua
468249992a Updated logos 2018-07-30 19:33:17 +02:00
dbroqua
3d9d820f34 Added BV 2018-07-30 19:32:40 +02:00
dbroqua
10d3043218 Fixed typo for wheel 2018-07-30 08:18:41 +02:00
dbroqua
1fbb136f77 Added explain bloc for Wheels 2018-07-29 19:05:17 +02:00
dbroqua
4b4a5e9126 Fixed bug in canvas renderer 2018-07-29 18:06:55 +02:00
dbroqua
190bc1547f Added Wheel component
* Bug on second Wheel canvas
2018-07-29 10:26:45 +02:00
32 changed files with 14635 additions and 1 deletions

34
.eslintrc.json Normal file
View file

@ -0,0 +1,34 @@
{
"env": {
"browser": true,
"es6": true
},
"extends": [
"airbnb"
],
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 2018,
"sourceType": "module"
},
"plugins": [
"react"
],
"rules": {
"react/jsx-filename-extension": [
1,
{
"extensions": [
".js",
".jsx"
]
}
]
}
}

21
.gitignore vendored Normal file
View file

@ -0,0 +1,21 @@
# See https://help.github.com/ignore-files/ for more about ignoring files.
# dependencies
/node_modules
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

80
.gitlab-ci.yml Normal file
View file

@ -0,0 +1,80 @@
image: node:9.4.0
cache:
paths:
- node_modules/
- .yarn
before_script:
- apt-get update -qq && apt-get install
stages:
- build
- test
- staging
- production
Build:
stage: build
tags:
- node
before_script:
- yarn config set cache-folder .yarn
- yarn install
script:
- npm run build
Test:
stage: test
tags:
- node
before_script:
- yarn config set cache-folder .yarn
- yarn install
script:
# Installs Chrome
- wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
- echo 'deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main' | tee /etc/apt/sources.list.d/google-chrome.list
- apt-get update
- apt-get install google-chrome-stable -y
# Runs the tests.
- npm run test:karma-headless
Deploy to Staging:
stage: staging
tags:
- node
before_script:
# Generates to connect to the AWS unit the SSH key.
- mkdir -p ~/.ssh
- echo -e "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
# Sets the permission to 600 to prevent a problem with AWS
# that it's too unprotected.
- chmod 600 ~/.ssh/id_rsa
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
script:
- bash ./gitlab-deploy/.gitlab-deploy.staging.sh
environment:
name: staging
# Exposes a button that when clicked take you to the defined URL:
url: http://ec2-13-59-173-91.us-east-2.compute.amazonaws.com:3001
Deploy to Production:
stage: production
tags:
- node
before_script:
# Generates to connect to the AWS unit the SSH key.
- mkdir -p ~/.ssh
- echo -e "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
# Sets the permission to 600 to prevent a problem with AWS
# that it's too unprotected.
- chmod 600 ~/.ssh/id_rsa
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
script:
- bash ./gitlab-deploy/.gitlab-deploy.prod.sh
environment:
name: production
# Exposes a button that when clicked take you to the defined URL:
url: http://ec2-13-59-173-91.us-east-2.compute.amazonaws.com:81
when: manual

15
.gitlab-deploy.prod.sh Normal file
View file

@ -0,0 +1,15 @@
# !/bin/bash
# Get servers list:
set - f
# Variables from GitLab server:
# Note: They can't have spaces!!
string=$DEPLOY_SERVER
array=(${string//,/ })
# Iterate servers for deploy and pull last commit
# Careful with the ; https://stackoverflow.com/a/20666248/1057052
for i in "${!array[@]}"; do
echo "Deploy project on server ${array[i]}"
ssh ubuntu@${array[i]} "cd ./Pardo/vr && git stash && git checkout $CI_BUILD_REF_NAME && git stash && git pull origin master && sudo yarn install && sudo npm run production"
done

15
.gitlab-deploy.staging.sh Normal file
View file

@ -0,0 +1,15 @@
# !/bin/bash
# Get servers list:
set - f
# Variables from GitLab server:
# Note: They can't have spaces!!
string=$DEPLOY_SERVER
array=(${string//,/ })
# Iterate servers for deploy and pull last commit
# Careful with the ; https://stackoverflow.com/a/20666248/1057052
for i in "${!array[@]}"; do
echo "Deploy project on server ${array[i]}"
ssh ubuntu@${array[i]} "cd ./Staging/vr && git stash && git checkout $CI_BUILD_REF_NAME && git stash && git pull && sudo yarn install && sudo npm run staging"
done

View file

@ -1,3 +1,19 @@
# car-tools # car-tools
Quelques outils pour vous aider dans votre bricoles auto Quelques outils pour vous aider dans votre bricoles auto
## Outils
### Roues
Cet outils vous permet de calculer la différence entre vos roues d'origines et vos nouvelles roues (largeur, diamètre, erreur au compteur...)
### Boite de vitesse
Cet outils vous permet de calculer votre régime moteur en fonction de votre vitesse.
Il vous permet aussi de calculer l'étalage de votre nouvelle boite si vous décidez d'en monter une qui n'est pas celle d'origines
### Résistance
Cet outils vous permet de calculer la valeur de la résistance qu'il vous faudra en fonction de votre alimentation et la led choisie.

22
gulpfile.js Normal file
View file

@ -0,0 +1,22 @@
const gulp = require('gulp');
const eslint = require('gulp-eslint');
const srcDir = [
'src/*.js',
'src/**/*.js',
];
function checkSrc() {
return gulp.src(srcDir)
.pipe(eslint())
.pipe(eslint.format())
.pipe(eslint.failAfterError());
}
function watchEslint() {
gulp.watch(srcDir, checkSrc);
}
gulp.task('check:lint', checkSrc);
gulp.task('watch:lint', watchEslint);
gulp.task('default', gulp.parallel('watch:lint'));

32
package.json Normal file
View file

@ -0,0 +1,32 @@
{
"name": "car-tools",
"version": "0.1.0",
"private": true,
"homepage": "https://outils.darkou.fr/",
"dependencies": {
"bootstrap": "^4.1.3",
"proptypes": "^1.1.0",
"react": "^16.4.1",
"react-dom": "^16.4.1",
"react-md-file": "^1.1.0",
"react-router-dom": "^4.3.1",
"react-scripts": "1.1.4",
"reactstrap": "^6.3.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
},
"devDependencies": {
"@svgr/cli": "^2.2.0",
"eslint": "^5.16.0",
"eslint-config-airbnb": "^17.1.0",
"eslint-plugin-import": "^2.18.0",
"eslint-plugin-jsx-a11y": "^6.2.1",
"eslint-plugin-react": "^7.14.2",
"gulp": "^4.0.2",
"gulp-eslint": "^5.0.0"
}
}

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

35
public/home.md Normal file
View file

@ -0,0 +1,35 @@
# Car tools
## Présentation
Comme son nom l'indique ce micro site est avant dédié au monde de la mécanique auto... mais pas que.
L'idée est de regrouper dans un seul endroits quelques outils pratiques quand on fait de la mécanique ou de l'électronique.
Des outils viendront s'ajouter avec le temps au fils de mes besoins mais aussi des votres, vous pouvez me contacter par [mail](https://www.darkou.fr/contact/).
## Outils disponibles
Voici la liste des outils actuellement disponibles sur ce mini site.
### Mécanique
#### Roues
Derrière ce nom très vaste ce cache un outils vous permettant de calculer les différences entre vous roues de références et vos futures roues.
Très utiles lorsque l'on change de jante ou de taille de pneus.
nouveau déport, nouveau diamètre, erreur au compteur... tout sera calculé !
#### Boîte de vitesse
Cet outils vous permettra de calculer le régime moteur en fonction du rapport engagé et de la vitesse au compteur.
Il vous permettra aussi de connaitre la différence de régime/vitesse entre 2 boites, dans le cas ou vous voudriez changer la votre par une avec des rapports plus longs, plus cours...
### Électronique
#### Résistance
Un outils qui me sers assez régulièrement quand je veux faire un montage à base de leds. En effet celui-ci vous permettra de calculer la résistance nécessaire dans l'idéal (mais également la résistance la plus proche dans la série standardisée) pour brancher votre Led sur votre circuit 12v (ou autre tension continue).

40
public/index.html Normal file
View file

@ -0,0 +1,40 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<!--
manifest.json provides metadata used when your web app is added to the
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>DarKou.fr :: outils</title>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

BIN
public/jante-face.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

BIN
public/jante-profil.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

15
public/manifest.json Normal file
View file

@ -0,0 +1,15 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
}
],
"start_url": "./index.html",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

186
public/resistor.svg Normal file
View file

@ -0,0 +1,186 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="157.39568mm"
height="32.996395mm"
viewBox="0 0 157.39568 32.996395"
version="1.1"
id="svg96"
inkscape:version="0.92.1 r15371"
sodipodi:docname="resistor.svg">
<defs
id="defs90" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.4"
inkscape:cx="253.98368"
inkscape:cy="39.858799"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
showguides="true"
inkscape:guide-bbox="true"
inkscape:window-width="1920"
inkscape:window-height="1007"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0">
<sodipodi:guide
position="-19.122808,16.498189"
orientation="0,1"
id="guide179"
inkscape:locked="false" />
<sodipodi:guide
position="78.697842,9.1482785"
orientation="1,0"
id="guide181"
inkscape:locked="false" />
<sodipodi:guide
position="25.110298,7.5446585"
orientation="0,1"
id="guide187"
inkscape:locked="false" />
<sodipodi:guide
position="54.145086,25.063019"
orientation="1,0"
id="guide266"
inkscape:locked="false" />
<sodipodi:guide
position="59.342262,19.393379"
orientation="1,0"
id="guide268"
inkscape:locked="false" />
<sodipodi:guide
position="67.004792,17.901349"
orientation="1,0"
id="guide272"
inkscape:locked="false" />
<sodipodi:guide
position="80.268042,16.498199"
orientation="1,0"
id="guide274"
inkscape:locked="false" />
<sodipodi:guide
position="102.76227,16.498199"
orientation="1,0"
id="guide276"
inkscape:locked="false" />
</sodipodi:namedview>
<metadata
id="metadata93">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-43.845239,-23.254863)">
<g
id="g264">
<g
id="g230">
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 64.144686,39.753061 c 0,0 -0.133636,7.684008 2.873147,11.559418 3.006783,3.875407 5.746295,5.746292 10.623963,4.343127 4.87767,-1.403165 6.548104,-6.949014 12.828939,-6.949014 6.280832,0 32.072345,0 32.072345,0"
id="path189"
inkscape:connector-curvature="0" />
<g
id="g207">
<path
inkscape:connector-curvature="0"
id="path189-3"
d="m 64.144686,39.753061 c 0,0 -0.133636,-7.684008 2.873147,-11.559418 3.006783,-3.875406 5.746295,-5.746292 10.623963,-4.343127 4.87767,1.403166 6.548104,6.949014 12.828938,6.949014 6.280833,0 32.072346,0 32.072346,0"
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
</g>
<g
id="g230-5"
transform="matrix(-1,0,0,1,245.08616,0)">
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 64.144686,39.753061 c 0,0 -0.133636,7.684008 2.873147,11.559418 3.006783,3.875407 5.746295,5.746292 10.623963,4.343127 4.87767,-1.403165 6.548104,-6.949014 12.828939,-6.949014 6.280832,0 32.072345,0 32.072345,0"
id="path189-35"
inkscape:connector-curvature="0" />
<g
id="g207-6">
<path
inkscape:connector-curvature="0"
id="path189-3-2"
d="m 64.144686,39.753061 c 0,0 -0.133636,-7.684008 2.873147,-11.559418 3.006783,-3.875406 5.746295,-5.746292 10.623963,-4.343127 4.87767,1.403166 6.548104,6.949014 12.828938,6.949014 6.280833,0 32.072346,0 32.072346,0"
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
</g>
</g>
<rect
id="rect270"
width="5.197175"
height="17.919262"
x="97.990326"
y="30.787331"
style="fill:#ff0000;fill-opacity:1;stroke:#000000;stroke-width:0.26759365;stroke-opacity:1"
inkscape:label="color-one"
label="color-one" />
<rect
id="rect270-9"
width="5.197175"
height="17.919262"
x="110.85003"
y="30.787329"
style="fill:#00ff00;fill-opacity:1;stroke:#000000;stroke-width:0.26759365;stroke-opacity:1"
inkscape:label="color-two"
label="color-two" />
<rect
id="rect270-9-2"
width="5.197175"
height="17.919262"
x="146.60751"
y="30.787329"
style="fill:#c0c0c0;fill-opacity:1;stroke:#000000;stroke-width:0.26759365;stroke-opacity:1"
inkscape:label="precision"
label="precision" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 64.144686,39.753061 H 43.845239"
id="path4790"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 201.24092,39.753061 H 180.94147"
id="path4790-7"
inkscape:connector-curvature="0" />
<rect
id="rect270-9-3"
width="5.197175"
height="17.919262"
x="124.11328"
y="30.787336"
style="fill:#0000ff;fill-opacity:1;stroke:#000000;stroke-width:0.26759365;stroke-opacity:1"
inkscape:label="factor"
label="color-two" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.5 KiB

50
src/App.css Normal file
View file

@ -0,0 +1,50 @@
.hidden {
display: none;
}
.clear{
clear: both;
}
.container {
margin-top: 16px;
}
.result {
margin-top: 16px;
}
.table>thead>tr>th,
.table-centered>tbody>tr>td{text-align:center}
figure{
padding:10px;
background:#fff;
border:1px solid #dadada;
text-align:center
}
figcaption{
margin-top:5px;
padding:5px;
background:#f4f4f4;
border:1px dotted #dadada;
text-align:center
}
.result>figure{
float:left
}
.table>thead>tr>th.error{
color:#ce4844
}
.table>thead>tr>th.ok{
color:#1b809e
}
.table>thead>tr>th.default{
color:#aa6708
}
.react-md {
padding: 1rem;
}

89
src/App.js Normal file
View file

@ -0,0 +1,89 @@
import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';
import {
Collapse,
Navbar,
NavbarToggler,
NavbarBrand,
Nav,
UncontrolledDropdown,
DropdownToggle,
DropdownMenu,
DropdownItem,
} from 'reactstrap';
import Home from './components/Home';
import Wheels from './components/Wheels';
import Gearbox from './components/Gearbox';
import Resistor from './components/Resistor';
import 'bootstrap/dist/css/bootstrap.min.css';
import './App.css';
class App extends Component {
constructor(props) {
super(props);
this.toggle = this.toggle.bind(this);
this.state = {
isOpen: false,
};
}
toggle() {
this.setState({
isOpen: !this.state.isOpen,
});
}
render() {
return (
<Router>
<div className="App">
<Navbar color="dark" dark expand="md">
<NavbarBrand href="/">Car tools</NavbarBrand>
<NavbarToggler onClick={this.toggle} />
<Collapse isOpen={this.state.isOpen} navbar>
<Nav className="ml-auto" navbar>
<UncontrolledDropdown nav inNavbar>
<DropdownToggle nav caret>
Mécanique
</DropdownToggle>
<DropdownMenu right>
<DropdownItem tag={Link} to="/Wheels">
Roues
</DropdownItem>
<DropdownItem tag={Link} to="/Gearbox">
Boîte de vitesse
</DropdownItem>
<DropdownItem tag={Link} to="/Spokes">
Calcul longueur rayons
</DropdownItem>
</DropdownMenu>
</UncontrolledDropdown>
<UncontrolledDropdown nav inNavbar>
<DropdownToggle nav caret>
Électronique
</DropdownToggle>
<DropdownMenu right>
<DropdownItem tag={Link} to="/Resistor">
Résistance
</DropdownItem>
</DropdownMenu>
</UncontrolledDropdown>
</Nav>
</Collapse>
</Navbar>
<div>
<Route exact path="/" component={Home} />
<Route exact path="/wheels" component={Wheels} />
<Route exact path="/Gearbox" component={Gearbox} />
<Route exact path="/Resistor" component={Resistor} />
<Route exact path="/Spokes" component={Wheels} />
</div>
</div>
</Router>
);
}
}
export default App;

9
src/App.test.js Normal file
View file

@ -0,0 +1,9 @@
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<App />, div);
ReactDOM.unmountComponentAtNode(div);
});

View file

@ -0,0 +1,397 @@
import React, { Component } from 'react';
import {
Container, Row, Col, Table, FormGroup, Input, Button, Label
} from 'reactstrap';
import Results from './results'
import 'bootstrap/dist/css/bootstrap.min.css';
import '../../App.css';
class Gearbox extends Component {
state = {};
constructor(props) {
super(props);
const sizes = [];
for (let i = 10; i <= 24; i += 1) {
sizes.push(i);
}
this.state = {
sizes,
showResult: false,
wheelDiameter: 14,
tyreWidth: 175,
tyreHeight: 65,
oldGearBoxOne: '11/37',
oldGearBoxSecond: '22/41',
oldGearBoxThird: '28/37',
oldGearBoxFourth: '34/35',
oldGearBoxFifth: '39/32',
oldGearBoxSixth: '',
oldGearBoxGate: '15/61',
oldGearBoxReverse: '11/39',
newGearBoxOne: '11/41',
newGearBoxSecond: '21/43',
newGearBoxThird: '28/37',
newGearBoxFourth: '30/29',
newGearBoxFifth: '39/31',
newGearBoxSixth: '',
newGearBoxGate: '14/63',
newGearBoxReverse: '11/39',
rpm: 2500,
speed: 90
};
this.handleChange = this.handleChange.bind(this);
this.submit = this.submit.bind(this);
}
handleChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value,
showResult: false
});
}
submit() {
this.setState({
showResult: true
})
}
render() {
return (
<Container>
<Row>
<Col xs="12">
<h1>Calculez vos rapports de boîte</h1>
</Col>
<Col xs="12">
<h2>Roue</h2>
</Col>
<Col xs="12">
<Table bordered>
<thead>
<tr>
<th>Diamètre</th>
<th>Largeur du pneu</th>
<th>Hauteur du flanc</th>
</tr>
</thead>
<tbody>
<tr>
<td className="align-middle col-xs-4">
<FormGroup>
<Input
type="select"
name="wheelDiameter"
value={this.state.wheelDiameter}
onChange={this.handleChange}>
{ this.state.sizes.map( item => (
<option value={item} key={`select_old_diametre_${item}`}>
{`${item}"`}
</option>
))}
</Input>
</FormGroup>
</td>
<td className="align-middle col-xs-4">
<FormGroup>
<Input
type="number"
name="tyreWidth"
step="5"
placeholder="Largeur du pneu"
value={this.state.tyreWidth}
onChange={this.handleChange}
/>
</FormGroup>
</td>
<td className="align-middle col-xs-4">
<FormGroup>
<Input
type="number"
name="tyreHeight"
step="5"
placeholder="Hauteur du pneu"
value={this.state.tyreHeight}
onChange={this.handleChange}
/>
</FormGroup>
</td>
</tr>
</tbody>
</Table>
</Col>
<Col xs="12">
<h2>Boîte de vitesse</h2>
</Col>
<Col xs="12">
<Table bordered>
<thead>
<tr>
<th></th>
<th>1<sup>ère</sup></th>
<th>2<sup>ère</sup></th>
<th>3<sup>ère</sup></th>
<th>4<sup>ère</sup></th>
<th>5<sup>ère</sup></th>
<th>6<sup>ère</sup></th>
<th>Pont</th>
<th>Marche arrière</th>
</tr>
</thead>
<tbody>
<tr>
<td className="align-middle">
Actuelle
</td>
<td className="align-middle col-xs-4">
<FormGroup>
<Input
type="text"
name="oldGearBoxOne"
value={this.state.oldGearBoxOne}
onChange={this.handleChange}
/>
</FormGroup>
</td>
<td className="align-middle col-xs-4">
<FormGroup>
<Input
type="text"
name="oldGearBoxSecond"
value={this.state.oldGearBoxSecond}
onChange={this.handleChange}
/>
</FormGroup>
</td>
<td className="align-middle col-xs-4">
<FormGroup>
<Input
type="text"
name="oldGearBoxThird"
value={this.state.oldGearBoxThird}
onChange={this.handleChange}
/>
</FormGroup>
</td>
<td className="align-middle col-xs-4">
<FormGroup>
<Input
type="text"
name="oldGearBoxFourth"
value={this.state.oldGearBoxFourth}
onChange={this.handleChange}
/>
</FormGroup>
</td>
<td className="align-middle col-xs-4">
<FormGroup>
<Input
type="text"
name="oldGearBoxFifth"
value={this.state.oldGearBoxFifth}
onChange={this.handleChange}
/>
</FormGroup>
</td>
<td className="align-middle col-xs-4">
<FormGroup>
<Input
type="text"
name="oldGearBoxSixth"
value={this.state.oldGearBoxSixth}
onChange={this.handleChange}
/>
</FormGroup>
</td>
<td className="align-middle col-xs-4">
<FormGroup>
<Input
type="text"
name="oldGearBoxGate"
value={this.state.oldGearBoxGate}
onChange={this.handleChange}
/>
</FormGroup>
</td>
<td className="align-middle col-xs-4">
<FormGroup>
<Input
type="text"
name="oldGearBoxReverse"
value={this.state.oldGearBoxReverse}
onChange={this.handleChange}
/>
</FormGroup>
</td>
</tr>
<tr>
<td className="align-middle">
Nouvelle
</td>
<td className="align-middle col-xs-4">
<FormGroup>
<Input
type="text"
name="newGearBoxOne"
value={this.state.newGearBoxOne}
onChange={this.handleChange}
/>
</FormGroup>
</td>
<td className="align-middle col-xs-4">
<FormGroup>
<Input
type="text"
name="newGearBoxSecond"
value={this.state.newGearBoxSecond}
onChange={this.handleChange}
/>
</FormGroup>
</td>
<td className="align-middle col-xs-4">
<FormGroup>
<Input
type="text"
name="newGearBoxThird"
value={this.state.newGearBoxThird}
onChange={this.handleChange}
/>
</FormGroup>
</td>
<td className="align-middle col-xs-4">
<FormGroup>
<Input
type="text"
name="newGearBoxFourth"
value={this.state.newGearBoxFourth}
onChange={this.handleChange}
/>
</FormGroup>
</td>
<td className="align-middle col-xs-4">
<FormGroup>
<Input
type="text"
name="newGearBoxFifth"
value={this.state.newGearBoxFifth}
onChange={this.handleChange}
/>
</FormGroup>
</td>
<td className="align-middle col-xs-4">
<FormGroup>
<Input
type="text"
name="newGearBoxSixth"
value={this.state.newGearBoxSixth}
onChange={this.handleChange}
/>
</FormGroup>
</td>
<td className="align-middle col-xs-4">
<FormGroup>
<Input
type="text"
name="newGearBoxGate"
value={this.state.newGearBoxGate}
onChange={this.handleChange}
/>
</FormGroup>
</td>
<td className="align-middle col-xs-4">
<FormGroup>
<Input
type="text"
name="newGearBoxReverse"
value={this.state.newGearBoxReverse}
onChange={this.handleChange}
/>
</FormGroup>
</td>
</tr>
</tbody>
</Table>
</Col>
<Col xs="12">
<h2>Bonus</h2>
</Col>
<Col xs="12">
<Row>
<Col xs="12" md="6">
<FormGroup>
<Label for="rpm">Afficher la vitesse pour le régime moteur suivant (tr/min) :</Label>
<Input
type="number"
id="rpm"
name="rpm"
step="50"
value={this.state.rpm}
onChange={this.handleChange}
/>
</FormGroup>
</Col>
<Col xs="12" md="6">
<FormGroup>
<Label for="speed">Afficher le régime moteur pour la vitesse suivante (km/h) :</Label>
<Input
type="number"
step="1"
id="speed"
name="speed"
value={this.state.speed}
onChange={this.handleChange}
/>
</FormGroup>
</Col>
</Row>
</Col>
<Col xs="12">
<Button onClick={this.submit}>Calculer</Button>
</Col>
</Row>
{
this.state.showResult ?
<Results
wheelDiameter={this.state.wheelDiameter}
tyreWidth={this.state.tyreWidth}
tyreHeight={this.state.tyreHeight}
oldGearBoxOne={this.state.oldGearBoxOne}
oldGearBoxSecond={this.state.oldGearBoxSecond}
oldGearBoxThird={this.state.oldGearBoxThird}
oldGearBoxFourth={this.state.oldGearBoxFourth}
oldGearBoxFifth={this.state.oldGearBoxFifth}
oldGearBoxSixth={this.state.oldGearBoxSixth}
oldGearBoxGate={this.state.oldGearBoxGate}
oldGearBoxReverse={this.state.oldGearBoxReverse}
newGearBoxOne={this.state.newGearBoxOne}
newGearBoxSecond={this.state.newGearBoxSecond}
newGearBoxThird={this.state.newGearBoxThird}
newGearBoxFourth={this.state.newGearBoxFourth}
newGearBoxFifth={this.state.newGearBoxFifth}
newGearBoxSixth={this.state.newGearBoxSixth}
newGearBoxGate={this.state.newGearBoxGate}
newGearBoxReverse={this.state.newGearBoxReverse}
rpm={this.state.rpm}
speed={this.state.speed}
/>
:
(null)
}
</Container>
)
}
}
export default Gearbox;

View file

@ -0,0 +1,484 @@
import React, { Component } from 'react';
import { Table, Row, Col } from 'reactstrap';
import { formatNumber } from '../../numbers';
class Results extends Component {
constructor(props) {
super(props);
this.state = {
wheelDiameter: this.props.wheelDiameter,
tyreWidth: this.props.tyreWidth,
tyreHeight: this.props.tyreHeight,
oldGearBoxOne: this.props.oldGearBoxOne,
oldGearBoxSecond: this.props.oldGearBoxSecond,
oldGearBoxThird: this.props.oldGearBoxThird,
oldGearBoxFourth: this.props.oldGearBoxFourth,
oldGearBoxFifth: this.props.oldGearBoxFifth,
oldGearBoxSixth: this.props.oldGearBoxSixth,
oldGearBoxGate: this.props.oldGearBoxGate,
oldGearBoxReverse: this.props.oldGearBoxReverse,
newGearBoxOne: this.props.newGearBoxOne,
newGearBoxSecond: this.props.newGearBoxSecond,
newGearBoxThird: this.props.newGearBoxThird,
newGearBoxFourth: this.props.newGearBoxFourth,
newGearBoxFifth: this.props.newGearBoxFifth,
newGearBoxSixth: this.props.newGearBoxSixth,
newGearBoxGate: this.props.newGearBoxGate,
newGearBoxReverse: this.props.newGearBoxReverse,
rpm: this.props.rpm,
speed: this.props.speed,
labels: {
1: 'One',
2: 'Second',
3: 'Third',
4: 'Fourth',
5: 'Fifth',
6: 'Sixth',
reverse: 'Reverse',
},
results: {
1000: {
1: {
old: 0,
new: 0,
},
2: {
old: 0,
new: 0,
},
3: {
old: 0,
new: 0,
},
4: {
old: 0,
new: 0,
},
5: {
old: 0,
new: 0,
},
6: {
old: 0,
new: 0,
},
reverse: {
old: 0,
new: 0,
},
},
2000: {
1: {
old: 0,
new: 0,
},
2: {
old: 0,
new: 0,
},
3: {
old: 0,
new: 0,
},
4: {
old: 0,
new: 0,
},
5: {
old: 0,
new: 0,
},
6: {
old: 0,
new: 0,
},
reverse: {
old: 0,
new: 0,
},
},
3000: {
1: {
old: 0,
new: 0,
},
2: {
old: 0,
new: 0,
},
3: {
old: 0,
new: 0,
},
4: {
old: 0,
new: 0,
},
5: {
old: 0,
new: 0,
},
6: {
old: 0,
new: 0,
},
reverse: {
old: 0,
new: 0,
},
},
4000: {
1: {
old: 0,
new: 0,
},
2: {
old: 0,
new: 0,
},
3: {
old: 0,
new: 0,
},
4: {
old: 0,
new: 0,
},
5: {
old: 0,
new: 0,
},
6: {
old: 0,
new: 0,
},
reverse: {
old: 0,
new: 0,
},
},
5000: {
1: {
old: 0,
new: 0,
},
2: {
old: 0,
new: 0,
},
3: {
old: 0,
new: 0,
},
4: {
old: 0,
new: 0,
},
5: {
old: 0,
new: 0,
},
6: {
old: 0,
new: 0,
},
reverse: {
old: 0,
new: 0,
},
},
6000: {
1: {
old: 0,
new: 0,
},
2: {
old: 0,
new: 0,
},
3: {
old: 0,
new: 0,
},
4: {
old: 0,
new: 0,
},
5: {
old: 0,
new: 0,
},
6: {
old: 0,
new: 0,
},
reverse: {
old: 0,
new: 0,
},
},
7000: {
1: {
old: 0,
new: 0,
},
2: {
old: 0,
new: 0,
},
3: {
old: 0,
new: 0,
},
4: {
old: 0,
new: 0,
},
5: {
old: 0,
new: 0,
},
6: {
old: 0,
new: 0,
},
reverse: {
old: 0,
new: 0,
},
},
rpm: {
1: {
old: 0,
new: 0,
},
2: {
old: 0,
new: 0,
},
3: {
old: 0,
new: 0,
},
4: {
old: 0,
new: 0,
},
5: {
old: 0,
new: 0,
},
6: {
old: 0,
new: 0,
},
reverse: {
old: 0,
new: 0,
},
},
speed: {
1: {
old: 0,
new: 0,
},
2: {
old: 0,
new: 0,
},
3: {
old: 0,
new: 0,
},
4: {
old: 0,
new: 0,
},
5: {
old: 0,
new: 0,
},
6: {
old: 0,
new: 0,
},
reverse: {
old: 0,
new: 0,
},
},
},
};
}
componentDidMount() {
const Pi = Math.PI;
const C = Pi * (Number(this.state.wheelDiameter.toString().replace('"', '')) * 25.4 + 2 * Number(this.state.tyreWidth) * Number(this.state.tyreHeight) / 100) / 1000;
const results = {};
Object.keys(this.state.results).map((rpm) => {
results[rpm] = {};
Object.keys(this.state.results[rpm]).map((gear) => {
results[rpm][gear] = {};
Object.keys(this.state.results[rpm][gear]).map((type) => {
let V = 0;
let f = 0;
let vitesseRoue = '-';
const currentRpm = rpm === 'rpm' ? this.state.rpm : rpm;
const rapportBoite = this.convertRapport(this.state[`${type}GearBox${this.state.labels[gear]}`]);
const rapportPont = this.convertRapport(this.state[`${type}GearBoxGate`]);
if (rapportBoite > 0 && rapportPont > 0) {
if (rpm !== 'speed') {
f = currentRpm * rapportBoite * rapportPont;
V = f * C * 60 / 1000;
vitesseRoue = `${formatNumber(V, 2, ',', ' ')}km/h`;
} else {
V = Number(this.state.speed);
f = V / (C * 60 / 1000);
const currentSpeedRpm = f / (rapportBoite * rapportPont);
vitesseRoue = `${formatNumber(currentSpeedRpm, 2, ',', ' ')}tr/min`;
}
}
results[rpm][gear][type] = vitesseRoue;
return true;
});
return true;
});
return true;
});
this.setState({ results });
}
convertRapport(value) {
if (value) {
const _rapport = value.split('/');
if (Number(value)) {
return value;
} if (_rapport.length === 2) {
return Number(_rapport[0]) / Number(_rapport[1]);
}
}
return -1;
}
render() {
return (
<Row className="result">
<Col xs="12">
<h2>
Résultat
</h2>
</Col>
<Col xs="12">
<Table bordered>
<thead>
<tr>
<th colSpan="2" />
<th>
1
<sup>
ère
</sup>
</th>
<th>
2
<sup>
ème
</sup>
</th>
<th>
3
<sup>
ème
</sup>
</th>
<th>
4
<sup>
ème
</sup>
</th>
<th>
5
<sup>
ème
</sup>
</th>
<th>
6
<sup>
ème
</sup>
</th>
<th>
Marche arrière
</th>
</tr>
</thead>
{Object.keys(this.state.results).map((tpm, index) => (
<tbody key={`rpm_${index}`}>
<tr>
<td className="align-middle" rowSpan="2">
{
tpm === 'speed'
? this.state.speed
: tpm === 'rpm'
? this.state.rpm
: tpm
}
{
tpm === 'speed'
? (
'km/h'
)
: (
'tr/min'
)
}
</td>
<td className="align-middle">
<strong>
Actuelle
</strong>
</td>
{Object.keys(this.state.results[tpm]).map((values, indexValues) => (
<td className="align-middle" key={`rpm_values_old_${index}_${indexValues}`}>
{this.state.results[tpm][values].old}
</td>
))}
</tr>
<tr>
<td className="align-middle">
<strong>
Nouvelle
</strong>
</td>
{Object.keys(this.state.results[tpm]).map((values, indexValues) => (
<td className="align-middle" key={`rpm_values_new_${index}_${indexValues}`}>
{this.state.results[tpm][values].new}
</td>
))}
</tr>
</tbody>
))}
</Table>
</Col>
</Row>
);
}
}
export default Results;

12
src/components/Home.js Normal file
View file

@ -0,0 +1,12 @@
import React, { Component } from 'react';
import ReactMd from 'react-md-file';
class Home extends Component {
render() {
return (
<ReactMd fileName="/home.md" />
);
}
}
export default Home;

View file

@ -0,0 +1,347 @@
import React, { Component } from 'react';
import {
Container,
Row,
Col,
FormGroup,
Label,
Input,
Button,
FormFeedback
} from 'reactstrap';
import Result from './result'
class Resistor extends Component {
state = {};
constructor(props) {
super(props);
this.state = {
powerSource: 12,
powerLed: 3.3,
ledConsumption: 20,
powerSourceError: false,
powerLedError: false,
ledConsumptionError: false,
showResult: false,
series: {
//Source: https://www.positron-libre.com/cours/electronique/resistances/serie-resistance.php
e24: [
1,
1.1,
1.2,
1.3,
1.5,
1.6,
1.8,
2.0,
2.2,
2.4,
2.7,
3.0,
3.30,
3.60,
3.90,
4.30,
4.70,
5.10,
5.60,
6.20,
6.80,
7.50,
8.20,
9.10
]
},
factors: [
{
factor: 0.01,
colorLabel: 'Argent',
color: '#ccc',
factorLabel: 'x0.01'
},
{
factor: 0.1,
colorLabel: 'or',
color: '#cd9932',
factorLabel: 'x0.1'
},
{
factor: 1,
colorLabel: 'noir',
color: '#000',
factorLabel: 'x1'
},
{
factor: 10,
colorLabel: 'marron',
color: '#663331',
factorLabel: 'x10'
},
{
factor: 100,
colorLabel: 'rouge',
color: '#fd0000',
factorLabel: 'x100'
},
{
factor: 1000,
colorLabel: 'orange',
color: '#ff6600',
factorLabel: 'x1 k'
},
{
factor: 10000,
colorLabel: 'jaune',
color: '#ffff00',
factorLabel: 'x10 k'
},
{
factor: 100000,
colorLabel: 'vert',
color: '#33cb33',
factorLabel: 'x100 k'
},
{
factor: 1000000,
colorLabel: 'bleu',
color: '#6666ff',
factorLabel: 'x1 M'
},
{
factor: 10000000,
colorLabel: 'violet',
color: '#cd66ff',
factorLabel: 'x10 M'
},
{
factor: 100000000,
colorLabel: 'gris',
color: '#939393',
factorLabel: 'x100 M'
},
{
factor: 1000000000,
colorLabel: 'blanc',
color: '#fff',
factorLabel: 'x1 G'
},
],
byColor: [
{
colorLabel: 'black',
color: '#000',
value: 0
},
{
colorLabel: 'brown',
color: '#663331',
value: 1
},
{
colorLabel: 'red',
color: '#fd0000',
value: 2
},
{
colorLabel: 'orange',
color: '#ff6600',
value: 3
},
{
colorLabel: 'yellow',
color: '#ffff00',
value: 4
},
{
colorLabel: 'green',
color: '#33cb33',
value: 5
},
{
colorLabel: 'blue',
color: '#6666ff',
value: 6
},
{
colorLabel: 'violet',
color: '#cd66ff',
value: 7
},
{
colorLabel: 'grey',
color: '#939393',
value: 8
},
{
colorLabel: 'white',
color: '#fff',
value: 9
},
]
}
this.handleChange = this.handleChange.bind(this);
this.checkForm = this.checkForm.bind(this);
this.submit = this.submit.bind(this);
}
handleChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value,
showResult: false
});
}
checkForm() {
let isOk = true;
let powerSourceError = false;
let powerLedError = false;
let ledConsumptionError = false;
if ( this.state.powerSource <= 0 )
{
powerSourceError = true;
}
if ( this.state.powerLed <= 0 || this.state.powerLed > this.state.powerSource )
{
powerLedError = true;
}
if ( this.state.ledConsumption <= 0 )
{
ledConsumptionError = true;
}
if ( powerSourceError === true
|| powerLedError === true
|| ledConsumptionError === true
){
isOk = false;
}
this.setState({
powerSourceError,
powerLedError,
ledConsumptionError
})
return isOk;
}
submit() {
let showResult = this.checkForm();
console.log(showResult);
this.setState({
showResult
})
}
render() {
return (
<Container>
<h1>Calcul de la valeur d&#39;une résistance</h1>
<Row>
<Col xs="12" md="6">
<Row>
<Col xs="12">
<FormGroup>
<Label for="powerSource">Alimentation</Label>
<Input
type="number"
id="powerSource"
name="powerSource"
placeholder="Alimentation (ex: 12V)"
step="0.1"
value={this.state.powerSource}
onChange={this.handleChange}
invalid={this.state.powerSourceError}
/>
{this.state.powerSourceError ?
(<FormFeedback>Vous devez saisir un nombre positif</FormFeedback>)
: (null)
}
</FormGroup>
</Col>
</Row>
<Row>
<Col xs="12">
<FormGroup>
<Label for="powerLed">Tension max admissible par la led</Label>
<Input
type="number"
id="powerLed"
name="powerLed"
placeholder="ex: 3.3V"
step="0.1"
value={this.state.powerLed}
onChange={this.handleChange}
invalid={this.state.powerLedError}
/>
{this.state.powerLedError ?
(<FormFeedback>Vous devez saisir un nombre positif et inférieur à votre alimentation</FormFeedback>)
: (null)
}
</FormGroup>
</Col>
</Row>
<Row>
<Col xs="12">
<FormGroup>
<Label for="ledConsumption">Consommation de la led (en mA)</Label>
<Input
type="number"
id="ledConsumption"
name="ledConsumption"
placeholder="20mA"
step="1"
value={this.state.ledConsumption}
onChange={this.handleChange}
invalid={this.state.ledConsumptionError}
/>
{this.state.ledConsumptionError ?
(<FormFeedback>Vous devez saisir un nombre positif</FormFeedback>)
: (null)
}
</FormGroup>
</Col>
</Row>
<Row>
<Col xs="12">
<Button onClick={this.submit}>Calculer</Button>
</Col>
</Row>
</Col>
<Col xs="12" md="6">
{
this.state.showResult ?
<Result
powerSource={this.state.powerSource}
powerLed={this.state.powerLed}
ledConsumption={this.state.ledConsumption}
series={this.state.series}
factors={this.state.factors}
colors={this.state.byColor}
/>
:
(null)
}
</Col>
</Row>
</Container>
);
}
}
export default Resistor

View file

@ -0,0 +1,50 @@
import React from 'react';
const Resistor = props => (
<svg viewBox="0 0 157.396 32.996" width="100%" height="100%" {...props}>
<path
d="M20.3 16.498s-.134 7.684 2.873 11.56c3.006 3.875 5.746 5.746 10.624 4.343 4.877-1.403 6.548-6.95 12.828-6.95h32.073M20.3 16.498s-.134-7.684 2.873-11.56C26.179 1.064 28.919-.807 33.797.597c4.877 1.403 6.548 6.949 12.828 6.949h32.073"
fill="none"
stroke="#000"
strokeWidth={0.265}
/>
<path
d="M137.096 16.498s.134 7.684-2.873 11.56c-3.007 3.875-5.746 5.746-10.624 4.343-4.878-1.403-6.548-6.95-12.829-6.95H78.698M137.096 16.498s.134-7.684-2.873-11.56C131.216 1.064 128.477-.807 123.6.597c-4.878 1.403-6.548 6.949-12.829 6.949H78.698"
fill="none"
stroke="#000"
strokeWidth={0.265}
/>
<path
fill={props.ringone}
stroke="#000"
strokeWidth={0.268}
d="M54.145 7.532h5.197v17.92h-5.197z"
/>
<path
fill={props.ringtwo}
stroke="#000"
strokeWidth={0.268}
d="M67.005 7.532h5.197v17.92h-5.197z"
/>
<path
fill={props.precision}
stroke="#000"
strokeWidth={0.268}
d="M102.763 7.532h5.197v17.92h-5.197z"
/>
<path
d="M20.3 16.498H0M157.396 16.498h-20.3"
fill="none"
stroke="#000"
strokeWidth={0.265}
/>
<path
fill={props.factor}
stroke="#000"
strokeWidth={0.268}
d="M80.268 7.532h5.197v17.92h-5.197z"
/>
</svg>
);
export default Resistor;

View file

@ -0,0 +1,177 @@
import React, { Component } from 'react';
import {
Row,
Col,
ListGroup,
ListGroupItem
} from 'reactstrap';
import Resistor from './resistor';
class Result extends Component {
state = {};
constructor(props) {
super(props);
this.state = {
series: this.props.series,
factors: this.props.factors,
powerSource: this.props.powerSource,
powerLed: this.props.powerLed,
ledConsumption: this.props.ledConsumption,
colors: this.props.colors,
perfectMatch: null,
// First resistor before the perfect value
underR: null,
underRColors: [
'red',
'red'
],
underRRingTwo: {
color: 'red'
},
underRFactor: null,
// First resistor after the perfect value
overR: null,
overRRingOne: {
color: 'red'
},
overRRingTwo: {
color: 'red'
},
overRFactor: null,
};
}
componentDidMount = () => {
const perfectMatch = Math.round( 1000 * ((this.state.powerSource - this.state.powerLed ) / ( this.props.ledConsumption/1000))) / 1000;
let overR = null;
let underR = null;
let underRFactor = null;
let overRFactor = null;
let underRColors = [];
let overRColors = [];
if ( perfectMatch > 0 )
{
for( let iFactor = 0 ; iFactor < this.state.factors.length ; iFactor += 1 ) {
const factorDetails = this.state.factors[iFactor];
const factor = factorDetails.factor;
for( let iSerie = 0 ; iSerie < this.state.series.e24.length ; iSerie += 1 ) {
const currentR = this.state.series.e24[iSerie] * factor;
if ( currentR >= perfectMatch ) {
overR = currentR;
overRFactor = factorDetails;
break;
}
underR = currentR;
}
underRFactor = factorDetails;
if ( overR)
{
break;
}
}
if ( overR === perfectMatch ){
underR = null;
overR = null;
underRFactor = null;
overRFactor = null;
}
}
// Extract colors from resistors
if ( underR ) {
for ( let i = 0 ; i < 2 ; i += 1) {
for ( let j = 0 ; j < this.state.colors.length ; j += 1) {
if ( this.state.colors[j].value === Number(underR.toString()[i]) ) {
underRColors[i] = this.state.colors[j].color;
break;
}
}
}
}
if ( overR ) {
for ( let i = 0 ; i < 2 ; i += 1) {
for ( let j = 0 ; j < this.state.colors.length ; j += 1) {
if ( this.state.colors[j].value === Number(overR.toString()[i]) ) {
overRColors[i] = this.state.colors[j].color;
break;
}
}
}
}
this.setState({
perfectMatch,
overR,
overRFactor,
underR,
underRFactor,
underRColors,
overRColors
});
}
render() {
return (
<Row>
<Col xs="12" md="12">
Vous devez mettre une résistance de <strong>{this.state.perfectMatch}&#8486;</strong>.
</Col>
{ this.state.overR ?
(
<Col xs="12">
Cette résistance n&#39;existant pas dans la série e24 vous pouvez opter pour l&#39;une des résistances suivante :
<ListGroup>
{this.state.underR ?
(
<ListGroupItem>
<Row>
<Col xs="12">
<strong>{this.state.underR}&#8486;</strong>
{' '}
({this.state.underR / this.state.underRFactor.factor} {this.state.underRFactor.factorLabel}&#8486;)
</Col>
<Col xs="12">
<Resistor ringone={this.state.underRColors[0]} ringtwo={this.state.underRColors[1]} factor={this.state.underRFactor.color} precision='#cd9932' />
</Col>
</Row>
</ListGroupItem>
)
: (null)
}
{this.state.overR ?
(
<ListGroupItem>
<Row>
<Col xs="12">
<strong>{this.state.overR}&#8486;</strong>
{' '}
({this.state.overR / this.state.overRFactor.factor} {this.state.overRFactor.factorLabel}&#8486;)
</Col>
<Col xs="12">
<Resistor ringone={this.state.overRColors[0]} ringtwo={this.state.overRColors[1]} factor={this.state.overRFactor.color} precision='#cd9932' />
</Col>
</Row>
</ListGroupItem>
)
: (null)
}
</ListGroup>
</Col>
) : (null)
}
</Row>
)
}
}
export default Result

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,252 @@
import React, { Component } from 'react';
import { Container, Row, Col, Table, FormGroup, Input, Button } from 'reactstrap';
import Result from "./results"
import Explain from "./explain"
import 'bootstrap/dist/css/bootstrap.min.css';
import '../../App.css';
class Wheels extends Component {
state = {};
constructor(props) {
super(props);
const sizes = [];
for (let i = 10; i <= 24; i += 1) {
sizes.push(i);
}
this.state = {
sizes,
showResult: false,
oldWheelDiameter: 14,
oldWheelWidth: 6.5,
oldWheelET: 37,
oldTyreWidth: 175,
oldTyreHeight: 65,
newWheelDiameter: 15,
newWheelWidth: 7,
newWheelET: 42,
newTyreWidth: 195,
newTyreHeight: 50,
};
this.handleChange = this.handleChange.bind(this);
this.submit = this.submit.bind(this);
}
handleChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value,
showResult: false
});
}
submit() {
this.setState({
showResult: true
})
}
render() {
return (
<Container>
<h1>
Calculez vos futures jantes et futurs pneus en ligne
</h1>
<Table bordered>
<thead>
<tr>
<th></th>
<th>Diamètre</th>
<th>Jante</th>
<th>Pneu</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Actuel</th>
<td>
<FormGroup>
<Input
type="select"
name="oldWheelDiameter"
value={this.state.oldWheelDiameter}
onChange={this.handleChange}>
{ this.state.sizes.map( item => (
<option value={item} key={`select_old_diametre_${item}`}>
{`${item}"`}
</option>
))}
</Input>
</FormGroup>
</td>
<td>
<Row>
<Col xs="12" md="6">
<FormGroup>
<Input
type="number"
name="oldWheelWidth"
placeholder="Largeur"
step="0.1"
value={this.state.oldWheelWidth}
onChange={this.handleChange}
/>
</FormGroup>
</Col>
<Col xs="12" md="6">
<FormGroup>
<Input
type="number"
name="oldWheelET"
placeholder="ET"
step="1"
value={this.state.oldWheelET}
onChange={this.handleChange}
/>
</FormGroup>
</Col>
</Row>
</td>
<td>
<Row>
<Col xs="12" md="6">
<FormGroup>
<Input
type="number"
name="oldTyreWidth"
placeholder="Largeur"
step="5"
value={this.state.oldTyreWidth}
onChange={this.handleChange}
/>
</FormGroup>
</Col>
<Col xs="12" md="6">
<FormGroup>
<Input
type="number"
name="oldTyreHeight"
placeholder="Hauteur"
step="5"
value={this.state.oldTyreHeight}
onChange={this.handleChange}
/>
</FormGroup>
</Col>
</Row>
</td>
</tr>
<tr>
<th scope="row">Nouveau</th>
<td>
<FormGroup>
<Input
type="select"
name="newWheelDiameter"
value={this.state.newWheelDiameter}
onChange={this.handleChange}>
{ this.state.sizes.map( item => (
<option value={item} key={`select_new_diametre_${item}`}>
{`${item}"`}
</option>
))}
</Input>
</FormGroup>
</td>
<td>
<Row>
<Col xs="12" md="6">
<FormGroup>
<Input
type="number"
name="newWheelWidth"
placeholder="Largeur"
step="0.1"
value={this.state.newWheelWidth}
onChange={this.handleChange}
/>
</FormGroup>
</Col>
<Col xs="12" md="6">
<FormGroup>
<Input
type="number"
name="newWheelET"
placeholder="ET"
step="1"
value={this.state.newWheelET}
onChange={this.handleChange}
/>
</FormGroup>
</Col>
</Row>
</td>
<td>
<Row>
<Col xs="12" md="6">
<FormGroup>
<Input
type="number"
name="newTyreWidth"
placeholder="Largeur"
step="5"
value={this.state.newTyreWidth}
onChange={this.handleChange}
/>
</FormGroup>
</Col>
<Col xs="12" md="6">
<FormGroup>
<Input
type="number"
name="newTyreHeight"
placeholder="Hauteur"
step="5"
value={this.state.newTyreHeight}
onChange={this.handleChange}
/>
</FormGroup>
</Col>
</Row>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colSpan="4">
<Button onClick={this.submit}>Calculer</Button>
</td>
</tr>
</tfoot>
</Table>
{
this.state.showResult ?
<Result
oldWheelDiameter={this.state.oldWheelDiameter}
oldWheelWidth={this.state.oldWheelWidth}
oldWheelET={this.state.oldWheelET}
oldTyreWidth={this.state.oldTyreWidth}
oldTyreHeight={this.state.oldTyreHeight}
newWheelDiameter={this.state.newWheelDiameter}
newWheelWidth={this.state.newWheelWidth}
newWheelET={this.state.newWheelET}
newTyreWidth={this.state.newTyreWidth}
newTyreHeight={this.state.newTyreHeight}
/>
:
(null)
}
<Explain />
</Container>
);
}
}
export default Wheels;

View file

@ -0,0 +1,561 @@
import React, { Component } from 'react';
import { formatNumber } from '../../numbers';
class Results extends Component {
state = {};
constructor(props) {
super(props);
this.state = {
oldWheelDiameter: this.props.oldWheelDiameter,
oldWheelWidth: this.props.oldWheelWidth,
oldWheelET: this.props.oldWheelET,
oldTyreWidth: this.props.oldTyreWidth,
oldTyreHeight: this.props.oldTyreHeight,
newWheelDiameter: this.props.newWheelDiameter,
newWheelWidth: this.props.newWheelWidth,
newWheelET: this.props.newWheelET,
newTyreWidth: this.props.newTyreWidth,
newTyreHeight: this.props.newTyreHeight,
diffET: null,
}
}
componentDidMount () {
// Rim
const _ETOld=(2.54*Number(this.state.oldWheelWidth)/2)+Number(this.state.oldWheelET)/10;
const _ETNew=(2.54*Number(this.state.newWheelWidth)/2)+Number(this.state.newWheelET)/10;
const _wayOld=(2.54*Number(this.state.oldTyreWidth)/2)-Number(this.state.oldWheelET)/10;
const _wayNew=(2.54*Number(this.state.newWheelWidth)/2)-Number(this.state.newWheelET)/10;
const diffET=(_ETNew-_ETOld)*10;
const diffWay=(_wayNew-_wayOld)*10;
// Tyres
const diamRimOld=Number(this.state.oldWheelDiameter)*2.54;
const tyreHOld=Number(this.state.oldTyreWidth)*(Number(this.state.oldTyreHeight))/1000;
const diamWheelOld=diamRimOld+2*Number(this.state.oldTyreWidth)*(Number(this.state.oldTyreHeight))/1000;
const diamRimNew=Number(this.state.newWheelDiameter)*2.54;
const tyreHNew=Number(this.state.newTyreWidth)*(Number(this.state.newTyreHeight))/1000;
const diamWheelNew=diamRimNew+2*Number(this.state.newTyreWidth)*(Number(this.state.newTyreHeight))/1000;
const diffDiam=diamWheelNew-diamWheelOld;
const diffRayon=diffDiam/2;
const tolerance=tyreHOld*0.03;
const limitDown=diamWheelOld*0.97;
const limitUp=diamWheelOld*1.03;
// Wheel
let libelleColA='';
let libelleColB='';
let libelleColC='';
let libelleColD='';
let diamColA=0;
let diamColB=0;
let diamColC=0;
let diamColD=0;
let clsColA='';
let clsColB='';
let clsColC='';
let clsColD='';
const horsTolerance="Diamètre hors tolérance";
const ToleranceBasse="Tolérance mini autorisée";
const ToleranceHaute="Tolérance maxi autorisée";
const DiametreOrigine="Diamètre origine";
const DiametreNew="Nouveau diamètre";
if(diamWheelNew<limitDown){
libelleColA=horsTolerance;
libelleColB=ToleranceBasse;
libelleColC=DiametreOrigine;
libelleColD=ToleranceHaute;
diamColA=diamWheelNew;
diamColB=limitDown;
diamColC=diamWheelOld;
diamColD=limitUp;
clsColA="error";
clsColC="default";
}else if(diamWheelNew>limitUp){
libelleColA=ToleranceBasse;
libelleColB=DiametreOrigine;
libelleColC=ToleranceHaute;
libelleColD=horsTolerance;
diamColA=limitDown;
diamColB=diamWheelOld;
diamColC=limitUp;
diamColD=diamWheelNew;
clsColD="error";
clsColB="default";
}else{
if(diamWheelNew<diamWheelOld){
libelleColA=ToleranceBasse;
libelleColB=DiametreNew;
libelleColC=DiametreOrigine;
libelleColD=ToleranceHaute;
diamColA=limitDown;
diamColB=diamWheelNew;
diamColC=diamWheelOld;
diamColD=limitUp;
clsColB="ok";
clsColC="default";
}else{
libelleColA=ToleranceBasse;
libelleColB=DiametreOrigine;
libelleColC=DiametreNew;
libelleColD=ToleranceHaute;
diamColA=limitDown;
diamColB=diamWheelOld;
diamColC=diamWheelNew;
diamColD=limitUp;
clsColB="default";
clsColC="ok";
}
}
// SPeed
const pi=Math.PI;
const speed=90;
const rayonOld=(diamWheelOld*10);
const rayonNew=(diamWheelNew*10);
const tpm=speed/(pi*rayonOld);
const vitesseNew=(pi*rayonNew*tpm);
// Set state
this.setState({
diffET: diffET,
diffWay: diffWay,
diffDiam: diffDiam,
diffRayon: diffRayon,
tolerance: tolerance,
limitDown: limitDown,
limitUp: limitUp,
libelleColA: libelleColA,
libelleColB: libelleColB,
libelleColC: libelleColC,
libelleColD: libelleColD,
diamColA: diamColA,
diamColB: diamColB,
diamColC: diamColC,
diamColD: diamColD,
clsColA: clsColA,
clsColB: clsColB,
clsColC: clsColC,
clsColD: clsColD,
speed: speed,
vitesseNew: vitesseNew
});
this.drawWheel(diamWheelOld,diamWheelNew,diamRimOld,diamRimNew);
this.drawET(diamRimOld,diamRimNew,tyreHOld,tyreHNew);
}
drawWheel(diamWheelOld,diamWheelNew,diamRimOld,diamRimNew){
let c = this.refs.roue_face;
var ctx=c.getContext("2d");
var scalling=2;
var YText=c.height-15;
var YArcOld=c.height-20-diamWheelOld*scalling;
var YArcNew=c.height-20-diamWheelNew*scalling;
var YTopWheelOld=c.height-20-diamWheelOld*scalling*2;
ctx.clearRect(0,0,c.width,c.height);
ctx.beginPath();
ctx.moveTo(0,0);
ctx.lineTo(0,c.height);
ctx.lineTo(c.width,c.height);
ctx.lineTo(c.width,0);
ctx.lineTo(0,0);
ctx.setLineDash([0]);
ctx.lineJoin="bevel";
ctx.lineCap="butt";
ctx.strokeStyle="black";
ctx.lineWidth=2;
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(0,c.height-20);
ctx.lineTo(c.width,c.height-20);
ctx.setLineDash([0]);
ctx.lineJoin="bevel";
ctx.lineCap="butt";
ctx.strokeStyle="black";
ctx.lineWidth=2;
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(0,YTopWheelOld);
ctx.lineTo(c.width,YTopWheelOld);
ctx.strokeStyle="red";
ctx.setLineDash([8,3]);
ctx.lineWidth=2;
ctx.stroke();
ctx.closePath();
ctx.beginPath();
var XAncien=diamWheelOld*scalling+20;
ctx.arc(XAncien,YArcOld,diamWheelOld*scalling,0,Math.PI*2,true);
ctx.setLineDash([0]);
ctx.strokeStyle="black";
ctx.fillStyle="black";
ctx.fill();ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.arc(XAncien,YArcOld,diamRimOld*scalling,0,Math.PI*2,true);
ctx.setLineDash([0]);
ctx.strokeStyle="white";
ctx.fillStyle="white";
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.font="10pt Verdana";
ctx.textAlign="center";
ctx.textBaseline="top";
ctx.fillStyle="#333";
ctx.fillText('Ancienne roue',XAncien,YText);
var imageAncienneWheel=new Image();
imageAncienneWheel.src='jante-face.png';
imageAncienneWheel.onload=function(){
var centreOldWheel=c.height-20-(diamWheelOld-diamRimOld)*scalling-diamRimOld*scalling*2;
ctx.drawImage(this,XAncien-diamRimOld*scalling,centreOldWheel,diamRimOld*scalling*2,diamRimOld*scalling*2);
};
ctx.beginPath();
var XNew=diamWheelOld*scalling*2+40+diamWheelNew*scalling;
ctx.arc(XNew,YArcNew,diamWheelNew*scalling,0,Math.PI*2,true);
ctx.setLineDash([0]);
ctx.strokeStyle="black";
ctx.fillStyle="black";
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.arc(XNew,YArcNew,diamRimNew*scalling,0,Math.PI*2,true);
ctx.setLineDash([0]);
ctx.strokeStyle="white";
ctx.fillStyle="white";
ctx.fill();
ctx.stroke();
ctx.closePath();
ctx.font="10pt Verdana";
ctx.textAlign="center";
ctx.textBaseline="top";
ctx.fillStyle="#333";
ctx.fillText('Nouvelle roue',XNew,YText);
var image=new Image();
image.src='jante-face.png';
image.onload=function(){
var centreNouvelleWheel=c.height-20-(diamWheelNew-diamRimNew)*scalling-diamRimNew*scalling*2;
ctx.drawImage(this,XNew-diamRimNew*scalling,centreNouvelleWheel,diamRimNew*scalling*2,diamRimNew*scalling*2);
};
}
drawET(diamRimOld,diamRimNew,tyreHOld,tyreHNew){
var c = this.refs.roue_profil;
var ctx=c.getContext("2d");
var scalling=5;
var YOld=c.height-50;
var YNew=c.height-50;
var XmoyeuOld=120;
var XmoyeuNew=395;
var actuel_jante_largeur=Number(this.state.oldWheelWidth);
var actuel_jante_ET=Number(this.state.oldWheelET);
var actuel_tyre_largeur=Number(this.state.oldTyreWidth);
var nouveau_jante_largeur=Number(this.state.newWheelWidth);
var nouveau_jante_ET=Number(this.state.newWheelET);
var nouveau_tyre_largeur=Number(this.state.newTyreWidth);
ctx.clearRect(0,0,c.width,c.height);
ctx.beginPath();
ctx.moveTo(0,0);
ctx.lineTo(0,c.height);
ctx.lineTo(c.width,c.height);
ctx.lineTo(c.width,0);
ctx.lineTo(0,0);
ctx.setLineDash([0]);
ctx.lineJoin="bevel";
ctx.lineCap="butt";
ctx.strokeStyle="black";
ctx.lineWidth=2;
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(20,0);
ctx.lineTo(20,c.height);
ctx.setLineDash([0]);
ctx.lineJoin="bevel";
ctx.lineCap="butt";
ctx.strokeStyle="black";
ctx.lineWidth=4;
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(20,YOld);
ctx.lineTo(XmoyeuOld,YOld);
ctx.setLineDash([0]);
ctx.lineJoin="bevel";
ctx.lineCap="butt";
ctx.strokeStyle="black";
ctx.lineWidth=16;
ctx.stroke();
ctx.closePath();
var largeurRimOld=scalling*(2.54*actuel_jante_largeur);
var rebordInterneOld=largeurRimOld/2+scalling*actuel_jante_ET/10;
var demiRimOld=scalling*diamRimOld/2;
ctx.beginPath();
ctx.moveTo(XmoyeuOld-rebordInterneOld,YOld-8);
ctx.lineTo(XmoyeuOld-rebordInterneOld,YOld-demiRimOld);
ctx.setLineDash([0]);
ctx.lineJoin="bevel";
ctx.lineCap="butt";
ctx.strokeStyle="#959595";
ctx.lineWidth=1;
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(XmoyeuOld-rebordInterneOld,YOld-demiRimOld);
ctx.lineTo(XmoyeuOld+largeurRimOld-rebordInterneOld,YOld-demiRimOld);
ctx.lineTo(XmoyeuOld+largeurRimOld-rebordInterneOld,YOld-demiRimOld+10);
ctx.lineTo(XmoyeuOld,YOld-10);
ctx.lineTo(XmoyeuOld,YOld+10);
ctx.setLineDash([0]);
ctx.lineJoin="bevel";
ctx.lineCap="butt";
ctx.strokeStyle="#959595";
ctx.lineWidth=6;
ctx.stroke();
ctx.closePath();
var largeurPneuOld=actuel_tyre_largeur/10;
var ETPneuOld=((2.54*actuel_jante_largeur)-largeurPneuOld)/2;
var Y=YOld;
if(tyreHOld>largeurPneuOld){
Y=Math.sqrt(ETPneuOld*ETPneuOld-tyreHOld*tyreHOld);
}else{
Y=Math.sqrt(tyreHOld*tyreHOld-ETPneuOld*ETPneuOld);
}
ctx.beginPath();
ctx.moveTo((XmoyeuOld-rebordInterneOld),YOld-demiRimOld);
ctx.lineTo((XmoyeuOld-rebordInterneOld+ETPneuOld*scalling),(YOld-demiRimOld-Y*scalling));
ctx.lineTo((XmoyeuOld-rebordInterneOld+ETPneuOld*scalling+largeurPneuOld*scalling),(YOld-demiRimOld-Y*scalling));
ctx.lineTo(XmoyeuOld+largeurRimOld-rebordInterneOld,YOld-demiRimOld);
ctx.setLineDash([0]);
ctx.lineJoin="round";
ctx.lineCap="round";
ctx.strokeStyle="#000";
ctx.lineWidth=6;
ctx.stroke();
ctx.closePath();
ctx.font="10pt Verdana";
ctx.textAlign="center";
ctx.textBaseline="top";
ctx.fillStyle="#333";
ctx.fillText('Ancienne roue',XmoyeuOld,c.height-15);
ctx.beginPath();
ctx.moveTo(XmoyeuOld-115,YOld);
ctx.lineTo(XmoyeuOld+15,YOld);
ctx.setLineDash([8,3,4,3]);
ctx.lineJoin="bevel";
ctx.lineCap="butt";
ctx.strokeStyle="red";
ctx.lineWidth=1;
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(c.width/2+20,0);
ctx.lineTo(c.width/2+20,c.height);
ctx.setLineDash([0]);
ctx.lineJoin="bevel";
ctx.lineCap="butt";
ctx.strokeStyle="black";
ctx.lineWidth=4;
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(c.width/2+20,YNew);
ctx.lineTo(XmoyeuNew,YNew);
ctx.setLineDash([0]);
ctx.lineJoin="bevel";
ctx.lineCap="butt";
ctx.strokeStyle="black";
ctx.lineWidth=16;
ctx.stroke();
ctx.closePath();
var largeurRimNew=scalling*(2.54*nouveau_jante_largeur);
var rebordInterneNew=largeurRimNew/2+scalling*nouveau_jante_ET/10;
var demiRimNew=scalling*diamRimNew/2;
ctx.beginPath();
ctx.moveTo(XmoyeuNew-rebordInterneNew,YNew-8);
ctx.lineTo(XmoyeuNew-rebordInterneNew,YNew-demiRimNew);
ctx.setLineDash([0]);
ctx.lineJoin="bevel";
ctx.lineCap="butt";
ctx.strokeStyle="#959595";
ctx.lineWidth=1;
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(XmoyeuNew-rebordInterneNew,YNew-demiRimNew);
ctx.lineTo(XmoyeuNew+largeurRimNew-rebordInterneNew,YNew-demiRimNew);
ctx.lineTo(XmoyeuNew+largeurRimNew-rebordInterneNew,YNew-demiRimNew+10);
ctx.lineTo(XmoyeuNew,YNew-10);
ctx.lineTo(XmoyeuNew,YNew+10);
ctx.setLineDash([0]);
ctx.lineJoin="bevel";
ctx.lineCap="butt";
ctx.strokeStyle="#959595";
ctx.lineWidth=6;
ctx.stroke();
ctx.closePath();
console.log("== Information nouvelle jante ==");
console.log("Largeur : "+(2.54*nouveau_jante_largeur));
console.log("ET : "+nouveau_jante_ET/10);
console.log("Position rebord interne : "+rebordInterneNew);
console.log("== END ==");
var largeurPneuNew=nouveau_tyre_largeur/10;
var ETPneuNew=((2.54*nouveau_jante_largeur)-largeurPneuNew)/2;Y=YNew;
if(tyreHNew>largeurPneuNew){
Y=Math.sqrt(ETPneuNew*ETPneuNew-tyreHNew*tyreHNew);
}else{
Y=Math.sqrt(tyreHNew*tyreHNew-ETPneuNew*ETPneuNew);
}
ctx.beginPath();
ctx.moveTo((XmoyeuNew-rebordInterneNew),YNew-demiRimNew);
ctx.lineTo((XmoyeuNew-rebordInterneNew+ETPneuNew*scalling),(YNew-demiRimNew-Y*scalling)); //ERR
ctx.lineTo((XmoyeuNew-rebordInterneNew+ETPneuNew*scalling+largeurPneuNew*scalling),(YNew-demiRimNew-Y*scalling)); //ERR
ctx.lineTo(XmoyeuNew+largeurRimNew-rebordInterneNew,YNew-demiRimNew); //ERR
ctx.setLineDash([0]);
ctx.lineJoin="round";
ctx.lineCap="round";
ctx.strokeStyle="#000";
ctx.lineWidth=6;
ctx.stroke();
ctx.closePath();
ctx.font="10pt Verdana";
ctx.textAlign="center";
ctx.textBaseline="top";
ctx.fillStyle="#333";
ctx.fillText('Nouvelle roue',XmoyeuNew,c.height-15);
ctx.beginPath();
ctx.moveTo(XmoyeuNew-115,YNew);
ctx.lineTo(XmoyeuNew+15,YNew);
ctx.setLineDash([8,3,4,3]);
ctx.lineJoin="bevel";
ctx.lineCap="butt";
ctx.strokeStyle="red";
ctx.lineWidth=1;
ctx.stroke();
ctx.closePath();
}
render() {
return (
<div>
<h1>Résultat</h1>
<h2>Jante</h2>
<p>
{ this.state.diffET > 0 ?
(
"Vos nouvelles jantes seront plus proches de votre pivot de " + formatNumber(this.state.diffET,2,',',' ') + " mm."
)
:
(
"Vos nouvelles jantes seront plus éloignées de votre pivot de " + formatNumber(this.state.diffET,2,',',' ') + " mm."
)
}
<br />
{
this.state.diffWay > 0 ?
(
"Vos nouvelles jantes ressortiront de " + formatNumber( this.state.diffWay, 2, ',', ' ' ) + " mm par rapport à l'origine."
)
:
(
"Vos nouvelles jantes rentreront de " + formatNumber(-(this.state.diffWay), 2, ',', ' ' ) + " mm par rapport à l'origine."
)
}
</p>
<h2>Pneu</h2>
<p>
{ this.state.diffDiam > 0 ?
(
<span>
{`Votre nouveau pneu aura un diamètre plus petit de ${formatNumber(- (this.state.diffDiam),2,',',' ')} cm.`}
<br />
{`Votre véhicule sera ainsi rabaissé de ${formatNumber(- (this.state.diffRayon),2,',',' ')} cm.`}
</span>
)
:
(
<span>
{`Votre nouveau pneu aura un diamètre plus grand de ${formatNumber( this.state.diffDiam,2,',',' ')} cm.`}
<br />
{`Votre véhicule sera ainsi réhaussé de ${formatNumber( this.state.diffRayon,2,',',' ')} cm.`}
</span>
)
}
<br />
<span className='glyphicon glyphicon-link' aria-hidden='true'></span>
<a href={`http://tyrestretch.com/${formatNumber(this.state.newWheelWidth,1,'.','')}-${this.state.newTyreWidth}-${this.state.newTyreHeight}-R${this.state.newWheelDiameter}/`} target='_blank'>Aperçu</a> (Il se peut qu'il n'y ai aucun aperçu pour cette dimension)
</p>
<h2>Vitesse</h2>
<p>
Quand votre compteur indique <strong>{this.state.speed} km/h</strong> vous roulez en réalité à <strong>{formatNumber(this.state.vitesseNew,2,',',' ')} km/h</strong>
</p>
<h2>Roue</h2>
<table className='table table-bordered table-condensed table-centered'>
<thead>
<tr>
<th className={this.state.clsColA}>{this.state.libelleColA}</th>
<th className={this.state.clsColB}>{this.state.libelleColB}</th>
<th className={this.state.clsColC}>{this.state.libelleColC}</th>
<th className={this.state.clsColD}>{this.state.libelleColD}</th>
</tr>
</thead>
<tbody>
<tr>
<td className='col-xs-3'>{formatNumber(this.state.diamColA,2,',',' ')}</td>
<td className='col-xs-3'>{formatNumber(this.state.diamColB,2,',',' ')}</td>
<td className='col-xs-3'>{formatNumber(this.state.diamColC,2,',',' ')}</td>
<td className='col-xs-3'>{formatNumber(this.state.diamColD,2,',',' ')}</td>
</tr>
</tbody>
</table>
<figure>
<canvas width="550" height="300" ref="roue_face">
Votre navigateur ne prends pas en charge la gestion des Canvas. Vous ne pourrez pas visualer le rendu de votre nouvelle roue.
</canvas>
<figcaption>Comparaison ancienne et nouvelle roue, vue de face</figcaption>
</figure>
<figure>
<canvas width="550" height="300" ref="roue_profil">
Votre navigateur ne prends pas en charge la gestion des Canvas. Vous ne pourrez pas visualer le rendu de votre nouvelle roue.
</canvas>
<figcaption>Comparaison ancienne et nouvelle roue, demie vue de profil</figcaption>
</figure>
</div>
);
}
}
export default Results;
/*
*/

5
src/index.css Normal file
View file

@ -0,0 +1,5 @@
body {
margin: 0;
padding: 0;
font-family: sans-serif;
}

8
src/index.js Normal file
View file

@ -0,0 +1,8 @@
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();

24
src/numbers.js Normal file
View file

@ -0,0 +1,24 @@
function toFixedFix (n,prec){
var k=Math.pow(10,prec);
return''+(Math.round(n*k)/k).toFixed(prec);
}
export function formatNumber (number,decimals,dec_point,thousands_sep){
number=(number+'').replace(/[^0-9+\-Ee.]/g,'');
const n=!isFinite(+number)?0:+number;
const prec=!isFinite(+decimals)?0:Math.abs(decimals);
const sep=(typeof thousands_sep==='undefined')?',':thousands_sep;
const dec=(typeof dec_point==='undefined')?'.':dec_point;
let s='';
s=(prec?toFixedFix(n,prec):''+Math.round(n)).split('.');
if(s[0].length>3){
s[0]=s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g,sep);
}
if((s[1]||'').length<prec){
s[1]=s[1]||'';
s[1]+=new Array(prec-s[1].length+1).join('0');
}
return s.join(dec);
};

View file

@ -0,0 +1,117 @@
// In production, we register a service worker to serve assets from local cache.
// This lets the app load faster on subsequent visits in production, and gives
// it offline capabilities. However, it also means that developers (and users)
// will only see deployed updates on the "N+1" visit to a page, since previously
// cached resources are updated in the background.
// To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
// This link also includes instructions on opting out of this behavior.
const isLocalhost = Boolean(
window.location.hostname === 'localhost' ||
// [::1] is the IPv6 localhost address.
window.location.hostname === '[::1]' ||
// 127.0.0.1/8 is considered localhost for IPv4.
window.location.hostname.match(
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
)
);
export default function register() {
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
// The URL constructor is available in all browsers that support SW.
const publicUrl = new URL(process.env.PUBLIC_URL, window.location);
if (publicUrl.origin !== window.location.origin) {
// Our service worker won't work if PUBLIC_URL is on a different origin
// from what our page is served on. This might happen if a CDN is used to
// serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374
return;
}
window.addEventListener('load', () => {
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
if (isLocalhost) {
// This is running on localhost. Lets check if a service worker still exists or not.
checkValidServiceWorker(swUrl);
// Add some additional logging to localhost, pointing developers to the
// service worker/PWA documentation.
navigator.serviceWorker.ready.then(() => {
console.log(
'This web app is being served cache-first by a service ' +
'worker. To learn more, visit https://goo.gl/SC7cgQ'
);
});
} else {
// Is not local host. Just register service worker
registerValidSW(swUrl);
}
});
}
}
function registerValidSW(swUrl) {
navigator.serviceWorker
.register(swUrl)
.then(registration => {
registration.onupdatefound = () => {
const installingWorker = registration.installing;
installingWorker.onstatechange = () => {
if (installingWorker.state === 'installed') {
if (navigator.serviceWorker.controller) {
// At this point, the old content will have been purged and
// the fresh content will have been added to the cache.
// It's the perfect time to display a "New content is
// available; please refresh." message in your web app.
console.log('New content is available; please refresh.');
} else {
// At this point, everything has been precached.
// It's the perfect time to display a
// "Content is cached for offline use." message.
console.log('Content is cached for offline use.');
}
}
};
};
})
.catch(error => {
console.error('Error during service worker registration:', error);
});
}
function checkValidServiceWorker(swUrl) {
// Check if the service worker can be found. If it can't reload the page.
fetch(swUrl)
.then(response => {
// Ensure service worker exists, and that we really are getting a JS file.
if (
response.status === 404 ||
response.headers.get('content-type').indexOf('javascript') === -1
) {
// No service worker found. Probably a different app. Reload the page.
navigator.serviceWorker.ready.then(registration => {
registration.unregister().then(() => {
window.location.reload();
});
});
} else {
// Service worker found. Proceed as normal.
registerValidSW(swUrl);
}
})
.catch(() => {
console.log(
'No internet connection found. App is running in offline mode.'
);
});
}
export function unregister() {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.ready.then(registration => {
registration.unregister();
});
}
}

10183
yarn.lock Normal file

File diff suppressed because it is too large Load diff