惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

阮一峰的网络日志
阮一峰的网络日志
P
Proofpoint News Feed
Hacker News: Ask HN
Hacker News: Ask HN
T
Threatpost
WordPress大学
WordPress大学
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 【当耐特】
Know Your Adversary
Know Your Adversary
P
Palo Alto Networks Blog
S
SegmentFault 最新的问题
月光博客
月光博客
Latest news
Latest news
博客园 - Franky
T
Threat Research - Cisco Blogs
有赞技术团队
有赞技术团队
博客园_首页
T
The Exploit Database - CXSecurity.com
The Cloudflare Blog
人人都是产品经理
人人都是产品经理
C
Cybersecurity and Infrastructure Security Agency CISA
S
Schneier on Security
Simon Willison's Weblog
Simon Willison's Weblog
爱范儿
爱范儿
Security Latest
Security Latest
Scott Helme
Scott Helme
博客园 - 聂微东
T
Tor Project blog
美团技术团队
IT之家
IT之家
Stack Overflow Blog
Stack Overflow Blog
B
Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
C
Cisco Blogs
Cisco Talos Blog
Cisco Talos Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
G
Google Developers Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
AWS News Blog
AWS News Blog
Jina AI
Jina AI
Vercel News
Vercel News
小众软件
小众软件
T
Tenable Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Forbes - Security
Forbes - Security
aimingoo的专栏
aimingoo的专栏
O
OpenAI News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
The Last Watchdog
The Last Watchdog
Cloudbric
Cloudbric
AI
AI

NBlog

NBlog - 软件工程和工程师们的未来在何方? NBlog - Gitlab EE 破解手册 NBlog - Gitlab EE 破解手册 NBlog - 又是一年高考季 NBlog - 又是一年高考季 NBlog - 心浮气躁的AI时代 NBlog - 心浮气躁的AI时代 NBlog - 我的2025 NBlog - 我的2025 NBlog - 一位高考数学73的学生证明了黎曼猜想 NBlog - 一位高考数学73的学生证明了黎曼猜想 NBlog - 2017 夏 NBlog - 2017 夏 NBlog - OPanel: 较大型开源个人项目初尝试 NBlog - OPanel: 较大型开源个人项目初尝试 NBlog - [博客更新] 博客添加AI生成内容标识 NBlog - [博客更新] 博客添加AI生成内容标识 NBlog - 为什么我感觉Minecraft越来越无聊了? NBlog - 为什么我感觉Minecraft越来越无聊了? NBlog - 对Abc曲谱标记语言的探索 NBlog - 对Abc曲谱标记语言的探索 NBlog - 域名弃用公告 NBlog - 域名弃用公告 NBlog - [博客更新] 转移至next.js,并重新设计整个网站 NBlog - [博客更新] 转移至next.js,并重新设计整个网站 NBlog - 我的歌单 NBlog - 我的歌单 NBlog - 证明简谐运动的周期公式 NBlog - 证明简谐运动的周期公式 NBlog - [聽后有感] 二 NBlog - [聽后有感] 二 NBlog - The Connells 歌词翻译 NBlog - The Connells 歌词翻译 NBlog - [聽后有感] 一 NBlog - [聽后有感] 一 NBlog - [博客更新] 域名已全面迁移至nocp.space NBlog - [博客更新] 域名已全面迁移至nocp.space NBlog - 证明皮克定理 NBlog - 证明皮克定理 NBlog - 英语选词填空中的数学问题 NBlog - 英语选词填空中的数学问题 NBlog - 如何在家制作食盐(NaCl)晶体? NBlog - 如何在家制作食盐(NaCl)晶体? NBlog - 拒绝“学习方法论”视频 NBlog - 拒绝“学习方法论”视频 NBlog - [博客更新] 现已支持RSS Feed NBlog - [博客更新] 现已支持RSS Feed NBlog - [代码日记] 编译运行VSCode源码 NBlog - [代码日记] 编译运行VSCode源码 NBlog - 证明一些导数结论 NBlog - 证明一些导数结论 NBlog - [代码日记] Calcium源码仓库喜提20stars NBlog - [代码日记] Calcium源码仓库喜提20stars NBlog - C大调卡农(摇滚版) NBlog - 陈升新单《望鄉》发布 NBlog - 陈升新单《望鄉》发布 NBlog - [博客更新] 全面重写整个网站 NBlog - [博客更新] 全面重写整个网站 NBlog - 我开发了一款计算器 (Calcium 使用手册) NBlog - 论如何免费的游玩离线Minecraft NBlog - 论如何免费的游玩离线Minecraft NBlog - Ferrum文件管理器荣获软件创新大赛二等奖 NBlog - Ferrum文件管理器荣获软件创新大赛二等奖 NBlog - 自己推导的三角函数二级结论 NBlog - 自己推导的三角函数二级结论 NBlog - 证明海伦公式 NBlog - 证明海伦公式 NBlog - Ferrum文件管理器参加了一个软件创新比赛活动! NBlog - Ferrum文件管理器参加了一个软件创新比赛活动! NBlog - NBlog, 2023新年好! NBlog - NBlog, 2023新年好! NBlog - [代码日记] 手写多功能计算器! (未完工+难题) NBlog - 中考结束, 我回来了! NBlog - 中考结束, 我回来了! NBlog - [代码日记] 上手实践webpack、babel NBlog - [代码日记] 上手实践webpack、babel NBlog - [代码日记] 在游戏中为实体写一个AI NBlog - [代码日记] 在游戏中为实体写一个AI NBlog - 为什么铜傀儡比轻灵更好? NBlog - 为什么铜傀儡比轻灵更好? NBlog - [代码日记] PR经历记录 NBlog - [代码日记] PR经历记录 NBlog - [代码日记] 为nodejs.org网站源码提PR NBlog - [代码日记] 为nodejs.org网站源码提PR NBlog - [博客更新] 博客已更换主题至经典landscape NBlog - [博客更新] 博客已更换主题至经典landscape NBlog - ICraft开发日志-3 NBlog - ICraft开发日志-3 NBlog - 发现某反mc网站的bug NBlog - 发现某反mc网站的bug NBlog - ICraft开发日志-2 NBlog - ICraft开发日志-2 NBlog - ICraft开发日志-1 NBlog - ICraft开发日志-1 NBlog - 在旧手机上部署MC服务器 NBlog - 在旧手机上部署MC服务器 NBlog - 函数图像生成器 一个控制台小游戏 Nocp-startpage NBlog - 新博客正式开启
NBlog - [代码日记] 手写多功能计算器! (未完工+难题)
NriotHrreion · 2023-01-18 · via NBlog

