diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..e1a10eb --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +# Top-most EditorConfig File +root = true + +# Unix-style newlines with a newline ending every file +[*] +end_of_line = lf +trim_trailing_whitespace = true +insert_final_newline = true + +# 4 space tab indentation +indent_style = tab +indent_size = 4 diff --git a/.htaccess b/.htaccess index 36bf67a..884e82d 100644 --- a/.htaccess +++ b/.htaccess @@ -1,3 +1,3 @@ AddType text/cache-manifest .appcache -ExpiresByType text/cache-manifest "access plus 0 seconds" \ No newline at end of file +ExpiresByType text/cache-manifest "access plus 0 seconds" diff --git a/calculator.appcache b/calculator.appcache index 9473f78..1dde63f 100644 --- a/calculator.appcache +++ b/calculator.appcache @@ -1,5 +1,5 @@ CACHE MANIFEST -# v3.2.2: 2015-12-20 +# v3.3: 2016-05-03 index.html js/script.js css/style.css diff --git a/css/style.css b/css/style.css index c55ce5d..bdbe7fe 100644 --- a/css/style.css +++ b/css/style.css @@ -1,350 +1,183 @@ -html, -body, -div, -span, -ul, -li { - margin: 0; - padding: 0; - border: 0; - font-size: 100%; - font: inherit; - vertical-align: baseline; -} -button { - margin: 0; -} -* { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -body { - color: #000; - background: #fff; - font-family: -apple-system, "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 20px; - line-height: 24px; - font-weight: 200; - width: 100%; - margin: 0; - -webkit-touch-callout: none; - -webkit-user-select: none; - user-select: none; -} -.calculator { - position: relative; - overflow: hidden; -} -button { - color: #ffffff; - background: none; - font-family: -apple-system, "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 22px; - line-height: 20px; - font-weight: 300; - border: none; - width: 100%; - margin: 0; - padding: 0; - transition: color 0.2s ease, background-color 0.2s ease; -} -button.flash, -button:active { - color: #ffffff; - background-color: #099d93; -} -.result { - color: #444444; - background: #ffffff; - text-align: right; - font-size: 60px; - font-weight: 200; - border-bottom: 0.5px solid #d9d9d9; - width: 100%; - margin: 0; - padding: 0 12px; -} -.result > span { - position: relative; - top: 49%; - right: 12px; - margin-right: -12px; -} -.equation { - color: #099d93; - background: #ffffff; - text-align: right; - width: 100%; - margin-bottom: 0; - padding: 17px 12px 0; - white-space: nowrap; - overflow: hidden; -} -.equation .eq { - display: inline; -} -.equation .eq .operator, -.equation .eq .left-bracket, -.equation .eq .right-bracket { - color: #999999; - font-weight: 100; - margin: 0 5px; -} -.equation .eq .left-bracket { - margin-left: 0; -} -.equation .eq .right-bracket { - margin-right: 0; -} -.history { - position: absolute; - bottom: 0; - left: 0; - background-color: rgba(0, 0, 0, 0.6); - -webkit-backdrop-filter: blur(10px); - backdrop-filter: blur(10px); - width: 100%; - z-index: 90; - -webkit-transform: translateY(100%); - transform: translateY(100%); - -webkit-transition: transform 0.35s cubic-bezier(0.66, 0, 0.33, 1); - transition: transform 0.35s cubic-bezier(0.66, 0, 0.33, 1); -} -.history-titlebar { - position: relative; - color: #ffffff; - background-color: rgba(9, 157, 147, 0.3); - text-align: center; - font-family: -apple-system, "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 17px; - line-height: 22px; - font-weight: bold; - padding: 12px; -} -.history-close { - position: absolute; - top: 0; - right: 0; - text-align: right; - font-size: 22px; - font-weight: 100; - width: 48px; - height: 46px; - padding: 9px 12px 0; -} -.history-list-scroll { - height: calc(100% - 52px); - overflow-y: scroll; - -webkit-overflow-scrolling: touch; -} -.history-list { - list-style: none; -} -.history-list button { - color: #ffffff; - background-color: transparent; - text-align: left; - padding: 10px 12px; -} -.history-list button:active { - color: #ffffff; - background-color: #099d93; -} -.history-list .equ { - float: right; - color: #aaaaaa; - font-size: 13px; - line-height: 20px; - max-width: 100%; - padding: 3px 0 0 5px; - white-space: nowrap; - text-align: right; - text-overflow: ellipsis; - overflow: hidden; -} -.history-list .equ span { - margin: 0 3px; -} -.history--open .history { - -webkit-transform: translateY(0); - transform: translateY(0); -} -.keypad { - position: absolute; - bottom: 0; - width: 100%; - background: #333333; - border-top: 6px solid #099d93; -} -.keypad button { - float: left; - border: 0.5px solid #000000; - width: 25%; -} -.keypad button.btn-history, -.keypad button.btn-equals { - width: 50%; -} -.keypad button.active { - color: #099d93; - border: 1.5px solid #000000; -} -.btn-clear { - color: #ff0f0f; - background-color: #262626; -} -.btn-history { - color: #bbbbbb; - background-color: #262626; - font-size: 18px; -} -.btn-backspace { - color: #ffffff; - background-color: #262626; - background-image: url("../assets/backspace-icon.svg"); - background-repeat: no-repeat; - background-position: center center; - background-size: 25px 16px; -} -.btn-plus-minus { - color: #bbbbbb; - background-color: #333333; - letter-spacing: 2px; -} -.btn-bracket { - color: #bbbbbb; - background-color: #333333; -} -.btn-operator { - color: #099d93; - background-color: #333333; - font-size: 26px; -} -.btn-digit { - color: #ffffff; - background-color: #333333; -} -.btn-decimal { - color: #ffffff; - background-color: #333333; -} -.btn-equals { - color: #099d93; - background-color: #333333; - font-size: 26px; -} -@media (min-height: 460px) { - .calculator { - height: 460px; - } - .result { - height: 100px; - } - .keypad button { - height: 50px; - } - .history { - height: 300px; - } -} -@media (min-height: 548px) { - .calculator { - height: 548px; - } - .result { - height: 140px; - } - .keypad button { - height: 58px; - } - .history { - height: 348px; - } -} -@media (min-height: 647px) { - .calculator { - height: 647px; - } - .result { - height: 140px; - } - .keypad button { - height: 74px; - } - .history { - height: 444px; - } -} -@media (min-height: 716px) { - .calculator { - height: 716px; - } - .result { - height: 145px; - } - .keypad button { - height: 85px; - } - .history { - height: 510px; - } -} -.installation { - display: none; -} -.install { - background: #383838; - background-attachment: fixed; - height: 100%; -} -.install .calculator { - display: none; -} -.install .installation { - display: block; -} -.installation { - margin: 0 auto; - width: 175px; -} -.instructions { - position: absolute; - top: 50%; - color: #d9d9d9; - text-align: center; - font-size: 14px; - line-height: 20px; - text-shadow: 0 1px 2px #000; - width: 175px; - height: 180px; - margin-top: -90px; -} -.instructions span { - font-family: -apple-system, "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 16px; - font-weight: 800; -} -.app-icon { - background: url("../assets/app-icon-large.png") no-repeat; - background-size: 125px 125px; - width: 125px; - height: 125px; - margin: 0 auto 20px; -} -.twitter { - position: fixed; - bottom: 20px; - left: 50%; - color: #099d93; - text-align: center; - font-size: 14px; - line-height: 20px; - text-decoration: none; - text-shadow: 0 1px 2px #000; - width: 130px; - margin-left: -65px; -} -.twitter:hover { - color: #d9d9d9; -} +html, body, div, span, ul, li { margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline; } + +html { box-sizing: border-box; } + +*, *:before, *:after { box-sizing: inherit; } + +body { color: #333; background: #333; font-family: -apple-system, "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 20px; line-height: 1.2; font-weight: 200; -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; } + +button { font: inherit; font-weight: 300; border: none; margin: 0; padding: 0; -webkit-appearance: none; -moz-appearance: none; } + +.app { position: relative; } + +.installation { display: none; } + +.install { background: #333; background-attachment: fixed; height: 100%; } + +.install .app { display: none; } + +.install .installation { display: block; } + +.installation { margin: 0 auto; width: 175px; } + +.instructions { position: absolute; top: 50%; color: #d9d9d9; text-align: center; font-size: 0.7em; line-height: 20px; text-shadow: 0 1px 2px #000; width: 175px; height: 180px; margin-top: -90px; } + +.add-to-home-screen { font-size: 1.1em; font-weight: 800; } + +.app-icon { display: block; margin: 0 auto 20px; } + +.twitter-link { position: fixed; bottom: 20px; left: 50%; color: #099d93; font-size: 0.7em; line-height: 20px; text-decoration: none; text-shadow: 0 1px 2px #000; width: 130px; margin-left: -65px; } + +.twitter-link:hover { color: #d9d9d9; } + +.display { background-color: #fff; border-bottom: 6px solid #099d93; } + +.result, .equation { text-align: right; white-space: nowrap; padding-left: 12px; padding-right: 12px; overflow: hidden; } + +.result { font-size: 3em; font-weight: 200; } + +.equation { color: #099d93; border-top: 1px solid #d9d9d9; } + +@media (-webkit-min-device-pixel-ratio: 2) { .equation { border-width: 0.5px; } } + +.eq { display: inline; } + +.left-bracket, .right-bracket, .equation-operator { color: #999; font-weight: 100; margin: 0 0.2em; } + +.left-bracket { margin-left: 0; } + +.right-bracket { margin-right: 0; } + +.keypad-button { float: left; color: #fff; background: #333; font-family: -apple-system, "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 1.1em; border: 1px solid #000; width: 25%; transition: color 0.2s ease, background-color 0.2s ease; } + +@media (-webkit-min-device-pixel-ratio: 2) { .keypad-button { border-width: 0.5px; } } + +.keypad-button:active { background-color: #099d93; } + +.keypad-button--active { color: #099d93; border: 1.5px solid #000; } + +.keypad-button--wide { width: 50%; } + +.keypad-button--equals, .keypad-button--operator { color: #099d93; } + +.keypad-button--bracket, .keypad-button--plus-minus { color: #b3b3b3; } + +.keypad-button--clear, .keypad-button--history, .keypad-button--backspace { color: #b3b3b3; background-color: #262626; } + +.keypad-button--backspace { background-image: url("../assets/backspace-icon.svg"); background-repeat: no-repeat; background-position: center center; background-size: 25px 16px; } + +.keypad-button--clear { color: #ff0f0f; } + +.history-container { position: absolute; bottom: 0; left: 0; -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); width: 100%; z-index: 90; -webkit-transform: translateY(100%); transform: translateY(100%); -webkit-transition: transform 0.35s cubic-bezier(0.66, 0, 0.33, 1); transition: transform 0.35s cubic-bezier(0.66, 0, 0.33, 1); } + +.history-title-bar { position: relative; color: #fff; background-color: rgba(9, 157, 147, 0.3); text-align: center; font-size: 0.85em; font-weight: bold; line-height: 52px; height: 52px; } + +.history-close-button { position: absolute; right: 0; color: #d9d9d9; background-color: transparent; text-align: right; font-weight: 100; width: 52px; height: 52px; margin: 0; padding-right: 12px; } + +.history-list-scroll { height: calc(100% - 52px); overflow-y: scroll; -webkit-overflow-scrolling: touch; } + +.history-button { color: #d9d9d9; background-color: transparent; text-align: left; width: 100%; padding: 10px 12px; } + +.history-button:active { background-color: #099d93; } + +.history-button-equation { float: right; color: #b3b3b3; font-size: 0.7em; line-height: 20px; max-width: 100%; padding: 3px 0 0 5px; white-space: nowrap; text-align: right; text-overflow: ellipsis; overflow: hidden; } + +.history--open .history-container { -webkit-transform: translateY(0); transform: translateY(0); } + +/* iPhone4 - in-call */ +@media (min-height: 440px) { .app { height: 440px; } + .result { height: 110px; line-height: 108px; } + .equation { height: 36px; line-height: 34px; } + .keypad-button { height: 48px; } + .history-container { height: 288px; } } + +/* iPhone4 - default */ +@media (min-height: 460px) { .app { height: 460px; } + .result { height: 115px; line-height: 113px; } + .equation { height: 39px; line-height: 37px; } + .keypad-button { height: 50px; } + .history-container { height: 300px; } } + +/* iPhone5 - in-call */ +@media (min-height: 528px) { .app { height: 528px; } + .result { height: 132px; line-height: 130px; } + .equation { height: 42px; line-height: 40px; } + .keypad-button { height: 58px; } + .history-container { height: 348px; } } + +/* iPhone5 - default */ +@media (min-height: 548px) { .app { height: 548px; } + .result { height: 137px; line-height: 135px; } + .equation { height: 45px; line-height: 43px; } + .keypad-button { height: 60px; } + .history-container { height: 360px; } } + +/* iPhone6 - in-call */ +@media (min-height: 627px) { .app { height: 627px; } + .result { height: 157px; line-height: 155px; } + .equation { height: 56px; line-height: 54px; } + .keypad-button { height: 68px; } + .history-container { height: 408px; } } + +/* iPhone6 - default */ +@media (min-height: 647px) { .app { height: 647px; } + .result { height: 162px; line-height: 160px; } + .equation { height: 53px; line-height: 51px; } + .keypad-button { height: 71px; } + .history-container { height: 426px; } } + +/* iPhone6 Plus - in-call */ +@media (min-height: 696px) { .app { height: 696px; } + .result { height: 174px; line-height: 172px; } + .equation { height: 60px; line-height: 58px; } + .keypad-button { height: 76px; } + .history-container { height: 456px; } } + +/* iPhone6 Plus - default */ +@media (min-height: 716px) { .app { height: 716px; } + .result { height: 179px; line-height: 177px; } + .equation { height: 63px; line-height: 61px; } + .keypad-button { height: 78px; } + .history-container { height: 468px; } } + +/* iPad Portrait - in-call */ +@media (min-height: 728px) { .app { height: 728px; } + .result { height: 182px; line-height: 180px; } + .equation { height: 66px; line-height: 64px; } + .keypad-button { height: 79px; } + .history-container { height: 474px; } } + +/* iPad Portrait - default */ +@media (min-height: 748px) { .app { height: 748px; } + .result { height: 187px; line-height: 185px; } + .equation { height: 63px; line-height: 61px; } + .keypad-button { height: 82px; } + .history-container { height: 492px; } } + +/* iPad Landscape - in-call */ +@media (min-height: 984px) { .app { height: 984px; } + .result { height: 246px; line-height: 244px; } + .equation { height: 90px; line-height: 88px; } + .keypad-button { height: 107px; } + .history-container { height: 642px; } } + +/* iPad Landscape - default */ +@media (min-height: 1004px) { .app { height: 1004px; } + .result { height: 251px; line-height: 249px; } + .equation { height: 93px; line-height: 91px; } + .keypad-button { height: 109px; } + .history-container { height: 654px; } } + +/* iPad Pro Landscape - in-call */ +@media (min-height: 1326px) { .app { height: 1326px; } + .result { height: 332px; line-height: 330px; } + .equation { height: 124px; line-height: 122px; } + .keypad-button { height: 144px; } + .history-container { height: 864px; } } + +/* iPad Pro Landscape - default */ +@media (min-height: 1346px) { .app { height: 1346px; } + .result { height: 337px; line-height: 335px; } + .equation { height: 127px; line-height: 125px; } + .keypad-button { height: 146px; } + .history-container { height: 876px; } } diff --git a/css/style.less b/css/style.less deleted file mode 100644 index 0dcbf0f..0000000 --- a/css/style.less +++ /dev/null @@ -1,519 +0,0 @@ -// COLORS -// ------ - -// Status Bar -@statusBarBG: #262626; - -// Display -@resultTextColor: #444; -@resultBgColor: #fff; - -@equationTextColor: #099d93; -@equationOperatorColor: #999; -@equationBgColor: #fff; -@equationSeparatorRuleColor: #d9d9d9; - -@displayRuleColor: #e8e8e8; - -// Keypad -@keypadTextColor: #fff; -@keypadBgColor: #333; -@keypadBorderColor: #000; -@keypadActiveTextColor: #fff; -@keypadActiveBgColor: #099d93; -@keypadSeparatorRuleColor: #099d93; - -@activeTextColor: #099d93; -@activeBgColor: #000; - -@clearTextColor: #ff0f0f; -@clearBgColor: #262626; -@historyTextColor: #bbb; -@historyBgColor: #262626; -@backspaceTextColor: #fff; -@backspaceBgColor: #262626; -@bracketTextColor: #bbb; -@bracketBgColor: #333; -@plusminusTextColor: #bbb; -@plusminusBgColor: #333; -@operatorTextColor: #099d93; -@operatorBgColor: #333; -@digitTextColor: #fff; -@digitBgColor: #333; -@decimalTextColor: #fff; -@decimalBgColor: #333; -@equalsTextColor: #099d93; -@equalsBgColor: #333; - -// History -@historyTitlebarTextColor: #fff; -@historyTitlebarBgColor: rgba(9, 157, 147, 0.3); - -@historyListTextColor: #fff; -@historyListEquationColor: #aaa; -@historyListBgColor: rgba(0, 0, 0, 0.6); -@historyListBorderColor: #000; -@historyActiveTextColor: #fff; -@historyActiveBgColor: #099d93; - -@borderWidth: 0.5px; - - - -// RESET -// ---------------------------------- - -html, body, div, span, ul, li { - margin: 0; - padding: 0; - border: 0; - font-size: 100%; - font: inherit; - vertical-align: baseline; -} - -button { - margin: 0; -} - - - -// LAYOUT -// ---------------------------------- - -* { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -body { - color: #000; - background: #fff; - font-family: -apple-system, "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 20px; - line-height: 24px; - font-weight: 200; - width: 100%; - margin: 0; - -webkit-touch-callout: none; - -webkit-user-select: none; - user-select: none; -} - -.calculator { - position: relative; - overflow: hidden; -} - -button { - color: @keypadTextColor; - background: none; - font-family: -apple-system, "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 22px; - line-height: 20px; - font-weight: 300; - border: none; - width: 100%; - margin: 0; - padding: 0; - transition: color 0.2s ease, background-color 0.2s ease; - - &.flash, - &:active { - color: @keypadActiveTextColor; - background-color: @keypadActiveBgColor; - } -} - - - -// DISPLAY -// ---------------------------------- - -.result { - color: @resultTextColor; - background: @resultBgColor; - text-align: right; - font-size: 60px; // Must be updated in JS settings as well - font-weight: 200; - border-bottom: @borderWidth solid @equationSeparatorRuleColor; - width: 100%; - margin: 0; - padding: 0 12px; - - > span { - position: relative; - top: 49%; - right: 12px; - margin-right: -12px; - } -} - -.equation { - color: @equationTextColor; - background: @equationBgColor; - text-align: right; - width: 100%; - margin-bottom: 0; - padding: 17px 12px 0; - white-space: nowrap; - overflow: hidden; - - .eq { - display: inline; - - .operator, - .left-bracket, - .right-bracket { - color: @equationOperatorColor; - font-weight: 100; - margin: 0 5px; - } - - .left-bracket { - margin-left: 0; - } - - .right-bracket { - margin-right: 0; - } - } -} - - - -// HISTORY -// ---------------------------------- - -.history { - position: absolute; - bottom: 0; - left: 0; - background-color: @historyListBgColor; - -webkit-backdrop-filter: blur(10px); - backdrop-filter: blur(10px); - width: 100%; - z-index: 90; - -webkit-transform: translateY(100%); - transform: translateY(100%); - -webkit-transition: transform 0.35s cubic-bezier(0.66, 0, 0.33, 1); - transition: transform 0.35s cubic-bezier(0.66, 0, 0.33, 1); -} - -.history-titlebar { - position: relative; - color: @historyTitlebarTextColor; - background-color: @historyTitlebarBgColor; - text-align: center; - font-family: -apple-system, "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 17px; - line-height: 22px; - font-weight: bold; - padding: 12px; -} - -.history-close { - position: absolute; - top: 0; - right: 0; - text-align: right; - font-size: 22px; - font-weight: 100; - width: 48px; - height: 46px; - padding: 9px 12px 0; -} - -.history-list-scroll { - height: ~"calc(100% - 52px)"; // 100% subtract titlebar and border thickness - overflow-y: scroll; - -webkit-overflow-scrolling: touch; -} - -.history-list { - list-style: none; - - button { - color: @historyListTextColor; - background-color: transparent; - text-align: left; - padding: 10px 12px; - - &:active { - color: @historyActiveTextColor; - background-color: @historyActiveBgColor; - } - } - - .equ { - float: right; - color: @historyListEquationColor; - font-size: 13px; - line-height: 20px; - max-width: 100%; - padding: 3px 0 0 5px; - white-space: nowrap; - text-align: right; - text-overflow: ellipsis; - overflow: hidden; - - span { - margin: 0 3px; - } - } -} - -.history--open { - .history { - -webkit-transform: translateY(0); - transform: translateY(0); - } -} - - - -// KEYPAD -// ---------------------------------- - -.keypad { - position: absolute; - bottom: 0; - width: 100%; - background: @keypadBgColor; - border-top: 6px solid @keypadSeparatorRuleColor; - - button { - float: left; - border: @borderWidth solid @keypadBorderColor; - width: 25%; - - &.btn-history, - &.btn-equals { - width: 50%; - } - - &.active { - color: @activeTextColor; - border: 1.5px solid @activeBgColor; - } - } -} - -.btn-clear { - color: @clearTextColor; - background-color: @clearBgColor; -} - -.btn-history { - color: @historyTextColor; - background-color: @historyBgColor; - font-size: 18px; -} - -.btn-backspace { - color: @backspaceTextColor; - background-color: @backspaceBgColor; - background-image: url("../assets/backspace-icon.svg"); - background-repeat: no-repeat; - background-position: center center; - background-size: 25px 16px; -} - -.btn-plus-minus { - color: @plusminusTextColor; - background-color: @plusminusBgColor; - letter-spacing: 2px; -} - -.btn-bracket { - color: @bracketTextColor; - background-color: @bracketBgColor; -} - -.btn-operator { - color: @operatorTextColor; - background-color: @operatorBgColor; - font-size: 26px; -} - -.btn-digit { - color: @digitTextColor; - background-color: @digitBgColor; -} - -.btn-decimal { - color: @decimalTextColor; - background-color: @decimalBgColor; -} - -.btn-equals { - color: @equalsTextColor; - background-color: @equalsBgColor; - font-size: 26px; -} - - - -// iPhone 4 and lower -// ---------------------------------- - -@media (min-height: 460px) { - .calculator { - height: 460px; - } - - .result { - height: 100px; - } - - .keypad button { - height: 50px; - } - - .history { - height: 300px; - } -} - - - -// iPhone 5, 5s & 5c -// ---------------------------------- - -@media (min-height: 548px) { - .calculator { - height: 548px; - } - - .result { - height: 140px; - } - - .keypad button { - height: 58px; - } - - .history { - height: 348px; - } -} - - - -// iPhone 6 -// ---------------------------------- - -@media (min-height: 647px) { - .calculator { - height: 647px; - } - - .result { - height: 140px; - } - - .keypad button { - height: 74px; - } - - .history { - height: 444px; - } -} - - - -// iPhone 6+ -// ---------------------------------- - -@media (min-height: 716px) { - .calculator { - height: 716px; - } - - .result { - height: 145px; - } - - .keypad button { - height: 85px; - } - - .history { - height: 510px; - } -} - - - -// INSTALL SCREEN -// ---------------------------------- - -.installation { - display: none; -} - -.install { - background: #383838; - background-attachment: fixed; - height: 100%; - - .calculator { - display: none; - } - - .installation { - display: block; - } -} - -.installation { - margin: 0 auto; - width: 175px; -} - -.instructions { - position: absolute; - top: 50%; - color: #d9d9d9; - text-align: center; - font-size: 14px; - line-height: 20px; - text-shadow: 0 1px 2px #000; - width: 175px; - height: 180px; - margin-top: -90px; - - span { - font-family: -apple-system, "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 16px; - font-weight: 800; - } -} - -.app-icon { - background: url("../assets/app-icon-large.png") no-repeat; - background-size: 125px 125px; - width: 125px; - height: 125px; - margin: 0 auto 20px; -} - -.twitter { - position: fixed; - bottom: 20px; - left: 50%; - color: @keypadActiveBgColor; - text-align: center; - font-size: 14px; - line-height: 20px; - text-decoration: none; - text-shadow: 0 1px 2px #000; - width: 130px; - margin-left: -65px; - - &:hover { - color: #d9d9d9; - } -} diff --git a/css/style.scss b/css/style.scss new file mode 100644 index 0000000..b735eb8 --- /dev/null +++ b/css/style.scss @@ -0,0 +1,395 @@ +// Screen Sizes +// ---------------------------------- + +$screenHeights: ( + // iPhones + "iPhone4": 480px, + "iPhone5": 568px, + "iPhone6": 667px, + "iPhone6 Plus": 736px, + // iPads + "iPad Portrait": 768px, + "iPad Landscape": 1024px, + "iPad Pro Landscape": 1366px +); + + + +// Global Variables +// ---------------------------------- + +$color-primary: #099d93; +$color-danger: #ff0f0f; + +$color-grey100: #fff; +$color-grey85: #d9d9d9; +$color-grey70: #b3b3b3; +$color-grey60: #999; +$color-grey20: #333; +$color-grey15: #262626; +$color-grey0: #000; + +$display-borderWidth: 6px; + +$fontStack: -apple-system, "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, sans-serif; + + + +// Reset +// ---------------------------------- + +html, body, div, span, ul, li { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} + +html { + box-sizing: border-box; +} + +*, *:before, *:after { + box-sizing: inherit; +} + + + +// Layout +// ---------------------------------- + +body { + color: $color-grey20; + background: $color-grey20; + font-family: $fontStack; + font-size: 20px; + line-height: 1.2; + font-weight: 200; + -webkit-touch-callout: none; + -webkit-user-select: none; + user-select: none; +} + +button { + font: inherit; + font-weight: 300; + border: none; + margin: 0; + padding: 0; + -webkit-appearance: none; + -moz-appearance: none; +} + +.app { + position: relative; +} + + + +// Installation Screen +// ---------------------------------- + +.installation { + display: none; +} + +.install { + background: $color-grey20; + background-attachment: fixed; + height: 100%; + + .app { + display: none; + } + + .installation { + display: block; + } +} + +.installation { + margin: 0 auto; + width: 175px; +} + +.instructions { + position: absolute; + top: 50%; + color: $color-grey85; + text-align: center; + font-size: 0.7em; + line-height: 20px; + text-shadow: 0 1px 2px $color-grey0; + width: 175px; + height: 180px; + margin-top: -90px; +} + +.add-to-home-screen { + font-size: 1.1em; + font-weight: 800; +} + +.app-icon { + display: block; + margin: 0 auto 20px; +} + +.twitter-link { + position: fixed; + bottom: 20px; + left: 50%; + color: $color-primary; + font-size: 0.7em; + line-height: 20px; + text-decoration: none; + text-shadow: 0 1px 2px $color-grey0; + width: 130px; + margin-left: -65px; + + &:hover { + color: $color-grey85; + } +} + + + +// Display +// ---------------------------------- + +.display { + background-color: $color-grey100; + border-bottom: $display-borderWidth solid $color-primary; +} + +.result, +.equation { + text-align: right; + white-space: nowrap; + padding-left: 12px; + padding-right: 12px; + overflow: hidden; +} + +.result { + font-size: 3em; + font-weight: 200; +} + +.equation { + color: $color-primary; + border-top: 1px solid $color-grey85; + + @media (-webkit-min-device-pixel-ratio: 2) { + border-width: 0.5px; + } +} + +.eq { + display: inline; +} + +.left-bracket, +.right-bracket, +.equation-operator { + color: $color-grey60; + font-weight: 100; + margin: 0 0.2em; +} + +.left-bracket { + margin-left: 0; +} + +.right-bracket { + margin-right: 0; +} + + + +// Kaypad +// ---------------------------------- + +// Keypad buttons +.keypad-button { + float: left; + color: $color-grey100; + background: $color-grey20; + font-family: $fontStack; + font-size: 1.1em; + border: 1px solid $color-grey0; + width: 25%; + transition: color 0.2s ease, background-color 0.2s ease; + + @media (-webkit-min-device-pixel-ratio: 2) { + border-width: 0.5px; + } + + &:active { + background-color: $color-primary; + } +} + +// Keypad button modifiers +.keypad-button--active { + color: $color-primary; + border: 1.5px solid $color-grey0; +} + +.keypad-button--wide { + width: 50%; +} + +.keypad-button--equals, +.keypad-button--operator { + color: $color-primary; +} + +.keypad-button--bracket, +.keypad-button--plus-minus { + color: $color-grey70; +} + +.keypad-button--clear, +.keypad-button--history, +.keypad-button--backspace { + color: $color-grey70; + background-color: $color-grey15; +} + +.keypad-button--backspace { + background-image: url("../assets/backspace-icon.svg"); + background-repeat: no-repeat; + background-position: center center; + background-size: 25px 16px; +} + +.keypad-button--clear { + color: $color-danger; +} + + + +// History +// ---------------------------------- + +.history-container { + position: absolute; + bottom: 0; + left: 0; + -webkit-backdrop-filter: blur(10px); + backdrop-filter: blur(10px); + width: 100%; + z-index: 90; + -webkit-transform: translateY(100%); + transform: translateY(100%); + -webkit-transition: transform 0.35s cubic-bezier(0.66, 0, 0.33, 1); + transition: transform 0.35s cubic-bezier(0.66, 0, 0.33, 1); +} + +.history-title-bar { + position: relative; + color: $color-grey100; + background-color: rgba($color-primary, 0.3); + text-align: center; + font-size: 0.85em; + font-weight: bold; + line-height: 52px; + height: 52px; +} + +.history-close-button { + position: absolute; + right: 0; + color: $color-grey85; + background-color: transparent; + text-align: right; + font-weight: 100; + width: 52px; + height: 52px; + margin: 0; + padding-right: 12px; +} + +.history-list-scroll { + height: calc(100% - 52px); + overflow-y: scroll; + -webkit-overflow-scrolling: touch; +} + +.history-button { + color: $color-grey85; + background-color: transparent; + text-align: left; + width: 100%; + padding: 10px 12px; + + &:active { + background-color: $color-primary; + } +} + +.history-button-equation { + float: right; + color: $color-grey70; + font-size: 0.7em; + line-height: 20px; + max-width: 100%; + padding: 3px 0 0 5px; + white-space: nowrap; + text-align: right; + text-overflow: ellipsis; + overflow: hidden; +} + +.history--open { + .history-container { + -webkit-transform: translateY(0); + transform: translateY(0); + } +} + + + +// Responsive Styles for Screen Sizes +// ---------------------------------- + +@each $phone, $screenHeight in $screenHeights { + $appHeights: ( + "in-call": $screenHeight - 40, + "default": $screenHeight - 20 + ); + + @each $status, $appHeight in $appHeights { + $buttonHeight: ceil(($appHeight * 0.65) / 6); + $resultHeight: ceil($appHeight * 0.25); + $equationHeight: ($appHeight - $resultHeight - $display-borderWidth - ($buttonHeight * 6)); + + /* #{$phone} - #{$status} */ + @media (min-height: $appHeight) { + .app { + height: $appHeight; + } + + .result { + height: $resultHeight; + line-height: ($resultHeight - 2); + } + + .equation { + height: $equationHeight; + line-height: ($equationHeight - 2); + } + + .keypad-button { + height: $buttonHeight; + } + + .history-container { + height: ($buttonHeight * 6); + } + } + } +} diff --git a/index.html b/index.html index d77e159..a60fcf1 100644 --- a/index.html +++ b/index.html @@ -4,18 +4,18 @@ Calculator - A calculator web app for iPhone - + - + - + - + @@ -23,49 +23,51 @@ -
-
-
History×
+
+
+
History×
    -
    0
    -
    +
    +
    0
    +
    +
    - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + +
    -
    - Add to Home Screen
    + Calculator icon + Add to Home Screen
    to install on the iPhone
    - +
    diff --git a/js/script.js b/js/script.js index aad2b6c..d919a53 100644 --- a/js/script.js +++ b/js/script.js @@ -69,20 +69,20 @@ function Calculator() { fontsize: 60, decimals: 2 }; - + this.appstate = { input: ['0'], brackets: 0, last: null }; - + this.history = []; - + this.timer = { timerlen: 750, timer: null }; - + this.calculator = document.getElementById('calculator'); this.result = document.getElementById('result'); this.equation = document.getElementById('equation'); @@ -90,14 +90,14 @@ function Calculator() { this.historyPanel = document.getElementById('history'); this.historyList = document.getElementById('history-list'); this.historyClose = document.getElementById('history-close'); - + this.dragging = false; this.addEventHandlers(); - + // Restore previous app state this.restoreAppState(); this.loadHistory(); - + this.updateDisplay(); } @@ -109,10 +109,10 @@ function Calculator() { Calculator.prototype.restoreAppState = function() { var json = localStorage.getItem('appState'), savedAppState; - + if (json !== null && json !== '') { savedAppState = JSON.parse(json); - + this.appstate.input = savedAppState.input; this.appstate.last = savedAppState.last; this.appstate.brackets = savedAppState.brackets; @@ -126,7 +126,7 @@ Calculator.prototype.restoreAppState = function() { */ Calculator.prototype.saveAppState = function() { var json = JSON.stringify(this.appstate); - + localStorage.setItem('appState', json); }; @@ -138,22 +138,22 @@ Calculator.prototype.saveAppState = function() { Calculator.prototype.addEventHandlers = function() { var buttonModeStart = 'mousedown', buttonModeEnd = 'mouseup'; - + if (window.navigator.hasOwnProperty('standalone') && window.navigator.standalone) { buttonModeStart = 'touchstart'; buttonModeEnd = 'touchend'; } - + // Disable bounce scrolling on main application document.getElementById('application').addEventListener(buttonModeStart, function(e) { e.preventDefault(); e.stopPropagation(); }, false); - + // Fix bounce scrolling of whole page at top and bottom of content document.getElementById('history-list-scroll').addEventListener('touchstart', function(e) { var startTopScroll = this.scrollTop; - + if (document.getElementById('history-list').offsetHeight <= this.offsetHeight) { e.preventDefault(); e.stopPropagation(); @@ -162,46 +162,46 @@ Calculator.prototype.addEventHandlers = function() { if (startTopScroll <= 0) { this.scrollTop = 1; } - + if (startTopScroll + this.offsetHeight >= this.scrollHeight) { this.scrollTop = this.scrollHeight - this.offsetHeight - 1; } } }, false); - + // Keypad events document.getElementById('btn-backspace').addEventListener(buttonModeStart, function() { this.addTimer(this.backspaceLongPress.bind(this)); }.bind(this), false); - + this.keypad.addEventListener(buttonModeEnd, function(event) { if (!this.dragging) { this.removeTimer(); this.buttonEvent(event.target.value); } }.bind(this), false); - + // History list events this.historyList.addEventListener(buttonModeStart, function() { this.dragging = false; }.bind(this), false); - + this.historyList.addEventListener('touchmove', function() { this.dragging = true; }.bind(this), false); - + this.historyList.addEventListener(buttonModeEnd, function(event) { if (!this.dragging) { this.appendHistoryItemToEquation(event.target.value); this.closeHistoryPanel(); } }.bind(this), false); - + // History close events this.historyClose.addEventListener(buttonModeStart, function() { this.addTimer(this.clearHistory.bind(this)); }.bind(this), false); - + this.historyClose.addEventListener(buttonModeEnd, function() { this.removeTimer(); this.closeHistoryPanel(); @@ -270,7 +270,7 @@ Calculator.prototype.buttonEvent = function(value) { */ Calculator.prototype.appendDigitToEquation = function(digit) { var lastInput = this.appstate.last; - + switch (lastInput) { case null: this.appstate.input = [digit]; @@ -304,7 +304,7 @@ Calculator.prototype.appendDigitToEquation = function(digit) { this.appstate.last = digit; break; } - + this.updateDisplay(); }; @@ -315,7 +315,7 @@ Calculator.prototype.appendDigitToEquation = function(digit) { */ Calculator.prototype.appendDecimalToEquation = function() { var lastInput = this.appstate.last; - + switch (lastInput) { case null: this.appstate.input = ['0.']; @@ -345,7 +345,7 @@ Calculator.prototype.appendDecimalToEquation = function() { this.appstate.last = '.'; break; } - + this.updateDisplay(); }; @@ -358,7 +358,7 @@ Calculator.prototype.appendDecimalToEquation = function() { */ Calculator.prototype.appendOperatorToEquation = function(operator) { var lastInput = this.appstate.last; - + switch (lastInput) { case null: case '0': @@ -383,7 +383,7 @@ Calculator.prototype.appendOperatorToEquation = function(operator) { this.appstate.last = operator; break; } - + this.updateDisplay(); }; @@ -396,7 +396,7 @@ Calculator.prototype.appendOperatorToEquation = function(operator) { */ Calculator.prototype.appendBracketToEquation = function(bracket) { var lastInput = this.appstate.last; - + if (bracket === '(') { switch (lastInput) { case null: @@ -452,7 +452,7 @@ Calculator.prototype.appendBracketToEquation = function(bracket) { break; } } - + this.updateDisplay(); }; @@ -463,10 +463,10 @@ Calculator.prototype.appendBracketToEquation = function(bracket) { */ Calculator.prototype.invertNumber = function() { var num; - + if (/[\d\.]/.test(this.appstate.last)) { num = this.appstate.input.last(); - + if (num.substr(0, 1) === '-') { this.appstate.input.replaceLast(num.substr(1, num.length)); } @@ -476,7 +476,7 @@ Calculator.prototype.invertNumber = function() { else if (this.isValidNum('-' + num)) { this.appstate.input.replaceLast('-' + num); } - + this.updateDisplay(); } }; @@ -489,7 +489,7 @@ Calculator.prototype.invertNumber = function() { */ Calculator.prototype.equate = function() { var result = this.compute(); - + if (result !== null) { this.addHistoryObj({ 'result': result, @@ -506,7 +506,7 @@ Calculator.prototype.equate = function() { */ Calculator.prototype.backspace = function() { var string; - + if (this.appstate.input.length <= 1 && this.appstate.input.last().length <= 1) { this.clearAll(); } @@ -549,10 +549,10 @@ Calculator.prototype.backspace = function() { this.appstate.input.pop(); break; } - + string = this.appstate.input.join(''); this.appstate.last = string.charAt(string.length - 1); - + this.updateDisplay(); } }; @@ -577,8 +577,8 @@ Calculator.prototype.backspaceLongPress = function() { */ Calculator.prototype.activateButton = function(id) { var btn = document.getElementById(id); - - btn.classList.add('active'); + + btn.classList.add('keypad-button--active'); }; @@ -589,7 +589,7 @@ Calculator.prototype.activateButton = function(id) { * @param btn string The DOM node to deactivate */ Calculator.prototype.deactivateButton = function(btn) { - btn.classList.remove('active'); + btn.classList.remove('keypad-button--active'); }; @@ -606,10 +606,10 @@ Calculator.prototype.clearAll = function(result) { else { this.appstate.input = ['0']; } - + this.appstate.brackets = 0; this.appstate.last = null; - + this.updateDisplay(); }; @@ -636,7 +636,7 @@ Calculator.prototype.isValidNum = function(num) { if (/^\-?(0|0(?!\.)|([1-9]{1}\d*)|\.(?!\.)\d*)(\.\d*){0,1}$/.test(num)) { return true; } - + return false; }; @@ -648,7 +648,7 @@ Calculator.prototype.isValidNum = function(num) { Calculator.prototype.updateDisplay = function() { var result = this.compute(), activeBtn = document.querySelector('.active'); - + // Update the result if (result !== null && !isNaN(result)) { if (result > 9E13) { @@ -659,12 +659,12 @@ Calculator.prototype.updateDisplay = function() { } this.resizeFont(); } - + // Show active operator if (activeBtn) { this.deactivateButton(activeBtn); } - + switch (this.appstate.last) { case '*': this.activateButton('btn-multiply'); @@ -679,9 +679,9 @@ Calculator.prototype.updateDisplay = function() { this.activateButton('btn-subtract'); break; } - + this.updateDisplayEquation(); - + this.saveAppState(); }; @@ -697,10 +697,10 @@ Calculator.prototype.updateDisplayEquation = function() { var ele = document.getElementById('eq'), equ = this.appstate.input.slice(), width; - + ele.innerHTML = this.replaceOperators(equ); width = ele.offsetWidth; - + while (width > this.equation.offsetWidth - 24) { equ.splice(0, 1); ele.innerHTML = '...' + this.replaceOperators(equ); @@ -718,20 +718,20 @@ Calculator.prototype.updateDisplayEquation = function() { */ Calculator.prototype.replaceOperators = function(equ) { var output = '', i; - + for (i = 0; i < equ.length; i += 1) { switch(equ[i]) { case '*': - output += '×'; + output += '×'; break; case '/': - output += '÷'; + output += '÷'; break; case '+': - output += '+'; + output += '+'; break; case '-': - output += ''; + output += ''; break; case '(': output += '('; @@ -743,7 +743,7 @@ Calculator.prototype.replaceOperators = function(equ) { output += equ[i]; } } - + return output; } @@ -755,9 +755,9 @@ Calculator.prototype.replaceOperators = function(equ) { */ Calculator.prototype.resizeFont = function() { var size = this.settings.fontsize; - + this.result.style.fontSize = size + 'px'; - + while (this.result.childNodes[0].offsetWidth > window.innerWidth - 24) { size -= 1; this.result.style.fontSize = size + 'px'; @@ -777,17 +777,17 @@ Calculator.prototype.addCommas = function(number) { regx = /(\d+)(\d{3})/, integer = parts[0], fraction = ''; - + // Add commas to integer part while (regx.test(integer)) { integer = integer.replace(regx, '$1' + ',' + '$2'); } - + // Add fractional part if (parts.length > 1) { fraction = '.' + parts[1]; } - + return integer + fraction; }; @@ -797,20 +797,20 @@ Calculator.prototype.addCommas = function(number) { * Compute an equation string * * @param equation string The equation string to compute - * return double The result of the computation, else null if it cannot be computed + * return double The result of the computation, else null if it cannot be computed */ Calculator.prototype.compute = function() { var equation = this.appstate.input.join(''), result, round = Math.pow(10, this.settings.decimals); - + try { result = eval(equation); } catch(err) { return null; } - + return Math.round(result * round) / round; }; @@ -854,7 +854,7 @@ Calculator.prototype.appendHistoryItemToEquation = function(value) { this.appstate.last = '1'; break; } - + this.updateDisplay(); }; @@ -869,14 +869,14 @@ Calculator.prototype.addHistoryObj = function(obj) { var last = this.history.first() || {result: null, equ: []}, currentLen = this.history.length, newLen = 0; - + if (this.replaceOperators(obj.equ) !== this.replaceOperators(last.equ)) { newLen = this.history.unshift(obj); - + if (newLen > this.settings.history) { this.history.splice(this.settings.history, newLen - currentLen); } - + this.flashButton('btn-history'); this.prependToHistoryList(obj); this.saveHistory(); @@ -896,16 +896,17 @@ Calculator.prototype.createHistoryElement = function(obj) { var li = document.createElement('li'), button = document.createElement('button'), span = document.createElement('span'); - + button.value = obj.result; + button.className = 'history-button'; button.innerText = this.addCommas(obj.result); - - span.className = 'equ'; + + span.className = 'history-button-equation'; span.innerHTML = this.replaceOperators(obj.equ); - + button.appendChild(span); li.appendChild(button); - + return li; }; @@ -919,7 +920,7 @@ Calculator.prototype.createHistoryElement = function(obj) { Calculator.prototype.prependToHistoryList = function(obj) { var children = this.historyList.childNodes, ele = this.createHistoryElement(obj); - + this.historyList.insertBefore(ele, children[0]); }; @@ -932,7 +933,7 @@ Calculator.prototype.prependToHistoryList = function(obj) { */ Calculator.prototype.appendToHistoryList = function(obj) { var ele = this.createHistoryElement(obj); - + this.historyList.appendChild(ele); }; @@ -943,7 +944,7 @@ Calculator.prototype.appendToHistoryList = function(obj) { */ Calculator.prototype.saveHistory = function() { var json; - + json = JSON.stringify(this.history); localStorage.setItem('history', json); }; @@ -957,14 +958,14 @@ Calculator.prototype.saveHistory = function() { Calculator.prototype.loadHistory = function() { var json = localStorage.getItem('history'), i; - + if (json !== null && json !== '') { this.history = JSON.parse(json); } else { this.history = []; } - + for (i = 0; i < this.history.length; i += 1) { this.appendToHistoryList(this.history[i]); } @@ -990,9 +991,9 @@ Calculator.prototype.clearHistory = function() { */ Calculator.prototype.flashButton = function(id) { var btn = document.getElementById(id); - + btn.classList.add('flash'); - + setTimeout(function() { btn.classList.remove('flash'); }, 200);