1+ <!DOCTYPE html>
2+ < html lang ="zh-CN ">
3+ < head >
4+ < meta charset ="UTF-8 ">
5+ < meta name ="viewport " content ="width=device-width, initial-scale=1.0 ">
6+ < title > 炉石传说斩杀伤害计算器</ title >
7+ <!-- 引入 Tailwind CSS,它默认支持移动优先的响应式设计 -->
8+ < script src ="https://cdn.tailwindcss.com "> </ script >
9+ < style >
10+ /* 自定义字体,确保中文字符显示正常 */
11+ body {
12+ font-family : 'Inter' , sans-serif;
13+ background-color : # f0f2f5 ; /* 浅灰色背景 */
14+ }
15+ /* 隐藏数字输入框的上下箭头,提升移动端体验 */
16+ input [type = "number" ]::-webkit-outer-spin-button ,
17+ input [type = "number" ]::-webkit-inner-spin-button {
18+ -webkit-appearance : none;
19+ margin : 0 ;
20+ }
21+ input [type = "number" ] {
22+ -moz-appearance : textfield; /* Firefox */
23+ }
24+ </ style >
25+ </ head >
26+ <!-- 使用 flex 布局居中内容,min-h-screen 确保高度至少为视口高度,p-4 添加内边距 -->
27+ < body class ="flex items-center justify-center min-h-screen p-4 ">
28+ <!-- 主容器:响应式宽度 (w-full 在小屏上占满,max-w-md 在大屏上限制最大宽度) -->
29+ < div class ="bg-white p-6 sm:p-8 rounded-xl shadow-2xl w-full max-w-md border border-gray-200 ">
30+ < h1 class ="text-2xl sm:text-3xl font-bold text-center text-gray-800 mb-6 "> 欧洛尼乌斯斩杀伤害计算器</ h1 >
31+
32+ < div class ="space-y-5 sm:space-y-6 ">
33+ <!-- 卡牌基本伤害 (X) -->
34+ < div >
35+ < label class ="block text-sm sm:text-base font-medium text-gray-700 mb-2 ">
36+ 卡牌基本伤害
37+ </ label >
38+ <!-- 单选按钮组:在小屏上垂直堆叠 (flex-col),在中等屏幕及以上水平排列 (sm:flex-row) -->
39+ < div class ="flex flex-col sm:flex-row items-start sm:items-center space-y-2 sm:space-y-0 sm:space-x-4 mb-3 ">
40+ <!-- 直接输入总伤害的单选按钮 -->
41+ < div class ="flex items-center ">
42+ < input type ="radio " id ="inputMethodDirect " name ="baseDamageInputMethod " value ="direct " checked class ="form-radio text-blue-600 h-4 w-4 ">
43+ < label for ="inputMethodDirect " class ="ml-2 text-gray-700 text-sm sm:text-base "> 直接输入总伤害</ label >
44+ </ div >
45+ <!-- 多张卡牌伤害求和的单选按钮 -->
46+ < div class ="flex items-center ">
47+ < input type ="radio " id ="inputMethodMultiple " name ="baseDamageInputMethod " value ="multiple " class ="form-radio text-blue-600 h-4 w-4 ">
48+ < label for ="inputMethodMultiple " class ="ml-2 text-gray-700 text-sm sm:text-base "> 多张卡牌伤害求和</ label >
49+ </ div >
50+ </ div >
51+
52+ <!-- 直接输入总伤害的输入框 -->
53+ < div id ="directInputContainer ">
54+ < input
55+ type ="number "
56+ id ="baseDamageXDirect "
57+ value ="0 "
58+ min ="0 "
59+ class ="mt-1 block w-full px-3 py-2 sm:px-4 sm:py-2 border border-gray-300 rounded-lg shadow-sm focus:ring-blue-500 focus:border-blue-500 text-base sm:text-lg text-gray-900 bg-gray-50 transition duration-150 ease-in-out "
60+ placeholder ="输入卡牌总基本伤害 "
61+ >
62+ </ div >
63+
64+ <!-- 多张卡牌伤害求和的输入框 -->
65+ < div id ="multipleInputContainer " class ="hidden ">
66+ < input
67+ type ="text "
68+ id ="baseDamageXMultiple "
69+ value =""
70+ class ="mt-1 block w-full px-3 py-2 sm:px-4 sm:py-2 border border-gray-300 rounded-lg shadow-sm focus:ring-blue-500 focus:border-blue-500 text-base sm:text-lg text-gray-900 bg-gray-50 transition duration-150 ease-in-out "
71+ placeholder ="输入多张卡牌伤害,用空格分隔 (例如: 3 2 1) "
72+ >
73+ </ div >
74+ </ div >
75+
76+ <!-- 欧洛尼乌斯的数量 (N) -->
77+ < div >
78+ < label for ="oloronusCountN " class ="block text-sm sm:text-base font-medium text-gray-700 mb-2 ">
79+ 欧洛尼乌斯的数量
80+ </ label >
81+ < input
82+ type ="number "
83+ id ="oloronusCountN "
84+ value ="0 "
85+ min ="0 "
86+ class ="mt-1 block w-full px-3 py-2 sm:px-4 sm:py-2 border border-gray-300 rounded-lg shadow-sm focus:ring-blue-500 focus:border-blue-500 text-base sm:text-lg text-gray-900 bg-gray-50 transition duration-150 ease-in-out "
87+ placeholder ="输入欧洛尼乌斯数量 "
88+ >
89+ </ div >
90+
91+ <!-- 法强增伤的数值 (Y) -->
92+ < div >
93+ < label for ="spellDamageY " class ="block text-sm sm:text-base font-medium text-gray-700 mb-2 ">
94+ 法强增伤的数值
95+ </ label >
96+ < input
97+ type ="number "
98+ id ="spellDamageY "
99+ value ="0 "
100+ class ="mt-1 block w-full px-3 py-2 sm:px-4 sm:py-2 border border-gray-300 rounded-lg shadow-sm focus:ring-blue-500 focus:border-blue-500 text-base sm:text-lg text-gray-900 bg-gray-50 transition duration-150 ease-in-out "
101+ placeholder ="输入法强增伤数值 "
102+ >
103+ </ div >
104+ </ div >
105+
106+ <!-- 结果显示区域 -->
107+ < div class ="mt-6 sm:mt-8 p-4 sm:p-6 bg-blue-100 border border-blue-300 rounded-lg text-center shadow-md ">
108+ < p class ="text-base sm:text-lg font-medium text-blue-800 mb-2 "> 最终斩杀伤害:</ p >
109+ < p id ="finalDamage " class ="text-4xl sm:text-5xl font-extrabold text-blue-700 "> 0</ p >
110+ </ div >
111+ </ div >
112+
113+ < script >
114+ // 获取所有输入框和结果显示元素
115+ const inputMethodDirect = document . getElementById ( 'inputMethodDirect' ) ;
116+ const inputMethodMultiple = document . getElementById ( 'inputMethodMultiple' ) ;
117+ const directInputContainer = document . getElementById ( 'directInputContainer' ) ;
118+ const multipleInputContainer = document . getElementById ( 'multipleInputContainer' ) ;
119+ const baseDamageXDirectInput = document . getElementById ( 'baseDamageXDirect' ) ; // 直接输入总伤害的输入框
120+ const baseDamageXMultipleInput = document . getElementById ( 'baseDamageXMultiple' ) ; // 多张卡牌伤害求和的输入框
121+
122+ const oloronusCountNInput = document . getElementById ( 'oloronusCountN' ) ;
123+ const spellDamageYInput = document . getElementById ( 'spellDamageY' ) ;
124+ const finalDamageDisplay = document . getElementById ( 'finalDamage' ) ;
125+
126+ /**
127+ * 计算并更新斩杀伤害
128+ */
129+ function calculateDamage ( ) {
130+ let X_total = 0 ; // 初始化卡牌基本伤害总和
131+ let cardCount = 0 ; // 初始化卡牌数量
132+
133+ // 根据选择的输入方式获取 X 的值和卡牌数量
134+ if ( inputMethodDirect . checked ) {
135+ // 如果选择直接输入总伤害
136+ X_total = parseFloat ( baseDamageXDirectInput . value ) || 0 ;
137+ cardCount = 1 ; // 视为一张卡牌
138+ } else {
139+ // 如果选择多张卡牌伤害求和
140+ const multipleValuesString = baseDamageXMultipleInput . value ;
141+ // 将空格分隔的字符串拆分为数组,过滤掉空字符串,并转换为数字,非数字项默认为0
142+ const multipleValues = multipleValuesString . split ( ' ' ) . filter ( s => s . trim ( ) !== '' ) . map ( s => parseFloat ( s . trim ( ) ) || 0 ) ;
143+
144+ X_total = multipleValues . reduce ( ( sum , current ) => sum + current , 0 ) ; // 求和所有卡牌的基本伤害
145+ cardCount = multipleValues . length ; // 获取卡牌数量
146+ }
147+
148+ // 获取欧洛尼乌斯数量 N 和法强增伤 Y
149+ const N = parseFloat ( oloronusCountNInput . value ) || 0 ;
150+ const Y = parseFloat ( spellDamageYInput . value ) || 0 ;
151+
152+ // 确保 N 为非负整数,因为 2 的 N 次方通常 N 是非负整数
153+ const safeN = Math . max ( 0 , Math . floor ( N ) ) ;
154+
155+ // 计算伤害:伤害 = X_total + (cardCount × 2^N × Y)
156+ // 这里将 2^N * Y 的部分乘以卡牌数量,再与基本伤害总和相加
157+ const damage = X_total + ( cardCount * Math . pow ( 2 , safeN ) * Y ) ;
158+
159+ // 更新结果显示,保留整数
160+ finalDamageDisplay . textContent = Math . floor ( damage ) ;
161+ }
162+
163+ /**
164+ * 根据单选按钮的选择切换卡牌基本伤害输入框的显示
165+ */
166+ function toggleBaseDamageInput ( ) {
167+ if ( inputMethodDirect . checked ) {
168+ // 显示直接输入框,隐藏多张卡牌输入框
169+ directInputContainer . classList . remove ( 'hidden' ) ;
170+ multipleInputContainer . classList . add ( 'hidden' ) ;
171+ // 切换时清空多张卡牌输入框的值,避免干扰计算
172+ baseDamageXMultipleInput . value = '' ;
173+ } else {
174+ // 显示多张卡牌输入框,隐藏直接输入框
175+ directInputContainer . classList . add ( 'hidden' ) ;
176+ multipleInputContainer . classList . remove ( 'hidden' ) ;
177+ // 切换时将直接输入框的值重置为0,避免干扰计算
178+ baseDamageXDirectInput . value = '0' ;
179+ }
180+ // 切换输入方式后立即重新计算伤害
181+ calculateDamage ( ) ;
182+ }
183+
184+ // 为单选按钮添加 'change' 事件监听器,以便在选择改变时切换输入框显示
185+ inputMethodDirect . addEventListener ( 'change' , toggleBaseDamageInput ) ;
186+ inputMethodMultiple . addEventListener ( 'change' , toggleBaseDamageInput ) ;
187+
188+ // 为所有输入框添加 'input' 事件监听器,实现实时计算
189+ baseDamageXDirectInput . addEventListener ( 'input' , calculateDamage ) ;
190+ baseDamageXMultipleInput . addEventListener ( 'input' , calculateDamage ) ;
191+ oloronusCountNInput . addEventListener ( 'input' , calculateDamage ) ;
192+ spellDamageYInput . addEventListener ( 'input' , calculateDamage ) ;
193+
194+ // 页面加载时执行一次初始化设置和计算,确保初始状态正确
195+ window . onload = ( ) => {
196+ toggleBaseDamageInput ( ) ; // 根据默认选择设置初始输入框显示
197+ calculateDamage ( ) ; // 初始计算
198+ } ;
199+ </ script >
200+ </ body >
201+ </ html >
0 commit comments