KMP 实现鸿蒙跨端:Kotlin 网页设计中的颜色选择 - 配色方案生成工具
本文介绍了一个基于Kotlin Multiplatform的网页设计配色方案生成工具,能够根据输入的主色调自动生成多种专业配色方案。该工具支持互补色、类似色、三角配色和分裂互补色等方案,并提供颜色格式转换(HEX/RGB/HSL)、色彩变体生成和颜色名称识别功能。核心算法通过HSL色彩空间计算配色方案,并实现跨平台兼容性。开发者可通过Kotlin代码生成专业配色方案,应用于OpenHarmony等

目录
概述
本文档介绍如何在 Kotlin Multiplatform (KMP) 鸿蒙跨端开发中实现一个完整的网页设计配色方案生成工具。网页设计中的颜色选择是创建视觉吸引力和用户体验的关键因素。这个案例展示了如何使用 Kotlin 的色彩科学和配色理论来创建一个功能丰富的配色方案生成工具。
配色方案生成工具能够根据用户选择的主色调,自动生成多种配色方案,包括互补色、类似色、三角配色和分裂互补色等。这些配色方案基于色彩理论的原理,确保生成的颜色组合在视觉上和谐且专业。通过 KMP,这个工具可以无缝编译到 JavaScript,在 OpenHarmony 应用中运行,为设计师提供专业的配色方案生成服务。
工具的特点
- 多种配色方案:支持互补色、类似色、三角配色、分裂互补色等多种方案
- 色彩空间转换:支持 HEX、RGB、HSL 等多种色彩空间
- 颜色名称识别:自动识别主色调的颜色名称
- 色彩变体生成:生成浅色和深色变体
- 设计建议:提供专业的设计建议和应用场景
- 跨端兼容:一份 Kotlin 代码可同时服务多个平台
工具功能
1. 主色调输入和验证
工具支持 HEX 格式的颜色输入(例如 FF6B35 表示橙色):
- 颜色格式:6 位十六进制格式
- 格式验证:确保输入的颜色格式正确
- 颜色信息:显示 HEX、RGB、HSL 三种格式的颜色信息
2. 互补色配色
互补色是色轮上相对的两种颜色,具有最高的对比度:
- 原理:互补色相差 180°
- 特点:对比度最高,视觉冲击力强
- 应用:用于强调和突出重要元素
3. 类似色配色
类似色是色轮上相邻的颜色,具有和谐统一的特点:
- 原理:类似色相差 ±30°
- 特点:和谐统一,视觉舒适
- 应用:用于创建统一的视觉风格
4. 三角配色
三角配色使用三个均匀分布在色轮上的颜色:
- 原理:三个颜色相差 120°
- 特点:活力十足,视觉平衡
- 应用:用于复杂的设计和多元素布局
5. 分裂互补色
分裂互补色使用一种颜色和其互补色两侧的颜色:
- 原理:颜色相差 ±150°
- 特点:平衡的对比,不过于刺眼
- 应用:用于需要对比但又不过于激进的设计
6. 色彩变体
工具生成浅色和深色变体,用于不同的应用场景:
- 浅色变体:亮度 80%,用于背景色
- 深色变体:亮度 30%,用于文本色
- 应用:创建完整的色彩系统
7. 颜色名称识别
工具根据色调自动识别颜色名称:
- 12 种基本颜色:红、橙、黄、黄绿、绿、青绿、青、蓝、紫蓝、紫、洋红、红紫
- 应用:帮助设计师快速理解颜色特性
8. 设计建议和应用场景
工具提供专业的设计建议和应用场景:
- 设计建议:如何使用各种配色方案
- 应用场景:网站品牌色、按钮色、背景色、文本色、强调色等
核心实现
算法原理
网页设计配色方案生成工具的核心算法包括:
- 颜色格式转换:HEX → RGB → HSL
- 色调计算:根据 RGB 计算 HSL 中的色调(H)
- 配色方案生成:基于色调生成各种配色方案
- 颜色格式转换:HSL → RGB → HEX
- 颜色名称识别:根据色调识别颜色名称
RGB 到 HSL 的转换
HSL(色调、饱和度、亮度)是一个更直观的色彩空间,便于生成配色方案。
转换步骤:
- 将 RGB 值归一化到 0-1 范围
- 计算最大值(max)和最小值(min)
- 计算亮度(L):(max + min) / 2
- 计算饱和度(S):根据亮度计算
- 计算色调(H):根据最大值是 R、G 还是 B 计算
配色方案生成
基于 HSL 的色调(H)生成各种配色方案:
- 互补色:H + 180°
- 类似色:H ± 30°
- 三角配色:H + 120°、H + 240°
- 分裂互补色:H ± 150°
HSL 到 RGB 的转换
将生成的 HSL 颜色转换回 RGB 格式,然后转换为 HEX。
Kotlin 源代码
// 案例 38: 网页设计中的颜色选择 - 配色方案生成工具
@OptIn(ExperimentalJsExport::class)
@JsExport
fun webDesignColorSchemeGenerator(inputData: String = "FF6B35"): String {
if (inputData.isEmpty()) {
return "❌ 错误: 输入不能为空\n请输入: 主色调 (HEX 格式, 如: FF6B35)"
}
val hexColor = inputData.trim().uppercase()
// 验证十六进制格式
if (!hexColor.matches(Regex("^[0-9A-F]{6}$"))) {
return "❌ 错误: 颜色格式不正确\n请使用6位十六进制格式 (例如: FF6B35)"
}
// 1. 转换HEX到RGB
val r = hexColor.substring(0, 2).toInt(16)
val g = hexColor.substring(2, 4).toInt(16)
val b = hexColor.substring(4, 6).toInt(16)
// 2. 转换RGB到HSL
val rNorm = r / 255.0
val gNorm = g / 255.0
val bNorm = b / 255.0
val max = maxOf(rNorm, gNorm, bNorm)
val min = minOf(rNorm, gNorm, bNorm)
val l = (max + min) / 2.0
val h = when {
max == min -> 0.0
max == rNorm -> (60 * (((gNorm - bNorm) / (max - min)) % 6) + 360) % 360
max == gNorm -> (60 * (((bNorm - rNorm) / (max - min)) + 2)) % 360
else -> (60 * (((rNorm - gNorm) / (max - min)) + 4)) % 360
}
val s = when {
max == min -> 0.0
l < 0.5 -> (max - min) / (max + min)
else -> (max - min) / (2.0 - max - min)
}
// 3. 生成互补色
val complementaryH = (h + 180) % 360
val complementaryRgb = hslToRgb(complementaryH, s, l)
val complementaryHex = rgbToHex(complementaryRgb.first, complementaryRgb.second, complementaryRgb.third)
// 4. 生成类似色(±30度)
val analogousH1 = (h + 30) % 360
val analogousH2 = (h - 30 + 360) % 360
val analogousRgb1 = hslToRgb(analogousH1, s, l)
val analogousRgb2 = hslToRgb(analogousH2, s, l)
val analogousHex1 = rgbToHex(analogousRgb1.first, analogousRgb1.second, analogousRgb1.third)
val analogousHex2 = rgbToHex(analogousRgb2.first, analogousRgb2.second, analogousRgb2.third)
// 5. 生成三角配色(120度间隔)
val triadic1H = (h + 120) % 360
val triadic2H = (h + 240) % 360
val triadicRgb1 = hslToRgb(triadic1H, s, l)
val triadicRgb2 = hslToRgb(triadic2H, s, l)
val triadicHex1 = rgbToHex(triadicRgb1.first, triadicRgb1.second, triadicRgb1.third)
val triadicHex2 = rgbToHex(triadicRgb2.first, triadicRgb2.second, triadicRgb2.third)
// 6. 生成分裂互补色(±150度)
val splitComplementary1H = (h + 150) % 360
val splitComplementary2H = (h - 150 + 360) % 360
val splitComplementaryRgb1 = hslToRgb(splitComplementary1H, s, l)
val splitComplementaryRgb2 = hslToRgb(splitComplementary2H, s, l)
val splitComplementaryHex1 = rgbToHex(splitComplementaryRgb1.first, splitComplementaryRgb1.second, splitComplementaryRgb1.third)
val splitComplementaryHex2 = rgbToHex(splitComplementaryRgb2.first, splitComplementaryRgb2.second, splitComplementaryRgb2.third)
// 7. 生成浅色和深色变体
val lightRgb = hslToRgb(h, s, 0.8)
val lightHex = rgbToHex(lightRgb.first, lightRgb.second, lightRgb.third)
val darkRgb = hslToRgb(h, s, 0.3)
val darkHex = rgbToHex(darkRgb.first, darkRgb.second, darkRgb.third)
// 8. 获取颜色名称
val colorName = getColorName(h)
// 9. 获取设计建议
val designTips = mutableListOf<String>()
designTips.add("• 主色用于品牌标识和重点元素")
designTips.add("• 互补色用于强调和对比")
designTips.add("• 类似色用于和谐的过渡")
designTips.add("• 三角配色适合复杂的设计")
designTips.add("• 浅色用于背景,深色用于文本")
designTips.add("• 确保颜色对比度满足无障碍要求")
return "🎨 网页设计配色方案生成器\n" +
"━━━━━━━━━━━━━━━━━━━━━\n" +
"🌈 主色调信息\n" +
"HEX: #$hexColor\n" +
"RGB: ($r, $g, $b)\n" +
"HSL: (${(h * 100).toInt() / 100.0}°, ${(s * 100).toInt()}%, ${(l * 100).toInt()}%)\n" +
"颜色: $colorName\n\n" +
"🎯 互补色配色\n" +
"互补色: #$complementaryHex\n" +
"说明: 对比度最高,用于强调\n\n" +
"🔄 类似色配色\n" +
"类似色1: #$analogousHex1\n" +
"类似色2: #$analogousHex2\n" +
"说明: 和谐统一,视觉舒适\n\n" +
"△ 三角配色\n" +
"颜色1: #$triadicHex1\n" +
"颜色2: #$triadicHex2\n" +
"说明: 三个颜色均匀分布,活力十足\n\n" +
"◇ 分裂互补色\n" +
"颜色1: #$splitComplementaryHex1\n" +
"颜色2: #$splitComplementaryHex2\n" +
"说明: 平衡的对比,不过于刺眼\n\n" +
"💫 色彩变体\n" +
"浅色: #$lightHex (背景色)\n" +
"深色: #$darkHex (文本色)\n\n" +
"💡 设计建议\n" +
designTips.joinToString("\n") + "\n\n" +
"📋 应用场景\n" +
"• 网站品牌色: #$hexColor\n" +
"• 按钮色: #$complementaryHex\n" +
"• 背景色: #$lightHex\n" +
"• 文本色: #$darkHex\n" +
"• 强调色: #$triadicHex1\n\n" +
"━━━━━━━━━━━━━━━━━━━━━\n" +
"✅ 配色方案生成完成!"
}
// 辅助函数: 获取颜色名称
fun getColorName(hue: Double): String {
return when {
hue < 15 || hue >= 345 -> "红色"
hue < 45 -> "橙色"
hue < 75 -> "黄色"
hue < 105 -> "黄绿色"
hue < 135 -> "绿色"
hue < 165 -> "青绿色"
hue < 195 -> "青色"
hue < 225 -> "蓝色"
hue < 255 -> "紫蓝色"
hue < 285 -> "紫色"
hue < 315 -> "洋红色"
else -> "红紫色"
}
}
// 辅助函数: HSL转RGB
fun hslToRgb(h: Double, s: Double, l: Double): Triple<Int, Int, Int> {
val c = (1 - kotlin.math.abs(2 * l - 1)) * s
val hPrime = h / 60.0
val x = c * (1 - kotlin.math.abs(hPrime % 2 - 1))
val (r1, g1, b1) = when {
hPrime < 1 -> Triple(c, x, 0.0)
hPrime < 2 -> Triple(x, c, 0.0)
hPrime < 3 -> Triple(0.0, c, x)
hPrime < 4 -> Triple(0.0, x, c)
hPrime < 5 -> Triple(x, 0.0, c)
else -> Triple(c, 0.0, x)
}
val m = l - c / 2
val r = ((r1 + m) * 255).toInt()
val g = ((g1 + m) * 255).toInt()
val b = ((b1 + m) * 255).toInt()
return Triple(r, g, b)
}
// 辅助函数: RGB转HEX
fun rgbToHex(r: Int, g: Int, b: Int): String {
val rHex = r.toString(16).padStart(2, '0').uppercase()
val gHex = g.toString(16).padStart(2, '0').uppercase()
val bHex = b.toString(16).padStart(2, '0').uppercase()
return rHex + gHex + bHex
}
Kotlin 代码详解
这个 Kotlin 函数实现了一个完整的网页设计配色方案生成工具。函数接收一个 HEX 格式的颜色作为主色调。
首先,函数进行输入验证,确保颜色格式正确。
接下来,函数将 HEX 颜色转换为 RGB,然后转换为 HSL。HSL 色彩空间更便于生成配色方案,因为色调(H)直接对应色轮上的位置。
然后,函数基于主色调的色调值生成各种配色方案:
- 互补色:H + 180°
- 类似色:H ± 30°
- 三角配色:H + 120°、H + 240°
- 分裂互补色:H ± 150°
最后,函数将所有生成的 HSL 颜色转换回 RGB 和 HEX 格式,并返回一个格式化的结果字符串。
JavaScript 编译代码
// 编译后的 JavaScript 代码(部分示例)
function webDesignColorSchemeGenerator(inputData) {
if (inputData === undefined) {
inputData = "FF6B35";
}
if (inputData.length === 0) {
return "❌ 错误: 输入不能为空\n请输入: 主色调 (HEX 格式, 如: FF6B35)";
}
var hexColor = inputData.trim().toUpperCase();
// 验证十六进制格式
var hexRegex = /^[0-9A-F]{6}$/;
if (!hexRegex.test(hexColor)) {
return "❌ 错误: 颜色格式不正确\n请使用6位十六进制格式 (例如: FF6B35)";
}
// 转换HEX到RGB
var r = parseInt(hexColor.substring(0, 2), 16);
var g = parseInt(hexColor.substring(2, 4), 16);
var b = parseInt(hexColor.substring(4, 6), 16);
// 转换RGB到HSL
var rNorm = r / 255.0;
var gNorm = g / 255.0;
var bNorm = b / 255.0;
var max = Math.max(rNorm, gNorm, bNorm);
var min = Math.min(rNorm, gNorm, bNorm);
var l = (max + min) / 2.0;
var h;
if (max === min) {
h = 0;
} else if (max === rNorm) {
h = (60 * (((gNorm - bNorm) / (max - min)) % 6) + 360) % 360;
} else if (max === gNorm) {
h = (60 * (((bNorm - rNorm) / (max - min)) + 2)) % 360;
} else {
h = (60 * (((rNorm - gNorm) / (max - min)) + 4)) % 360;
}
var s;
if (max === min) {
s = 0;
} else if (l < 0.5) {
s = (max - min) / (max + min);
} else {
s = (max - min) / (2.0 - max - min);
}
// 生成互补色
var complementaryH = (h + 180) % 360;
var complementaryRgb = hslToRgb(complementaryH, s, l);
var complementaryHex = rgbToHex(complementaryRgb[0], complementaryRgb[1], complementaryRgb[2]);
// 生成类似色
var analogousH1 = (h + 30) % 360;
var analogousH2 = (h - 30 + 360) % 360;
var analogousRgb1 = hslToRgb(analogousH1, s, l);
var analogousRgb2 = hslToRgb(analogousH2, s, l);
var analogousHex1 = rgbToHex(analogousRgb1[0], analogousRgb1[1], analogousRgb1[2]);
var analogousHex2 = rgbToHex(analogousRgb2[0], analogousRgb2[1], analogousRgb2[2]);
// 生成三角配色
var triadic1H = (h + 120) % 360;
var triadic2H = (h + 240) % 360;
var triadicRgb1 = hslToRgb(triadic1H, s, l);
var triadicRgb2 = hslToRgb(triadic2H, s, l);
var triadicHex1 = rgbToHex(triadicRgb1[0], triadicRgb1[1], triadicRgb1[2]);
var triadicHex2 = rgbToHex(triadicRgb2[0], triadicRgb2[1], triadicRgb2[2]);
// 生成分裂互补色
var splitComplementary1H = (h + 150) % 360;
var splitComplementary2H = (h - 150 + 360) % 360;
var splitComplementaryRgb1 = hslToRgb(splitComplementary1H, s, l);
var splitComplementaryRgb2 = hslToRgb(splitComplementary2H, s, l);
var splitComplementaryHex1 = rgbToHex(splitComplementaryRgb1[0], splitComplementaryRgb1[1], splitComplementaryRgb1[2]);
var splitComplementaryHex2 = rgbToHex(splitComplementaryRgb2[0], splitComplementaryRgb2[1], splitComplementaryRgb2[2]);
// 生成浅色和深色变体
var lightRgb = hslToRgb(h, s, 0.8);
var lightHex = rgbToHex(lightRgb[0], lightRgb[1], lightRgb[2]);
var darkRgb = hslToRgb(h, s, 0.3);
var darkHex = rgbToHex(darkRgb[0], darkRgb[1], darkRgb[2]);
// 获取颜色名称
var colorName = getColorName(h);
var designTips = [
"• 主色用于品牌标识和重点元素",
"• 互补色用于强调和对比",
"• 类似色用于和谐的过渡",
"• 三角配色适合复杂的设计",
"• 浅色用于背景,深色用于文本",
"• 确保颜色对比度满足无障碍要求"
];
return "🎨 网页设计配色方案生成器\n" +
"━━━━━━━━━━━━━━━━━━━━━\n" +
"🌈 主色调信息\n" +
"HEX: #" + hexColor + "\n" +
"RGB: (" + r + ", " + g + ", " + b + ")\n" +
"HSL: (" + (Math.floor(h * 100) / 100) + "°, " + Math.floor(s * 100) + "%, " + Math.floor(l * 100) + "%)\n" +
"颜色: " + colorName + "\n\n" +
"🎯 互补色配色\n" +
"互补色: #" + complementaryHex + "\n" +
"说明: 对比度最高,用于强调\n\n" +
"🔄 类似色配色\n" +
"类似色1: #" + analogousHex1 + "\n" +
"类似色2: #" + analogousHex2 + "\n" +
"说明: 和谐统一,视觉舒适\n\n" +
"△ 三角配色\n" +
"颜色1: #" + triadicHex1 + "\n" +
"颜色2: #" + triadicHex2 + "\n" +
"说明: 三个颜色均匀分布,活力十足\n\n" +
"◇ 分裂互补色\n" +
"颜色1: #" + splitComplementaryHex1 + "\n" +
"颜色2: #" + splitComplementaryHex2 + "\n" +
"说明: 平衡的对比,不过于刺眼\n\n" +
"💫 色彩变体\n" +
"浅色: #" + lightHex + " (背景色)\n" +
"深色: #" + darkHex + " (文本色)\n\n" +
"💡 设计建议\n" +
designTips.join("\n") + "\n\n" +
"📋 应用场景\n" +
"• 网站品牌色: #" + hexColor + "\n" +
"• 按钮色: #" + complementaryHex + "\n" +
"• 背景色: #" + lightHex + "\n" +
"• 文本色: #" + darkHex + "\n" +
"• 强调色: #" + triadicHex1 + "\n\n" +
"━━━━━━━━━━━━━━━━━━━━━\n" +
"✅ 配色方案生成完成!";
}
function getColorName(hue) {
if (hue < 15 || hue >= 345) return "红色";
if (hue < 45) return "橙色";
if (hue < 75) return "黄色";
if (hue < 105) return "黄绿色";
if (hue < 135) return "绿色";
if (hue < 165) return "青绿色";
if (hue < 195) return "青色";
if (hue < 225) return "蓝色";
if (hue < 255) return "紫蓝色";
if (hue < 285) return "紫色";
if (hue < 315) return "洋红色";
return "红紫色";
}
function hslToRgb(h, s, l) {
var c = (1 - Math.abs(2 * l - 1)) * s;
var hPrime = h / 60.0;
var x = c * (1 - Math.abs(hPrime % 2 - 1));
var r1, g1, b1;
if (hPrime < 1) {
r1 = c; g1 = x; b1 = 0;
} else if (hPrime < 2) {
r1 = x; g1 = c; b1 = 0;
} else if (hPrime < 3) {
r1 = 0; g1 = c; b1 = x;
} else if (hPrime < 4) {
r1 = 0; g1 = x; b1 = c;
} else if (hPrime < 5) {
r1 = x; g1 = 0; b1 = c;
} else {
r1 = c; g1 = 0; b1 = x;
}
var m = l - c / 2;
var r = Math.floor((r1 + m) * 255);
var g = Math.floor((g1 + m) * 255);
var b = Math.floor((b1 + m) * 255);
return [r, g, b];
}
function rgbToHex(r, g, b) {
var rHex = r.toString(16).padStart(2, '0').toUpperCase();
var gHex = g.toString(16).padStart(2, '0').toUpperCase();
var bHex = b.toString(16).padStart(2, '0').toUpperCase();
return rHex + gHex + bHex;
}
JavaScript 代码详解
Kotlin 代码编译到 JavaScript 后,保留了原有的逻辑结构,但使用 JavaScript 的语法和 API。主要的转换包括:
- 数学函数:Kotlin 的
maxOf()和minOf()转换为 JavaScript 的Math.max()和Math.min() - 条件语句:Kotlin 的
when表达式转换为 JavaScript 的if-else链 - 字符串操作:Kotlin 的
padStart()转换为 JavaScript 的padStart() - 数组操作:Kotlin 的
Triple转换为 JavaScript 的数组
ArkTS 调用代码
import { webDesignColorSchemeGenerator } from './hellokjs';
@Entry
@Component
struct Index {
@State message: string = '准备就绪';
@State mainColor: string = 'FF6B35';
@State resultText: string = '';
@State isLoading: boolean = false;
aboutToAppear(): void {
this.generateNewCase();
}
generateNewCase(): void {
this.resultText = '';
this.message = '准备就绪';
const samples = [
'FF6B35',
'0066CC',
'00CC99',
'FF3366',
'FFCC00',
'9933FF',
'33CC99',
'FF9900'
];
const random = samples[Math.floor(Math.random() * samples.length)];
this.mainColor = random;
}
generate(): void {
this.isLoading = true;
try {
const result: string = webDesignColorSchemeGenerator(this.mainColor);
this.resultText = result;
console.log(result);
this.message = '✓ 配色方案生成完成';
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
this.message = `✗ 错误: ${errorMessage}`;
} finally {
this.isLoading = false;
}
}
build() {
Column() {
// ===== 顶部标题栏 - 设计蓝色主题 =====
Column() {
Text('🎨 Web Design Color Scheme')
.fontSize(28)
.fontWeight(FontWeight.Bold)
.fontColor(Color.White)
.margin({ bottom: 8 })
Text('Professional Color Palette Generator')
.fontSize(13)
.fontColor('#B3E5FC')
}
.width('100%')
.padding(24)
.backgroundColor('#0277BD')
.alignItems(HorizontalAlign.Start)
// ===== 主内容区域 =====
Scroll() {
Column() {
// 输入卡片
Column() {
Row() {
Text('🎨 Main Color')
.fontSize(16)
.fontWeight(FontWeight.Bold)
.fontColor('#FFFFFF')
Blank()
Text('🎲 Random')
.fontSize(12)
.fontColor(Color.White)
.padding({ left: 10, right: 10, top: 6, bottom: 6 })
.backgroundColor('#004D7A')
.borderRadius(12)
.onClick(() => {
this.generateNewCase();
})
}
.width('100%')
.margin({ bottom: 18 })
// 颜色输入
TextInput({ placeholder: 'Main Color (HEX)', text: this.mainColor })
.width('100%')
.height(50)
.padding(14)
.fontSize(15)
.fontColor('#000000')
.placeholderColor('#999999')
.border({ width: 2, color: '#0277BD' })
.borderRadius(12)
.backgroundColor('#E1F5FE')
.onChange((value: string) => {
this.mainColor = value;
})
.margin({ bottom: 20 })
// 生成按钮
Button(this.isLoading ? 'Generating...' : 'Generate Palette')
.width('100%')
.height(54)
.fontSize(16)
.fontWeight(FontWeight.Bold)
.fontColor(Color.White)
.backgroundColor(this.isLoading ? '#004D7A' : '#0277BD')
.borderRadius(14)
.onClick(() => {
if (!this.isLoading) {
this.generate();
}
})
}
.width('90%')
.padding(20)
.backgroundColor('#FFFFFF')
.borderRadius(16)
.margin({ top: 20, bottom: 20, left: 'auto', right: 'auto' })
.border({ width: 2, color: '#0277BD' })
// 状态提示卡片
if (this.message !== '准备就绪') {
Row() {
Text(this.message.startsWith('✓') ? '✅' : '⚠️')
.fontSize(20)
.margin({ right: 12 })
Text(this.message)
.fontSize(14)
.fontColor(this.message.startsWith('✓') ? '#4ECDC4' : '#FF6B6B')
.fontWeight(FontWeight.Bold)
.layoutWeight(1)
}
.width('90%')
.padding(16)
.backgroundColor(this.message.startsWith('✓') ? '#1a3a3a' : '#3a1a1a')
.border({ width: 2, color: this.message.startsWith('✓') ? '#4ECDC4' : '#FF6B6B' })
.borderRadius(14)
.margin({ bottom: 20, left: 'auto', right: 'auto' })
.alignItems(VerticalAlign.Center)
}
// 结果卡片
if (this.resultText) {
Column() {
Row() {
Text('📊 Color Scheme')
.fontSize(14)
.fontWeight(FontWeight.Bold)
.fontColor('#0277BD')
}
.width('100%')
.padding(14)
.backgroundColor('#E1F5FE')
.borderRadius(12)
.margin({ bottom: 14 })
.border({ width: 1, color: '#0277BD' })
Text(this.resultText)
.fontSize(12)
.fontFamily('monospace')
.fontColor('#004D7A')
.width('100%')
.padding(14)
.backgroundColor('#E1F5FE')
.borderRadius(12)
.border({ width: 1, color: '#0288D1' })
}
.width('90%')
.padding(16)
.backgroundColor('#E1F5FE')
.borderRadius(16)
.margin({ bottom: 20, left: 'auto', right: 'auto' })
.border({ width: 2, color: '#0277BD' })
}
// 底部提示
Column() {
Row() {
Text('💡')
.fontSize(18)
.margin({ right: 10 })
Text('🎨 Design Tips')
.fontSize(14)
.fontWeight(FontWeight.Bold)
.fontColor('#0277BD')
}
.width('100%')
.margin({ bottom: 12 })
Text('• Enter a main color in HEX format\n• Generate multiple color schemes\n• Get professional design advice\n• Create harmonious palettes')
.fontSize(12)
.fontColor('#004D7A')
.lineHeight(1.6)
}
.width('90%')
.padding(16)
.backgroundColor('#E1F5FE')
.borderRadius(16)
.margin({ bottom: 20, left: 'auto', right: 'auto' })
.border({ width: 2, color: '#0277BD' })
Blank()
.height(20)
}
.width('100%')
}
.layoutWeight(1)
}
.width('100%')
.height('100%')
.backgroundColor('#E1F5FE')
}
}
ArkTS 代码详解
这个 ArkTS 组件实现了网页设计配色方案生成工具的用户界面。组件使用了 OpenHarmony 的 ArkTS 语言,提供了一个现代化的、设计蓝色主题的用户界面。
组件定义了一个 @State 属性来存储主色调。这个属性与输入框绑定,当用户输入数据时,这个属性会自动更新。
generateNewCase() 方法生成随机的颜色样本,帮助用户快速测试应用。用户可以点击"Random"按钮来生成随机数据。
generate() 方法调用 Kotlin 编译的 JavaScript 函数 webDesignColorSchemeGenerator(),并将主色调作为参数传递。函数返回的配色方案会显示在结果卡片中。
用户界面包括一个输入框(主色调)、一个生成按钮、一个状态提示卡片、一个结果卡片和一个提示卡片。所有元素都使用了设计蓝色主题。
实战案例
案例 1:橙色配色方案
输入:FF6B35
系统生成的配色方案:
- 主色调:#FF6B35(橙色)
- 互补色:#35B8FF(蓝色)
- 类似色1:#FFAA35、类似色2:#FF3535
- 三角配色:#35FF6B、#6B35FF
- 分裂互补色:#35FFFF、#FF35AA
- 浅色变体:#FFCC99(背景色)
- 深色变体:#663300(文本色)
案例 2:蓝色配色方案
输入:0066CC
系统生成的配色方案:
- 主色调:#0066CC(蓝色)
- 互补色:#CCAA00(金色)
- 类似色1:#0099CC、类似色2:#0033CC
- 三角配色:#00CC66、#CC0066
- 分裂互补色:#00CCAA、#CC0033
- 浅色变体:#99CCFF(背景色)
- 深色变体:#003366(文本色)
案例 3:绿色配色方案
输入:00CC99
系统生成的配色方案:
- 主色调:#00CC99(绿色)
- 互补色:#CC0066(洋红色)
- 类似色1:#00CCCC、类似色2:#00CC66
- 三角配色:#CC0099、#99CC00
- 分裂互补色:#CC0033、#CC3300
- 浅色变体:#99FFEE(背景色)
- 深色变体:#003333(文本色)
最佳实践
1. 选择合适的配色方案
不同的配色方案适用于不同的设计场景:
- 互补色:用于需要高对比度和强调的设计
- 类似色:用于需要和谐统一的设计
- 三角配色:用于复杂的设计和多元素布局
- 分裂互补色:用于需要对比但又不过于激进的设计
2. 考虑无障碍性
确保颜色组合满足无障碍要求:
- 对比度:确保文本和背景有足够的对比度
- 色盲友好:不要仅依赖颜色来传达信息
- 测试:在不同的显示设备上测试颜色
3. 建立色彩系统
创建一个完整的色彩系统:
- 主色:品牌标识和重点元素
- 辅助色:强调和对比
- 背景色:浅色变体
- 文本色:深色变体
4. 保持一致性
在整个设计中保持颜色的一致性:
- 品牌一致性:使用相同的主色调
- 视觉层次:使用不同的颜色表示不同的优先级
- 文化考虑:考虑不同文化对颜色的理解
5. 测试和迭代
不断测试和改进配色方案:
- 用户反馈:收集用户对颜色的反馈
- A/B 测试:测试不同的配色方案
- 性能监控:监控不同配色方案的用户参与度
总结
网页设计中的颜色选择 - 配色方案生成工具展示了如何使用 Kotlin Multiplatform 技术创建一个功能丰富、跨端兼容的配色方案生成应用。通过采用色彩理论的原理,系统能够帮助设计师快速生成专业的配色方案。
这个案例不仅展示了 KMP 的强大功能,还演示了如何将色彩科学和设计理论知识转化为实用的应用功能。无论是网页设计、移动应用还是品牌设计,设计师都可以使用这个工具来快速生成和谐的配色方案,提高设计效率和质量。
通过使用这个配色方案生成工具,设计师可以确保他们的设计在视觉上和谐、专业且易于访问,为用户创造更好的视觉体验。
更多推荐



所有评论(0)