基于HarmonyOS系统 使用JS开发一个简单的仿苹果计算器 原创

我曾是少年_
发布于 2021-9-27 15:37
浏览
3收藏

先看效果图

基于HarmonyOS系统 使用JS开发一个简单的仿苹果计算器-鸿蒙开发者社区
基于HarmonyOS系统 使用JS开发一个简单的仿苹果计算器-鸿蒙开发者社区

众所周知鸿蒙JS框架是非常轻量级的MVVM模式。通过使用和Vue2相似的属性劫持技术实现了响应式系统;学习鸿蒙很长时间了,想写一个demo进行练练手,就选择开发这个仿苹果计算器程序。

话不多说,上代码:
hml

<div class="container">
    <div class="header">
        <text class="{{outputClassName}}">{{output}}</text>
    </div>
    <div class="keyboard">
        <block for="{{keyArr}}">
            <div if="{{$item == '0'}}" class="zeroKeys" onclick="onclickNubmer({{$item}})">
                <text>
                    {{$item}}
                </text>
            </div>
            <div elif="{{$item == 'AC' || $item == '+/-' || $item == '%'}}" class="operatorKeys-top" onclick="onclickOper({{$item}})">
                <text>
                    {{$item}}
                </text>
            </div>
            <div elif="{{$item == '÷' || $item == '×' || $item == '-' || $item == '+' || $item == '='}}" class="operatorKeys-right" onclick="onclickOper({{$item}})">
                <text>
                    {{$item}}
                </text>
            </div>
            <div else class="keys keys-nubmer" onclick="onclickNubmer({{$item}})">
                <text>
                    {{$item}}
                </text>
            </div>
        </block>
    </div>
</div>

css

.container {
    flex-direction: column;
    background-color: #010101;
    height:100%;
    width:100%;
}

.header{
    height:36%;
    width:100%;
    align-items: flex-end;
    padding:2px 20px 2px 10px;
}
.keyboard{
    height:64%;
    width:100%;
    padding:2px 10px;
    flex-wrap: wrap;
}
.outputText,.outputTextSmall{
    width:100%;
    height:100px;
    color:#FFFFFF;
    text-align: end;
}
.outputText{
    font-size:80px;
}
.outputTextSmall{
    font-size:58px;
}
.keys,.zeroKeys,.operatorKeys-top,.operatorKeys-right{
    width:74px;
    height:74px;
    justify-content: center;
    align-items: center;
    border-radius:74px;
    margin:10px 5px;
}
.keys-nubmer,.zeroKeys{
    background-color:#333333;
}
.zeroKeys{
    width:158px;
}
.operatorKeys-top{
    background-color: #a4a4a4;
}
.operatorKeys-right{
    background-color: #f79f31;
}
.keys:active,.zeroKeys:active{
    background-color: #737373;
}
.keys text,.zeroKeys text,.operatorKeys-right text{
    font-size:42px;
    color: #FFFFFF;
}
.operatorKeys-top text{
    font-size:36px;
    color: #010101;
}
.operatorKeys-top:active{
    background-color: #d9d9d9;
}
.operatorKeys-right:active{
    background-color: #f5c891;
}

js