Ferrum Explorer的开发暂时告一段落, 这下我又不知道下一个项目写什么了. 有一天, 我突然想到, 下一个项目可以是一个多功能计算器!

开启新项目

接下来就是用create-react-app搭建一个React+Typescript的新项目. 因为计算器的英文是"calculator", 钙的英文是"calcium", 它们的前四个字母相同, 所以我就将"Calcium"作为项目的名称.

项目有了, 接下来就构思整个app的功能和页面的布局.

功能

在功能方面, 我计划做三个模式: 通用模式、函数图像模式、程序员模式

布局

在布局方面, 我打算参考VSCode, 做一个像下图一样的布局.

布局设计布局设计

在最左侧的那条较窄的侧边栏中放三个模式的切换按钮, 在左侧较宽的侧边栏中放历史记录列表, 在右侧上部放输出栏, 在右侧下部放输入栏.

制作模式按钮图标

原本我是打算在Google Fonts里找图标的, 但是找了一圈发现根本就没有符合我想法的图标, 于是我就自己用矢量图软件Ai画了几个.

通用模式

通用模式的开发还是比较顺利的. 大致的开发过程是: 输入栏 > 输出栏 (包括输入框) > 算式编译执行器 > 历史记录栏

输入栏

输入栏比较简单, 它无非就是几列几排的按钮, 难点在于如何使它正确布局.

我这里使用flex布局模式. 将整个输入栏分成4大块: 一块是数学函数类, 一块是常用类, 一块是变量或常量字符类, 还有一块放版本号.

输入栏输入栏

接着, 将每一排看作一个整体, 将整个输入栏再次分为11排, 每一排再用flex将每一个按钮放好, 中间的空格用单独的<div>占位, 较大的按钮(如上图的"%"和"Result")用css中的flex-grow来控制宽度.

输入栏布局方式输入栏布局方式

输出栏

输出栏比较复杂. 我将它分为输入框与输出框两部分, 虽说是输出栏, 但是它既包括输入也包括输出. 由于原生HTML的输入框不是很友好, 因此我不得不自己做一个自制版的<input type="text">, 所以我说输出栏是比较复杂的.

输出栏的布局如图:

输出栏布局方式输出栏布局方式

输入框的每一个字符都由一个单独的<span>来包裹, 如果遇到像"sin"之类的整体, 则将这个整体直接包进<span>即可, 这样一来才便于编译执行器解析. 如图所示:

输入框布局方式输入框布局方式

输出框就比较简单了, 将结果直接输出来就可以.

算式编译执行器

这个编译执行器我觉得对我来说是最难的部分, 我将它单独存在Compiler.tsx文件中.

它大致的原理就是将输入框传来的算式(为字符串数组, 数组中每一个元素都是一个单独的符号)进行遍历, 识别每一个字符, 并将它存入编译后的数字列表与运算符号列表; 如果遇到括号, 就将整个括号内的内容单独存储, 然后运用递归来完成括号内的编译; 如果遇到函数, 就向函数列表中查找对应的函数, 然后进行计算.

编译完成后就是执行. 执行的部分按照我们小学就学过的"先乘除, 后加减"的原则, 同时遍历数字列表与运算符号列表, 然后进行计算(此时括号内的算式已被转换为算式的结果).

历史记录栏

历史记录栏是最简单的部分, 只需要监听输出框的输出, 然后将输出的内容连同输入的式子存入历史记录中并显示出来即可.

函数图像模式

函数图像模式的开发涉及到<canvas>上下文的调用与渲染, 然而这玩意性能比较差, 于是出了很多超出我现有水平的问题, 以至于我无法解决.

遇到的问题

就在我以为函数图像模式的开发如此顺利的时候, 我发现仅需要2~3个函数图像就可以让整个<canvas>的画面非常卡顿, 于是我打算通过Javascript的新特性Service Worker来解决这个问题.

但当我实装了Worker之后, 我发现它渲染出来的函数图像会不断闪烁, 并且渲染某些函数图像的时候会渲染错误, 这就太令人匪夷所思了. 最后归根到底还是我的水平太低, 以及<canvas>性能太差...

于是乎, 整个开发进度就卡在这里了...

总结

没啥好说, 项目先搁置了, 咕咕咕~

项目已经部署在: calcium.js.org