Skip to content

Commit

Permalink
feat(fab): 悬浮按钮支持拖拽 (#2478)
Browse files Browse the repository at this point in the history
* feat(fab): 悬浮按钮支持拖拽

#2374

* style(fab): 移动实现逻辑改成touch,兼容webview和skyline框架

* fix(fab): 水平移动或垂直移动异常修复

* style(fab): 代码优化

* docs(fab): 文档更新
  • Loading branch information
hkaikai authored Dec 21, 2023
1 parent eecbe1b commit dc127c3
Show file tree
Hide file tree
Showing 23 changed files with 234 additions and 26 deletions.
1 change: 1 addition & 0 deletions src/fab/README.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ button-props | Object | - | \- | N
icon | String | - | \- | N
style | String | right: 16px; bottom: 32px; | \- | N
text | String | - | \- | N
draggable | Boolean / String | false | \- | N

### Fab Events

Expand Down
1 change: 1 addition & 0 deletions src/fab/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ button-props | Object | - | 透传至 Button 组件 | N
icon | String | - | 图标 | N
style | String | right: 16px; bottom: 32px; | 悬浮按钮的样式,常用于调整位置(即将废弃,建议使用 `style`) | N
text | String | - | 文本内容 | N
draggable | Boolean / String | false | `true` / `'all'`可拖动<br>`'vertical'`可垂直拖动<br>`'horizontal'`可水平拖动<br>`false`禁止拖动 | N

### Fab Events

Expand Down
10 changes: 10 additions & 0 deletions src/fab/_example/draggable/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Component({
methods: {
handleClick(e) {
console.log(e);
},
handleMove(e) {
console.log(e);
},
},
});
6 changes: 6 additions & 0 deletions src/fab/_example/draggable/index.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"component": true,
"usingComponents": {
"t-fab": "tdesign-miniprogram/fab/fab"
}
}
8 changes: 8 additions & 0 deletions src/fab/_example/draggable/index.wxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<t-fab
icon="gesture-press"
text="拖我"
bind:click="handleClick"
bind:move="handleMove"
aria-label="增加"
draggable="{{true}}"
></t-fab>
Empty file.
3 changes: 2 additions & 1 deletion src/fab/_example/fab.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"usingComponents": {
"t-button": "tdesign-miniprogram/button/button",
"base": "./base",
"advance": "./advance"
"advance": "./advance",
"draggable": "./draggable"
}
}
10 changes: 9 additions & 1 deletion src/fab/_example/fab.wxml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@
</t-button>
</view>
</t-demo>
<t-demo desc="可移动悬浮按钮">
<view class="wrapper">
<t-button theme="primary" size="large" block variant="outline" bind:tap="handleChange" data-type="movable">
可移动悬浮按钮
</t-button>
</view>
</t-demo>

<base wx:if="{{type == 'base'}}" />
<advance wx:else />
<advance wx:elif="{{type == 'advance'}}" />
<draggable wx:else />
4 changes: 4 additions & 0 deletions src/fab/draggable/draggable.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"component": true,
"usingComponents": {}
}
5 changes: 5 additions & 0 deletions src/fab/draggable/draggable.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@import '../../common/style/index.less';

.@{prefix}-draggable {
position: absolute;
}
64 changes: 64 additions & 0 deletions src/fab/draggable/draggable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { SuperComponent, wxComponent } from '../../common/src/index';
import config from '../../common/config';
import props from './props';
import { getRect } from '../../common/utils';
import type { TdDraggableProps } from './type';

const systemInfo = wx.getSystemInfoSync();
const { prefix } = config;
const name = `${prefix}-draggable`;

export interface DraggableProps extends TdDraggableProps {}

@wxComponent()
export default class Draggable extends SuperComponent {
properties = props;

externalClasses = [`${prefix}-class`];

data = {
prefix,
classPrefix: name,
};

lifetimes = {
ready() {
this.computedRect();
},
};

methods = {
onTouchStart(e) {
if (this.properties.direction === 'none') return;
this.startX = e.touches[0].clientX + systemInfo.windowWidth - this.rect.right;
this.startY = e.touches[0].clientY + systemInfo.windowHeight - this.rect.bottom;
this.triggerEvent('start', { startX: this.startX, startY: this.startY, rect: this.rect, e });
},

onTouchMove(e) {
if (this.properties.direction === 'none') return;
let x = this.startX - e.touches[0].clientX; // x轴移动偏移量
let y = this.startY - e.touches[0].clientY; // y轴移动偏移量

if (this.properties.direction === 'vertical') {
x = systemInfo.windowWidth - this.rect.right;
}
if (this.properties.direction === 'horizontal') {
y = systemInfo.windowHeight - this.rect.bottom;
}

this.triggerEvent('move', { x, y, rect: this.rect, e });
},

async onTouchEnd(e) {
if (this.properties.direction === 'none') return;
await this.computedRect();
this.triggerEvent('end', { rect: this.rect, e });
},

async computedRect() {
this.rect = { right: 0, bottom: 0, width: 0, height: 0 };
this.rect = await getRect(this, `.${this.data.classPrefix}`);
},
};
}
11 changes: 11 additions & 0 deletions src/fab/draggable/draggable.wxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<wxs src="../../common/utils.wxs" module="_" />

