diff --git a/miniprogram 2.zip b/miniprogram 2.zip deleted file mode 100644 index 454e29e..0000000 Binary files a/miniprogram 2.zip and /dev/null differ diff --git a/miniprogram.zip b/miniprogram.zip deleted file mode 100644 index 39146c0..0000000 Binary files a/miniprogram.zip and /dev/null differ diff --git a/miniprogram/app.json b/miniprogram/app.json index 1a940c5..711aeb2 100644 --- a/miniprogram/app.json +++ b/miniprogram/app.json @@ -3,7 +3,8 @@ "pages/index/index", "pages/shape/index", "pages/debug/debug", - "pages/wordDemo/index" + "pages/wordDemo/index", + "pages/buttonTest/buttonTest" ], "window": {}, "style": "v2", diff --git a/miniprogram/components/word-card/word-card.less b/miniprogram/components/word-card/word-card.less index 3161446..547b730 100644 --- a/miniprogram/components/word-card/word-card.less +++ b/miniprogram/components/word-card/word-card.less @@ -1,57 +1,70 @@ .word-card { + position: relative; + width: 100%; + height: 200rpx; + background: #FFFFFF; + border-radius: 24rpx; + border: 2rpx solid #E8E8E8; display: flex; - flex-direction: row; - // width: 324rpx; - height: 100rpx; - border-radius: 16rpx; - background-color: #eefcfc; align-items: center; - box-shadow: 0 2rpx 2rpx rgba(0, 0, 0, 0.35); + justify-content: center; + transition: all 0.2s ease-in-out; + box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05); + + &:active { + transform: scale(0.95); + box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1); + } .color-box { - width: 60rpx; - height: 60rpx; + position: absolute; + top: 24rpx; + left: 24rpx; + width: 40rpx; + height: 40rpx; border-radius: 50%; - background-color: #ff0000; - margin-left: 24rpx; - border: 1rpx solid #141414; - - position: relative; - - &::after { - content: ''; - position: absolute; - top: 0; - left: 0; - width: 200%; - height: 200%; - border-radius: 50%; - border: 1px solid #141414; - transform: scale(0.5); - transform-origin: 0 0; - box-sizing: border-box; - } + border: 4rpx solid #FFFFFF; + box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.1); } .word-box { - margin: 0 16rpx 0 36rpx; display: flex; justify-content: center; align-items: center; - width: 82rpx; - height: 52rpx; - border: 1rpx solid #000; - background-color: #fff; + width: 100%; + height: 100%; .word-content { - font-size: 28rpx; + font-size: 72rpx; + font-weight: 600; color: #141414; text-align: center; } } .delete-icon { - padding: 20rpx; - color: rgba(255, 0, 0, 0.7); + position: absolute; + top: -12rpx; + right: -12rpx; + width: 40rpx; + height: 40rpx; + background: #FF4757; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + color: #FFFFFF; + font-size: 32rpx; + font-weight: bold; + box-shadow: 0 2rpx 6rpx rgba(255, 71, 87, 0.3); + transition: all 0.2s ease-in-out; + + &:active { + transform: scale(0.9); + } + + .delete-icon-inner { + color: #FFFFFF !important; + } } } \ No newline at end of file diff --git a/miniprogram/components/word-card/word-card.wxml b/miniprogram/components/word-card/word-card.wxml index dc35d5c..6b4ee39 100644 --- a/miniprogram/components/word-card/word-card.wxml +++ b/miniprogram/components/word-card/word-card.wxml @@ -3,7 +3,7 @@ class="color-box" style="background-color: {{color}};" bindtap="onColorTap"> - + {{word}} @@ -11,6 +11,6 @@ class-prefix="toy-icon" name="dustbin-o" custom-class="delete-icon-inner" - size="48rpx" /> + size="32rpx" /> diff --git a/miniprogram/pages/buttonTest/buttonTest.json b/miniprogram/pages/buttonTest/buttonTest.json new file mode 100644 index 0000000..ae35187 --- /dev/null +++ b/miniprogram/pages/buttonTest/buttonTest.json @@ -0,0 +1,10 @@ +{ + "navigationBarTitleText": "按钮组件测试", + "navigationBarBackgroundColor": "#FFD719", + "backgroundColor": "#F6F6F6", + "usingComponents": { + "toy-button": "../../ui/button/button", + "van-icon": "@vant/weapp/icon/index", + "word-card": "../../components/word-card/word-card" + } +} diff --git a/miniprogram/pages/buttonTest/buttonTest.less b/miniprogram/pages/buttonTest/buttonTest.less new file mode 100644 index 0000000..d9f9016 --- /dev/null +++ b/miniprogram/pages/buttonTest/buttonTest.less @@ -0,0 +1,34 @@ +page { + background-color: #F6F6F6; +} + +.button-test-container { + padding: 40rpx; +} + +.test-section { + margin-bottom: 60rpx; +} + +.section-title { + display: block; + font-size: 32rpx; + font-weight: 600; + color: #141414; + margin-bottom: 24rpx; +} + +.button-group { + display: flex; + flex-direction: column; + gap: 24rpx; + align-items: flex-start; +} + +.word-cards-grid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 32rpx; + width: 100%; + max-width: 600rpx; +} \ No newline at end of file diff --git a/miniprogram/pages/buttonTest/buttonTest.ts b/miniprogram/pages/buttonTest/buttonTest.ts new file mode 100644 index 0000000..9df8451 --- /dev/null +++ b/miniprogram/pages/buttonTest/buttonTest.ts @@ -0,0 +1,28 @@ +Page({ + data: {}, + + onButtonClick(e: WechatMiniprogram.TouchEvent) { + console.log('按钮点击:', e); + wx.showToast({ + title: '按钮被点击了', + icon: 'success', + duration: 1000 + }); + }, + + onWordColorTap(e: any) { + console.log('点击了颜色:', e); + wx.showToast({ + title: '点击了颜色', + icon: 'none', + }); + }, + + onWordDelete(e: any) { + console.log('删除文字:', e); + wx.showToast({ + title: '删除文字', + icon: 'none', + }); + } +}); diff --git a/miniprogram/pages/buttonTest/buttonTest.wxml b/miniprogram/pages/buttonTest/buttonTest.wxml new file mode 100644 index 0000000..8331d2b --- /dev/null +++ b/miniprogram/pages/buttonTest/buttonTest.wxml @@ -0,0 +1,160 @@ + + + 主要按钮 (Primary) + + 主要按钮 + 禁用状态 + 加载中 + + + + + 次要按钮 (Secondary) + + 次要按钮 + 禁用状态 + 加载中 + + + + + 绿色按钮 (Green) + + 绿色按钮 + 禁用状态 + 加载中 + + + + + 白色按钮 (White) + + 白色按钮 + 禁用状态 + 透明模式 + + + + + 扁平化按钮 (Flat) + + 扁平主要 + 扁平次要 + 扁平白色 + + + + + 带图标按钮 + + 添加 + 删除 + 编辑 + + + + + 不同尺寸 + + + 小按钮 + + 中按钮 + + 大按钮 + + + + + + + 点击动效测试 + + 点击我测试动效 + 抖动效果 + 缩放动画 + + + + + Word Card 测试 + + + + + + + + + + + diff --git a/miniprogram/pages/index/index.less b/miniprogram/pages/index/index.less index d3e5726..232ec23 100644 --- a/miniprogram/pages/index/index.less +++ b/miniprogram/pages/index/index.less @@ -16,7 +16,7 @@ page { background-color: #ffffff; border-radius: 20rpx; padding: 24rpx; - box-shadow: 0 3rpx 4rpx rgba(0, 0, 0, 0.15); + box-shadow: 0 6rpx 8rpx rgba(0, 0, 0, 0.15); margin: 30rpx 0; display: flex; flex-direction: column; @@ -42,15 +42,10 @@ page { color: #999; } - .word-card-list { - display: flex; - flex-direction: row; - justify-content: space-between; - margin-bottom: 24rpx; - - &:last-child { - margin-bottom: 0; - } + .word-cards-grid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 24rpx; } } diff --git a/miniprogram/pages/index/index.wxml b/miniprogram/pages/index/index.wxml index 8865c76..98fd9e1 100644 --- a/miniprogram/pages/index/index.wxml +++ b/miniprogram/pages/index/index.wxml @@ -12,33 +12,20 @@ - - + - - - - - - - - - 请选择或输入文字,生成涂鸦卡 - - + wx:for-index="index" + word="{{item.word}}" + color="{{item.color}}" + bind:onDelete="deleteWordCard" + bind:onColorTap="onColorTap" /> + + + 请选择或输入文字,生成涂鸦卡 + +主要按钮 + + +次要按钮 + + +绿色按钮 + + +白色按钮 +``` + +### 按钮状态 + +```xml + +禁用按钮 + + +加载中 + + +扁平按钮 +``` + +### 带图标按钮 + +```xml + +添加 + + +编辑 +``` + +### 自定义尺寸 + +```xml + +自定义宽度 + + +自定义高度 +``` + +## 属性说明 + +| 属性 | 类型 | 默认值 | 说明 | +| --------------- | ------- | ---------- | ------------------------------------------ | +| type | String | 'default' | 按钮类型:primary、secondary、green、white | +| disabled | Boolean | false | 是否禁用 | +| loading | Boolean | false | 是否显示加载状态 | +| flat | Boolean | false | 是否扁平化模式 | +| plain | Boolean | false | 是否朴素模式(仅white类型有效) | +| width | String | '' | 按钮宽度 | +| height | String | '' | 按钮高度 | +| icon | String | '' | 图标名称 | +| iconColor | String | '#ffffff' | 图标颜色 | +| iconSize | String | '44rpx' | 图标大小 | +| iconClassPrefix | String | 'toy-icon' | 图标类名前缀 | + +## 事件说明 + +| 事件名 | 说明 | 回调参数 | +| ------ | -------------- | -------- | +| click | 点击按钮时触发 | event | + +## 样式说明 + +### 按钮类型 + +- **primary**: 黄色背景 (#FFD719),深色文字 (#141414) +- **secondary**: 绿色背景 (#93D333),白色文字 +- **green**: 绿色背景 (#93D333),白色文字(与secondary相同) +- **white**: 白色背景,深色文字,带边框 + +### 点击动效 + +- 所有按钮都支持 `scale(0.95)` 的点击缩放效果 +- 扁平化模式下有背景色变化效果 +- 动效持续时间为 150ms + +### 禁用状态 + +- 背景色变为浅灰色 (#F5F5F5) +- 文字颜色变为浅灰色 (#CCCCCC) +- 移除阴影效果 + +## 设计规范 + +本组件完全遵循 doodle-ui 的设计规范: + +- 圆角:24rpx (对应 doodle-ui 的 12px) +- 字体大小:48rpx (对应 doodle-ui 的 24px) +- 字体粗细:600 +- 内边距:0 48rpx +- 最小宽度:240rpx +- 过渡动画:0.15s ease-in-out +- 点击动效:抖动缩放动画 + +## 测试页面 + +可以通过访问 `pages/buttonTest/buttonTest` 页面查看所有按钮类型的效果。 + +## 更新日志 + +### v2.1.0 + +- 修复圆角大小,与 doodle-ui 保持一致 (24rpx) +- 修复字体大小,与 doodle-ui 保持一致 (48rpx) +- 修复点击抖动效果,移除 wxs 中的 setTimeout +- 优化按钮动画,使用纯 CSS 实现抖动效果 +- 改进所有按钮类型的点击反馈 + +### v2.0.0 + +- 完全重构样式,与 doodle-ui 保持一致 +- 添加 secondary 类型支持 +- 优化点击动效 +- 改进扁平化模式 +- 统一设计规范 diff --git a/miniprogram/ui/button/button.less b/miniprogram/ui/button/button.less index ab7d29a..8818bc7 100644 --- a/miniprogram/ui/button/button.less +++ b/miniprogram/ui/button/button.less @@ -1,6 +1,6 @@ -@button-default-height: 86rpx; -@button-border-radius: 18rpx; -@button-default-font-size: 32rpx; +@button-default-height: 80rpx; +@button-border-radius: 16rpx; +@button-default-font-size: 30rpx; @button-default-color: #fff; wx-button:not([size=mini]) { @@ -18,91 +18,109 @@ wx-button:not([size=mini]) { border-radius: @button-border-radius; font-size: @button-default-font-size; color: @button-default-color; - padding: 0 44rpx; - font-weight: normal; - // width: auto !important; - // transition: all 0.04s; + padding: 0 48rpx; + font-weight: 600; + text-align: center; + cursor: pointer; + transition: all 0.15s ease-in-out; + border: none; + min-width: 240rpx; &--primary { - background: rgba(255, 215, 25, 1); - box-shadow: 0px 10rpx 2rpx #DBB917; + background: #FFD719; + box-shadow: 0 4rpx 12rpx rgba(255, 215, 25, 0.3); + color: #141414; &.disabled { - background: rgba(255, 215, 25, 0.5); - box-shadow: 0px 10rpx 2rpx rgba(219, 185, 23, 0.5); + background: #F5F5F5; + color: #CCCCCC; + box-shadow: none; } &.active { - transform: translateY(10rpx); - box-shadow: 0 0 0 rgba(219, 185, 23, 0.5); - /* 阴影效果 */ + transform: scale(0.92); + box-shadow: 0 2rpx 6rpx rgba(255, 215, 25, 0.2); + animation: buttonPress 0.15s ease-in-out; } } &--green { - background: #93d333; - box-shadow: 0px 10rpx 2rpx rgba(121, 185, 21, 1); + background: #93D333; + box-shadow: 0 4rpx 12rpx rgba(147, 211, 51, 0.3); + color: #FFFFFF; &.disabled { - background: rgba(147, 211, 51, 0.5); - box-shadow: 0px 10rpx 2rpx rgba(121, 185, 21, 0.5); + background: #F5F5F5; + color: #CCCCCC; + box-shadow: none; } &.active { - transform: translateY(10rpx); - box-shadow: 0 0 0 rgba(121, 185, 21, 0.5); - /* 阴影效果 */ + transform: scale(0.92); + box-shadow: 0 2rpx 6rpx rgba(147, 211, 51, 0.2); + animation: buttonPress 0.15s ease-in-out; + } + } + + &--secondary { + background: #93D333; + box-shadow: 0 4rpx 12rpx rgba(147, 211, 51, 0.3); + color: #FFFFFF; + + &.disabled { + background: #F5F5F5; + color: #CCCCCC; + box-shadow: none; + } + + &.active { + transform: scale(0.92); + box-shadow: 0 2rpx 6rpx rgba(147, 211, 51, 0.2); + animation: buttonPress 0.15s ease-in-out; } } &--white { - color: rgba(34, 36, 37, 0.9); - background: #fff; - box-shadow: 0 8rpx 0rpx rgba(223, 220, 220, 1); - border: 2rpx solid rgba(223, 220, 220, 1); + background: #FFFFFF; + border: 1rpx solid #E8E8E8; + color: #141414; &.disabled { - color: rgba(34, 36, 37, 0.5); - background: rgba(255, 255, 255, 0.7); - box-shadow: 0px 8rpx 0rpx rgba(223, 220, 220, 0.9); + background: #F5F5F5; + color: #CCCCCC; + border-color: #E8E8E8; } &.plain { - color: #fff; - background: rgba(255, 255, 255, 0.2); - border: 2rpx solid rgba(255, 255, 255, 1); - box-shadow: 0px 8rpx 0rpx rgba(255, 255, 255, 0.88); - - // &.disabled { - // background: rgba(255, 255, 255, 0.2); - // border: 1px solid rgba(255, 255, 255, 0.6); - // box-shadow: 0px 3px 0px rgba(255, 255, 255, 0.6); - // } + color: #FFFFFF; + background: transparent; + border: 1rpx solid #FFFFFF; } &.active { - transform: translateY(8rpx); - box-shadow: 0 0 0 rgba(223, 220, 220, 1); - /* 阴影效果 */ + transform: scale(0.92); + background: #F8F8F8; + animation: buttonPress 0.15s ease-in-out; } } &--flat { box-shadow: none !important; - border: none; - transition: background 0.1s; + border: none !important; + transition: all 0.15s ease-in-out; // 覆盖所有颜色变体 &.toy-button--primary, &.toy-button--green, + &.toy-button--secondary, &.toy-button--white { box-shadow: none !important; border: none !important; &.active { - transform: none !important; - box-shadow: none !important; + transform: scale(0.92) !important; + animation: buttonPress 0.15s ease-in-out !important; } } @@ -113,29 +131,55 @@ wx-button:not([size=mini]) { box-shadow: none !important; } - // 重置active变换 - &.active { - transform: none !important; - } - // 彩色按钮active背景变化 &.toy-button--primary.active { - background: rgba(255, 215, 25, 0.7); + background: rgba(255, 215, 25, 0.8); } &.toy-button--green.active { - background: rgba(147, 211, 51, 0.7); + background: rgba(147, 211, 51, 0.8); + } + + &.toy-button--secondary.active { + background: rgba(147, 211, 51, 0.8); } &.toy-button--white.active { - background: rgba(255, 255, 255, 0.7); + background: rgba(255, 255, 255, 0.8); } } .loading-class, &__icon { - margin-right: 18rpx; + margin-right: 12rpx; } + // 添加按钮点击动画类 + &.button-press { + animation: buttonPress 0.15s ease-in-out; + } +} + +// 按钮点击动画 +@keyframes buttonPress { + 0% { + transform: scale(1); + } + + 25% { + transform: scale(0.92); + } + + 50% { + transform: scale(0.98); + } + + 75% { + transform: scale(0.92); + } + + 100% { + transform: scale(1); + } } \ No newline at end of file diff --git a/miniprogram/ui/button/button.ts b/miniprogram/ui/button/button.ts index d161e1b..df40a2a 100644 --- a/miniprogram/ui/button/button.ts +++ b/miniprogram/ui/button/button.ts @@ -8,7 +8,7 @@ Component({ properties: { type: { type: String, - value: 'default', // primary, green, white + value: 'default', // primary, green, secondary, white }, openType: { type: String, diff --git a/project.config.json b/project.config.json index 92a82f9..e570d17 100644 --- a/project.config.json +++ b/project.config.json @@ -1,70 +1,70 @@ { - "description": "项目配置文件", - "miniprogramRoot": "miniprogram/", - "compileType": "miniprogram", - "cloudfunctionRoot": "cloudfunctions/", - "setting": { - "useCompilerPlugins": [ - "typescript", - "less" - ], - "babelSetting": { - "ignore": [], - "disablePlugins": [], - "outputPath": "" - }, - "urlCheck": true, - "coverView": false, - "postcss": false, - "minified": true, - "minifyWXSS": true, - "enhance": true, - "showShadowRootInWxmlPanel": false, - "packNpmRelationList": [ - { - "packageJsonPath": "./package.json", - "miniprogramNpmDistDir": "./miniprogram/" - } - ], - "ignoreUploadUnusedFiles": true, - "compileHotReLoad": false, - "skylineRenderEnable": true, - "es6": true, - "packNpmManually": true, - "compileWorklet": false, - "uglifyFileName": true, - "uploadWithSourceMap": true, - "minifyWXML": true, - "localPlugins": false, - "disableUseStrict": false, - "condition": false, - "swc": false, - "disableSWC": true + "description": "项目配置文件", + "miniprogramRoot": "miniprogram/", + "compileType": "miniprogram", + "cloudfunctionRoot": "cloudfunctions/", + "setting": { + "useCompilerPlugins": [ + "typescript", + "less" + ], + "babelSetting": { + "ignore": [], + "disablePlugins": [], + "outputPath": "" }, - "simulatorType": "wechat", - "simulatorPluginLibVersion": {}, - "condition": { - "miniprogram": { - "list": [ - { - "name": "db guide", - "pathName": "pages/databaseGuide/databaseGuide", - "query": "" - } - ] + "urlCheck": true, + "coverView": false, + "postcss": false, + "minified": true, + "minifyWXSS": true, + "enhance": true, + "showShadowRootInWxmlPanel": false, + "packNpmRelationList": [ + { + "packageJsonPath": "./package.json", + "miniprogramNpmDistDir": "./miniprogram/" + } + ], + "ignoreUploadUnusedFiles": true, + "compileHotReLoad": false, + "skylineRenderEnable": true, + "es6": true, + "packNpmManually": true, + "compileWorklet": false, + "uglifyFileName": true, + "uploadWithSourceMap": true, + "minifyWXML": true, + "localPlugins": false, + "disableUseStrict": false, + "condition": false, + "swc": false, + "disableSWC": true + }, + "simulatorType": "wechat", + "simulatorPluginLibVersion": {}, + "condition": { + "miniprogram": { + "list": [ + { + "name": "db guide", + "pathName": "pages/databaseGuide/databaseGuide", + "query": "" } - }, - "srcMiniprogramRoot": "miniprogram/", - "editorSetting": { - "tabIndent": "insertSpaces", - "tabSize": 4 - }, - "libVersion": "3.7.12", - "packOptions": { - "ignore": [], - "include": [] - }, - "cloudfunctionTemplateRoot": "cloudfunctionTemplate/", - "appid": "wx4353d20418f2fa37", - "projectname": "doodle-mini" + ] + } + }, + "srcMiniprogramRoot": "miniprogram/", + "editorSetting": { + "tabIndent": "insertSpaces", + "tabSize": 4 + }, + "libVersion": "3.7.12", + "packOptions": { + "ignore": [], + "include": [] + }, + "cloudfunctionTemplateRoot": "cloudfunctionTemplate/", + "appid": "wx4353d20418f2fa37", + "projectname": "doodle-mini" } \ No newline at end of file diff --git a/project.private.config.json b/project.private.config.json index cd23d60..32103a0 100644 --- a/project.private.config.json +++ b/project.private.config.json @@ -24,32 +24,11 @@ "miniprogram": { "list": [ { - "name": "pages/wordDemo/index", - "pathName": "pages/wordDemo/index", + "name": "pages/buttonTest/buttonTest", + "pathName": "pages/buttonTest/buttonTest", "query": "", "scene": null, "launchMode": "default" - }, - { - "name": "pages/shape/index", - "pathName": "pages/shape/index", - "query": "", - "launchMode": "default", - "scene": null - }, - { - "name": "测试图形绘制", - "pathName": "demoPages/shapePrint/index", - "query": "", - "launchMode": "default", - "scene": null - }, - { - "name": "debug页", - "pathName": "pages/debug/debug", - "query": "", - "launchMode": "default", - "scene": null } ] }