feat: Add Scoreboard and Date Calc pages, update Calculator with scientific mode and new UI
This commit is contained in:
@@ -6,15 +6,34 @@ Page({
|
||||
operator: null as string | null,
|
||||
firstOperand: null as number | null,
|
||||
waitingForSecondOperand: false,
|
||||
isScientific: false
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
},
|
||||
|
||||
vibrate() {
|
||||
// wx.vibrateShort({ type: 'light' });
|
||||
},
|
||||
|
||||
toggleMode() {
|
||||
this.vibrate();
|
||||
this.setData({
|
||||
isScientific: !this.data.isScientific
|
||||
});
|
||||
},
|
||||
|
||||
onDigit(e: any) {
|
||||
this.vibrate();
|
||||
const digit = e.currentTarget.dataset.digit;
|
||||
const { displayValue, waitingForSecondOperand } = this.data;
|
||||
|
||||
// 科学模式允许更多数字
|
||||
const limit = 15;
|
||||
if (!waitingForSecondOperand && displayValue.length >= limit) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (waitingForSecondOperand) {
|
||||
this.setData({
|
||||
displayValue: digit,
|
||||
@@ -28,6 +47,7 @@ Page({
|
||||
},
|
||||
|
||||
onDot() {
|
||||
this.vibrate();
|
||||
const { displayValue, waitingForSecondOperand } = this.data;
|
||||
if (waitingForSecondOperand) {
|
||||
this.setData({
|
||||
@@ -42,6 +62,7 @@ Page({
|
||||
},
|
||||
|
||||
onClear() {
|
||||
this.vibrate();
|
||||
this.setData({
|
||||
displayValue: '0',
|
||||
history: '',
|
||||
@@ -52,13 +73,94 @@ Page({
|
||||
},
|
||||
|
||||
onDelete() {
|
||||
this.vibrate();
|
||||
const { displayValue } = this.data;
|
||||
if (displayValue.length > 1) {
|
||||
this.setData({
|
||||
displayValue: displayValue.slice(0, -1)
|
||||
});
|
||||
} else {
|
||||
this.setData({ displayValue: '0' });
|
||||
}
|
||||
},
|
||||
|
||||
onToggleSign() {
|
||||
this.vibrate();
|
||||
const { displayValue } = this.data;
|
||||
const newValue = parseFloat(displayValue) * -1;
|
||||
this.setData({
|
||||
displayValue: String(newValue)
|
||||
});
|
||||
},
|
||||
|
||||
onConstant(e: any) {
|
||||
this.vibrate();
|
||||
const type = e.currentTarget.dataset.const;
|
||||
let val = 0;
|
||||
if (type === 'pi') val = Math.PI;
|
||||
if (type === 'e') val = Math.E;
|
||||
|
||||
this.setData({
|
||||
displayValue: displayValue.length > 1 ? displayValue.slice(0, -1) : '0'
|
||||
displayValue: String(val).slice(0, 10),
|
||||
waitingForSecondOperand: true // 下次输入将开启新数字,或者作为操作数
|
||||
});
|
||||
},
|
||||
|
||||
onMathFunc(e: any) { // 单操作数立即计算
|
||||
this.vibrate();
|
||||
const func = e.currentTarget.dataset.func;
|
||||
let val = parseFloat(this.data.displayValue);
|
||||
let result = 0;
|
||||
let desc = '';
|
||||
|
||||
switch(func) {
|
||||
case 'sin':
|
||||
// 默认转为弧度计算 (度数 * PI / 180)
|
||||
result = Math.sin(val * Math.PI / 180);
|
||||
desc = `sin(${val})`;
|
||||
break;
|
||||
case 'cos':
|
||||
result = Math.cos(val * Math.PI / 180);
|
||||
desc = `cos(${val})`;
|
||||
break;
|
||||
case 'tan':
|
||||
result = Math.tan(val * Math.PI / 180);
|
||||
desc = `tan(${val})`;
|
||||
break;
|
||||
case 'log':
|
||||
result = Math.log10(val);
|
||||
desc = `log(${val})`;
|
||||
break;
|
||||
case 'ln':
|
||||
result = Math.log(val);
|
||||
desc = `ln(${val})`;
|
||||
break;
|
||||
case 'sqrt':
|
||||
result = Math.sqrt(val);
|
||||
desc = `√(${val})`;
|
||||
break;
|
||||
case 'pow2':
|
||||
result = Math.pow(val, 2);
|
||||
desc = `sqr(${val})`;
|
||||
break;
|
||||
case 'percent':
|
||||
result = val / 100;
|
||||
desc = `${val}%`;
|
||||
break;
|
||||
}
|
||||
|
||||
// 格式化结果
|
||||
const formatted = parseFloat(result.toPrecision(12));
|
||||
|
||||
this.setData({
|
||||
displayValue: String(formatted),
|
||||
history: desc,
|
||||
waitingForSecondOperand: true // 计算完后,下次输入数字是新数字
|
||||
});
|
||||
},
|
||||
|
||||
onOperator(e: any) {
|
||||
this.vibrate();
|
||||
const nextOperator = e.currentTarget.dataset.op;
|
||||
const { displayValue, operator, firstOperand } = this.data;
|
||||
const inputValue = parseFloat(displayValue);
|
||||
@@ -66,7 +168,8 @@ Page({
|
||||
if (operator && this.data.waitingForSecondOperand) {
|
||||
this.setData({
|
||||
operator: nextOperator,
|
||||
history: `${firstOperand} ${nextOperator}`
|
||||
// 更新历史记录中的符号
|
||||
history: `${firstOperand} ${nextOperator}`
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -79,7 +182,7 @@ Page({
|
||||
const result = this.performCalculation(operator, firstOperand, inputValue);
|
||||
newFirstOperand = result;
|
||||
this.setData({
|
||||
displayValue: String(result),
|
||||
displayValue: String(result),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -92,35 +195,33 @@ Page({
|
||||
},
|
||||
|
||||
onEqual() {
|
||||
this.vibrate();
|
||||
const { displayValue, operator, firstOperand } = this.data;
|
||||
const inputValue = parseFloat(displayValue);
|
||||
|
||||
if (operator && firstOperand != null) {
|
||||
const result = this.performCalculation(operator, firstOperand, inputValue);
|
||||
|
||||
this.setData({
|
||||
displayValue: String(result),
|
||||
firstOperand: null,
|
||||
operator: null,
|
||||
waitingForSecondOperand: true,
|
||||
history: ''
|
||||
history: `${firstOperand} ${operator} ${inputValue} =`
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
performCalculation(operator: string, firstOperand: number, secondOperand: number) {
|
||||
switch (operator) {
|
||||
case '+':
|
||||
return firstOperand + secondOperand;
|
||||
case '-':
|
||||
return firstOperand - secondOperand;
|
||||
case '*':
|
||||
return firstOperand * secondOperand;
|
||||
case '/':
|
||||
return firstOperand / secondOperand;
|
||||
case '%':
|
||||
return firstOperand % secondOperand;
|
||||
default:
|
||||
return secondOperand;
|
||||
}
|
||||
performCalculation(op: string, first: number, second: number): number {
|
||||
let result = 0;
|
||||
switch(op) {
|
||||
case '+': result = first + second; break;
|
||||
case '-': result = first - second; break;
|
||||
case '×': result = first * second; break;
|
||||
case '÷': result = first / second; break;
|
||||
default: return second;
|
||||
}
|
||||
const precision = 10000000000;
|
||||
return Math.round(result * precision) / precision;
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
@@ -1,32 +1,68 @@
|
||||
<!--pages/calculator/calculator.wxml-->
|
||||
<view class="calculator">
|
||||
<view class="screen">
|
||||
<view class="history">{{history}}</view>
|
||||
<view class="result">{{displayValue}}</view>
|
||||
<view class="calculator-container">
|
||||
<!-- 显示区域 -->
|
||||
<view class="display-area">
|
||||
<view class="mode-indicator" bindtap="toggleMode">
|
||||
<text class="{{isScientific ? 'active' : ''}}">⚗️ 科学模式</text>
|
||||
</view>
|
||||
<view class="history-text">{{history}}</view>
|
||||
<view class="current-value {{displayValue.length > 9 ? 'shrink' : ''}} {{displayValue.length > 15 ? 'shrink-more' : ''}}">{{displayValue}}</view>
|
||||
</view>
|
||||
<view class="keypad">
|
||||
<view class="btn operator" bindtap="onClear">C</view>
|
||||
<view class="btn operator" bindtap="onDelete">DEL</view>
|
||||
<view class="btn operator" bindtap="onOperator" data-op="%">%</view>
|
||||
<view class="btn operator" bindtap="onOperator" data-op="/">÷</view>
|
||||
|
||||
<!-- 键盘区域 -->
|
||||
<view class="keypad-area {{isScientific ? 'scientific-pad' : ''}}">
|
||||
|
||||
<view class="btn" bindtap="onDigit" data-digit="7">7</view>
|
||||
<view class="btn" bindtap="onDigit" data-digit="8">8</view>
|
||||
<view class="btn" bindtap="onDigit" data-digit="9">9</view>
|
||||
<view class="btn operator" bindtap="onOperator" data-op="*">×</view>
|
||||
<!-- 科学功能区 (隐藏/显示) -->
|
||||
<block wx:if="{{isScientific}}">
|
||||
<view class="row small-row">
|
||||
<view class="btn sci-btn" hover-class="btn-hover" hover-start-time="0" hover-stay-time="100" bindtap="onMathFunc" data-func="sin">sin</view>
|
||||
<view class="btn sci-btn" hover-class="btn-hover" hover-start-time="0" hover-stay-time="100" bindtap="onMathFunc" data-func="cos">cos</view>
|
||||
<view class="btn sci-btn" hover-class="btn-hover" hover-start-time="0" hover-stay-time="100" bindtap="onMathFunc" data-func="tan">tan</view>
|
||||
<view class="btn sci-btn" hover-class="btn-hover" hover-start-time="0" hover-stay-time="100" bindtap="onMathFunc" data-func="log">log</view>
|
||||
<view class="btn sci-btn" hover-class="btn-hover" hover-start-time="0" hover-stay-time="100" bindtap="onMathFunc" data-func="ln">ln</view>
|
||||
</view>
|
||||
<view class="row small-row">
|
||||
<view class="btn sci-btn" hover-class="btn-hover" hover-start-time="0" hover-stay-time="100" bindtap="onConstant" data-const="pi">π</view>
|
||||
<view class="btn sci-btn" hover-class="btn-hover" hover-start-time="0" hover-stay-time="100" bindtap="onConstant" data-const="e">e</view>
|
||||
<view class="btn sci-btn" hover-class="btn-hover" hover-start-time="0" hover-stay-time="100" bindtap="onMathFunc" data-func="pow2">x²</view>
|
||||
<view class="btn sci-btn" hover-class="btn-hover" hover-start-time="0" hover-stay-time="100" bindtap="onMathFunc" data-func="sqrt">√</view>
|
||||
<view class="btn sci-btn" hover-class="btn-hover" hover-start-time="0" hover-stay-time="100" bindtap="onMathFunc" data-func="percent">%</view>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!-- 基础键盘 -->
|
||||
<view class="row">
|
||||
<view class="btn func" hover-class="btn-hover" hover-start-time="0" hover-stay-time="100" bindtap="onClear">AC</view>
|
||||
<view class="btn func" hover-class="btn-hover" hover-start-time="0" hover-stay-time="100" bindtap="onDelete">⌫</view>
|
||||
<view class="btn func" hover-class="btn-hover" hover-start-time="0" hover-stay-time="100" bindtap="onToggleSign">+/-</view>
|
||||
<view class="btn operator" hover-class="btn-hover" hover-start-time="0" hover-stay-time="100" bindtap="onOperator" data-op="÷">÷</view>
|
||||
</view>
|
||||
|
||||
<view class="btn" bindtap="onDigit" data-digit="4">4</view>
|
||||
<view class="btn" bindtap="onDigit" data-digit="5">5</view>
|
||||
<view class="btn" bindtap="onDigit" data-digit="6">6</view>
|
||||
<view class="btn operator" bindtap="onOperator" data-op="-">-</view>
|
||||
<view class="row">
|
||||
<view class="btn digit" hover-class="btn-hover" hover-start-time="0" hover-stay-time="100" bindtap="onDigit" data-digit="7">7</view>
|
||||
<view class="btn digit" hover-class="btn-hover" hover-start-time="0" hover-stay-time="100" bindtap="onDigit" data-digit="8">8</view>
|
||||
<view class="btn digit" hover-class="btn-hover" hover-start-time="0" hover-stay-time="100" bindtap="onDigit" data-digit="9">9</view>
|
||||
<view class="btn operator" hover-class="btn-hover" hover-start-time="0" hover-stay-time="100" bindtap="onOperator" data-op="×">×</view>
|
||||
</view>
|
||||
|
||||
<view class="btn" bindtap="onDigit" data-digit="1">1</view>
|
||||
<view class="btn" bindtap="onDigit" data-digit="2">2</view>
|
||||
<view class="btn" bindtap="onDigit" data-digit="3">3</view>
|
||||
<view class="btn operator" bindtap="onOperator" data-op="+">+</view>
|
||||
<view class="row">
|
||||
<view class="btn digit" hover-class="btn-hover" hover-start-time="0" hover-stay-time="100" bindtap="onDigit" data-digit="4">4</view>
|
||||
<view class="btn digit" hover-class="btn-hover" hover-start-time="0" hover-stay-time="100" bindtap="onDigit" data-digit="5">5</view>
|
||||
<view class="btn digit" hover-class="btn-hover" hover-start-time="0" hover-stay-time="100" bindtap="onDigit" data-digit="6">6</view>
|
||||
<view class="btn operator" hover-class="btn-hover" hover-start-time="0" hover-stay-time="100" bindtap="onOperator" data-op="-">−</view>
|
||||
</view>
|
||||
|
||||
<view class="btn zero" bindtap="onDigit" data-digit="0">0</view>
|
||||
<view class="btn" bindtap="onDot">.</view>
|
||||
<view class="btn equal" bindtap="onEqual">=</view>
|
||||
<view class="row">
|
||||
<view class="btn digit" hover-class="btn-hover" hover-start-time="0" hover-stay-time="100" bindtap="onDigit" data-digit="1">1</view>
|
||||
<view class="btn digit" hover-class="btn-hover" hover-start-time="0" hover-stay-time="100" bindtap="onDigit" data-digit="2">2</view>
|
||||
<view class="btn digit" hover-class="btn-hover" hover-start-time="0" hover-stay-time="100" bindtap="onDigit" data-digit="3">3</view>
|
||||
<view class="btn operator" hover-class="btn-hover" hover-start-time="0" hover-stay-time="100" bindtap="onOperator" data-op="+">+</view>
|
||||
</view>
|
||||
|
||||
<view class="row">
|
||||
<view class="btn digit zero" hover-class="btn-hover" hover-start-time="0" hover-stay-time="100" bindtap="onDigit" data-digit="0">0</view>
|
||||
<view class="btn digit" hover-class="btn-hover" hover-start-time="0" hover-stay-time="100" bindtap="onDot">.</view>
|
||||
<view class="btn operator equal" hover-class="btn-hover" hover-start-time="0" hover-stay-time="100" bindtap="onEqual">=</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -1,74 +1,188 @@
|
||||
/* pages/calculator/calculator.wxss */
|
||||
page {
|
||||
height: 100%;
|
||||
background-color: #f5f5f5;
|
||||
background-color: #000000;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.calculator {
|
||||
.calculator-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
}
|
||||
|
||||
.screen {
|
||||
/* 显示区域 */
|
||||
.display-area {
|
||||
flex: 1;
|
||||
background-color: #333;
|
||||
color: white;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
align-items: flex-end;
|
||||
padding: 20rpx;
|
||||
padding: 40rpx;
|
||||
background-color: #000;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mode-indicator {
|
||||
position: absolute;
|
||||
top: 40rpx;
|
||||
left: 40rpx;
|
||||
}
|
||||
|
||||
.mode-indicator text {
|
||||
color: #444;
|
||||
font-size: 24rpx;
|
||||
border: 1px solid #444;
|
||||
padding: 10rpx 20rpx;
|
||||
border-radius: 30rpx;
|
||||
}
|
||||
|
||||
.mode-indicator text.active {
|
||||
color: #ff9f0a;
|
||||
border-color: #ff9f0a;
|
||||
background: rgba(255, 159, 10, 0.1);
|
||||
}
|
||||
|
||||
|
||||
.history-text {
|
||||
font-size: 36rpx;
|
||||
color: #666;
|
||||
min-height: 50rpx;
|
||||
margin-bottom: 20rpx;
|
||||
font-family: monospace;
|
||||
text-align: right;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.current-value {
|
||||
font-size: 160rpx;
|
||||
color: #fff;
|
||||
line-height: 1;
|
||||
font-weight: 200;
|
||||
word-break: break-all;
|
||||
text-align: right;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.history {
|
||||
font-size: 40rpx;
|
||||
color: #aaa;
|
||||
margin-bottom: 10rpx;
|
||||
.current-value.shrink {
|
||||
font-size: 100rpx;
|
||||
}
|
||||
.current-value.shrink-more {
|
||||
font-size: 70rpx;
|
||||
}
|
||||
|
||||
.result {
|
||||
font-size: 80rpx;
|
||||
font-weight: bold;
|
||||
/* 键盘区域 */
|
||||
.keypad-area {
|
||||
background-color: #000;
|
||||
padding: 0 30rpx 30rpx 30rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 30rpx;
|
||||
}
|
||||
|
||||
.keypad {
|
||||
background-color: #fff;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
grid-gap: 1px;
|
||||
background-color: #ccc; /* Gap color */
|
||||
/* 科学模式适配 */
|
||||
.keypad-area.scientific-pad {
|
||||
gap: 20rpx;
|
||||
padding-bottom: 20rpx;
|
||||
}
|
||||
|
||||
/* 统一圆形按钮 */
|
||||
.keypad-area.scientific-pad .btn {
|
||||
width: 130rpx;
|
||||
height: 130rpx;
|
||||
font-size: 50rpx;
|
||||
border-radius: 50%; /* 保持圆形 */
|
||||
}
|
||||
|
||||
.keypad-area.scientific-pad .zero {
|
||||
width: 280rpx; /* 适配新的宽度 */
|
||||
border-radius: 65rpx; /* 圆角为高度一半 */
|
||||
}
|
||||
|
||||
/* 科学功能键行 */
|
||||
.keypad-area.scientific-pad .sci-btn {
|
||||
width: 120rpx; /* 稍微大一点,填满宽度 */
|
||||
height: 120rpx; /* 正圆 */
|
||||
font-size: 36rpx;
|
||||
background: #222;
|
||||
color: #fff;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.small-row {
|
||||
justify-content: space-around; /* 均匀分布 */
|
||||
gap: 10rpx;
|
||||
}
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 30rpx;
|
||||
}
|
||||
.keypad-area.scientific-pad .row {
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
|
||||
.btn {
|
||||
background-color: #fff;
|
||||
width: 150rpx;
|
||||
height: 150rpx;
|
||||
border-radius: 75rpx; /* 圆形按钮 */
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 40rpx;
|
||||
active-color: #eee;
|
||||
font-size: 60rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.btn:active {
|
||||
background-color: #eee;
|
||||
/* 数字键 */
|
||||
.digit {
|
||||
background-color: #333333;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* 功能键 (AC, Del, +/-) */
|
||||
.func {
|
||||
background-color: #a5a5a5;
|
||||
color: #000;
|
||||
font-size: 50rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 运算符 */
|
||||
.operator {
|
||||
color: #ff9500;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.equal {
|
||||
background-color: #ff9500;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.equal:active {
|
||||
background-color: #e08900;
|
||||
background-color: #ff9f0a;
|
||||
color: #fff;
|
||||
font-size: 70rpx;
|
||||
padding-bottom: 10rpx;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* 0键特殊处理 */
|
||||
.zero {
|
||||
grid-column: span 2;
|
||||
width: 330rpx;
|
||||
border-radius: 75rpx;
|
||||
justify-content: flex-start;
|
||||
padding-left: 60rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 点击反馈 */
|
||||
.btn-hover {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
/* 平板适配或小屏适配 */
|
||||
@media (max-width: 360px) {
|
||||
.btn {
|
||||
width: 140rpx;
|
||||
height: 140rpx;
|
||||
font-size: 50rpx;
|
||||
}
|
||||
.zero {
|
||||
width: 310rpx;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user