<view
class="{{classPrefix}} class {{prefix}}-class"
style="{{_._style([style, customStyle])}}"
bind:touchstart="onTouchStart"
bind:touchmove="onTouchMove"
bind:touchend="onTouchEnd"
>
<slot></slot>
</view>
3 changes: 3 additions & 0 deletions src/fab/draggable/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './props';
export * from './type';
export * from './draggable';
11 changes: 11 additions & 0 deletions src/fab/draggable/props.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { TdDraggableProps } from './type';

const props: TdDraggableProps = {
/** 移动方向 */
direction: {
type: String,
value: 'all',
},
};

export default props;
10 changes: 10 additions & 0 deletions src/fab/draggable/type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export interface TdDraggableProps {
/**
* 移动方向
* @default 'all'
*/
direction?: {
type: StringConstructor;
value?: 'all' | 'vertical' | 'horizontal' | 'none';
};
}
3 changes: 2 additions & 1 deletion src/fab/fab.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"component": true,
"usingComponents": {
"t-button": "../button/button"
"t-button": "../button/button",
"t-draggable": "./draggable/draggable"
}
}
4 changes: 4 additions & 0 deletions src/fab/fab.less
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,8 @@
&__button {
box-shadow: @fab-shadow;
}

&__draggable {
position: fixed;
}
}
49 changes: 37 additions & 12 deletions src/fab/fab.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,15 @@ import { SuperComponent, wxComponent } from '../common/src/index';
import config from '../common/config';
import props from './props';

const systemInfo = wx.getSystemInfoSync();
const { prefix } = config;
const name = `${prefix}-fab`;
const baseButtonProps = {
size: 'large',
shape: 'circle',
theme: 'primary',
externalClass: `${prefix}-fab__button`,
};

@wxComponent()
export default class Fab extends SuperComponent {
Expand All @@ -14,28 +21,46 @@ export default class Fab extends SuperComponent {
data = {
prefix,
classPrefix: name,
baseButtonProps: {
size: 'large',
shape: 'circle',
theme: 'primary',
},
buttonData: baseButtonProps,
moveStyle: null,
};

observers = {
text(val) {
if (val) {
this.setData({
baseButtonProps: {
shape: 'round',
'buttonProps.**, icon, text, ariaLabel'() {
this.setData(
{
buttonData: {
...baseButtonProps,
shape: this.properties.text ? 'round' : 'circle',
icon: this.properties.icon,
...this.properties.buttonProps,
content: this.properties.text,
ariaLabel: this.properties.ariaLabel,
},
});
}
},
this.computedSize,
);
},
};

methods = {
onTplButtonTap(e) {
this.triggerEvent('click', e);
},
onMove(e) {
const { x, y, rect } = e.detail;
const maxX = systemInfo.windowWidth - rect.width; // 父容器宽度 - 拖动元素宽度
const maxY = systemInfo.windowHeight - rect.height; // 父容器高度 - 拖动元素高度
const right = Math.max(0, Math.min(x, maxX));
const bottom = Math.max(0, Math.min(y, maxY));
this.setData({
moveStyle: `right: ${right}px; bottom: ${bottom}px;`,
});
},
computedSize() {
if (!this.properties.draggable) return;
const insChild = this.selectComponent('#draggable');
insChild.computedRect(); // button更新时,重新获取其尺寸
},
};
}
17 changes: 6 additions & 11 deletions src/fab/fab.wxml
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
<import src="../common/template/button.wxml" />
<wxs src="../common/utils.wxs" module="_" />
<import src="./template/view.wxml" />
<import src="./template/draggable.wxml" />

<view
class="{{classPrefix}} class {{prefix}}-class"
style="right: 16px; bottom: 32px; {{_._style([style, customStyle])}}"
>
<template
is="button"
data="{{ ...baseButtonProps, icon, ...buttonProps, externalClass: prefix + '-fab__button', content: text, ariaLabel}}"
/>
</view>
<template
is="{{draggable ? 'draggable' : 'view'}}"
data="{{prefix, classPrefix, style, customStyle, moveStyle, draggable, buttonData}}"
/>
6 changes: 6 additions & 0 deletions src/fab/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ const props: TdFabProps = {
type: String,
value: '',
},
/** 是否可移动 */
draggable: {
type: Boolean,
optionalTypes: [String],
value: false,
},
};

export default props;
14 changes: 14 additions & 0 deletions src/fab/template/draggable.wxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<import src="../../common/template/button.wxml" />
<wxs src="../../common/utils.wxs" module="_" />

<template name="draggable">
<t-draggable
id="draggable"
style="right: 16px; bottom: 32px; {{_._style([style, customStyle, moveStyle])}}"
t-class="{{prefix}}}-fab__button"
direction="{{draggable === true ? 'all' : draggable}}"
bind:move="onMove"
>
<template is="button" data="{{...buttonData}}" />
</t-draggable>
</template>
11 changes: 11 additions & 0 deletions src/fab/template/view.wxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<import src="../../common/template/button.wxml" />
<wxs src="../../common/utils.wxs" module="_" />

<template name="view">
<view
class="{{classPrefix}} class {{prefix}}-class"
style="right: 16px; bottom: 32px; {{_._style([style, customStyle])}}"
>
<template is="button" data="{{...buttonData}}" />
</view>
</template>
9 changes: 9 additions & 0 deletions src/fab/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,13 @@ export interface TdFabProps {
type: StringConstructor;
value?: string;
};
/**
* 是否可移动
* @default false
*/
draggable?: {
type: BooleanConstructor;
optionalTypes: Array<StringConstructor>;
value?: boolean | 'all' | 'vertical' | 'horizontal';
};
}

0 comments on commit dc127c3

Please sign in to comment.