import {math} from "../../common/js/utils.js";
export default {
  data: {
    output:"0",
    outputClassName:"outputText",
    cache:[],//记录输入内容
    keyArr:["AC","+/-","%","÷","7","8","9","×","4","5","6","-","1","2","3","+","0",".","="],
    reOper:"",//记录点击的运算符
    reStr1:"",//记录第一次输入内容
    reStr2:"",//记录点击运算符后的内容
    bool:false//防止第二次输入内容时内容清空
  },
  onInit(){
    this.$watch("output","watchOutPut")
  },
  onclickOper(item){
    if(item == "AC"){
      this.clearComput();
    } else if(item == "+" || item == "-" || item == "×" || item == "÷"){
      this.reOper = item;
      this.reStr1 = this.output;
      if(this.cache.length > 0){
        this.startCompute();
      }
      this.cache.push(this.reStr1);
    } else if(item == "+/-"){
      this.output = "-"+this.output;
    } else if(item == "%"){
      this.output = math.accDiv(this.output,100);
    } else if(item == "="){
      this.reStr2 = this.output;
      this.cache.push(this.reStr2);
      this.startCompute();
    }
  },
  onclickNubmer(item){
    if(this.cache.length > 0 && !this.bool){
      this.output = "0";
      this.bool = true;
    }
    if(this.output == "0" && item != "."){
      this.output = item;
    } else if(item == "."){
      if(this.output.indexOf(".") == -1){
        if(this.output == "0"){
          this.output = "0."
        } else {
          this.output += item;
        }
      }
    } else {
      if(this.output.length < 10){
        this.output += item;
      }
    }
  },
  watchOutPut(nVal){
    if(nVal.length > 7 && nVal.length< 10){
      this.outputClassName = "outputTextSmall";
    } else {
      this.outputClassName = "outputText";
    }
  },
  startCompute(){
    switch (this.reOper) {
      case "+":
        this.output = math.accAdd(this.reStr1,this.reStr2);
        this.reStr1 = this.output;
        break;
      case "-":
        this.output = math.accSub(this.reStr1,this.reStr2);
        this.reStr1 = this.output;
        break;
      case "×":
        this.output = math.accMul(this.reStr1,this.reStr2);
        this.reStr1 = this.output;
        break;
      case "÷":
        this.output = math.accDiv(this.reStr1,this.reStr2);
        this.reStr1 = this.output;
        break;
      default:
        break;
    }
  },
  clearComput(){
    this.output = "0";
    this.reOper = "";
    this.reStr1 = "";
    this.reStr2 = "";
    this.cache = [];
    this.bool = false;
  }
}

utils.js

class MathCalss {
  //js精准除法函数
  accDiv(arg1, arg2){
    let t1 = 0,
       t2 = 0,
       r1,
       r2;
     try {
       t1 = arg1.toString().split('.')[1].length;
     } catch (e) {}
     try {
       t2 = arg2.toString().split('.')[1].length;
     } catch (e) {}
     r1 = Number(arg1.toString().replace('.', ''));
     r2 = Number(arg2.toString().replace('.', ''));
     return (r1 / r2) * Math.pow(10, t2 - t1);
  }

  //js精准加法函数
  accAdd(arg1, arg2) {
    var r1, r2, m, c;
    try {
      r1 = arg1.toString().split(".")[1].length;
    }
    catch (e) {
      r1 = 0;
    }
    try {
      r2 = arg2.toString().split(".")[1].length;
    }
    catch (e) {
      r2 = 0;
    }
    c = Math.abs(r1 - r2);
    m = Math.pow(10, Math.max(r1, r2));
    if (c > 0) {
      var cm = Math.pow(10, c);
      if (r1 > r2) {
        arg1 = Number(arg1.toString().replace(".", ""));
        arg2 = Number(arg2.toString().replace(".", "")) * cm;
      } else {
        arg1 = Number(arg1.toString().replace(".", "")) * cm;
        arg2 = Number(arg2.toString().replace(".", ""));
      }
    } else {
      arg1 = Number(arg1.toString().replace(".", ""));
      arg2 = Number(arg2.toString().replace(".", ""));
    }
    return (arg1 + arg2) / m;
  }
  //js精准减法函数
  accSub(arg1, arg2) {
    let r1, r2, m, n;
    try {
      r1 = arg1.toString().split('.')[1].length;
    } catch (e) {
      r1 = 0;
    }
    try {
      r2 = arg2.toString().split('.')[1].length;
    } catch (e) {
      r2 = 0;
    }
    m = Math.pow(10, Math.max(r1, r2));
    //动态控制精度长度
    n = r1 >= r2 ? r1 : r2;
    return (arg1 * m - arg2 * m) / m;
  }
  //js精准乘法函数
  accMul(arg1, arg2) {
    var m = 0, s1 = arg1.toString(), s2 = arg2.toString();
    try {
      m += s1.split(".")[1].length;
    }
    catch (e) {
    }
    try {
      m += s2.split(".")[1].length;
    }
    catch (e) {
    }
    return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m);
  }
}

export var math = new MathCalss();

为了解决浮点数计算失准问题,我使用一些解决计算失准的函数可供大家参考。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
calculator.zip 93.83K 39次下载
7
收藏 3
回复
举报
1条回复
按时间正序
/
按时间倒序
mb609898e2cfb86
mb609898e2cfb86

感谢分享

已于2021-9-28 10:19:53修改
回复
2021-9-28 10:19:48
回复
    相关推荐