[新增]wxmlToCanvas
This commit is contained in:
1186
node_modules/widget-ui/src/css-layout.js
generated
vendored
Normal file
1186
node_modules/widget-ui/src/css-layout.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
172
node_modules/widget-ui/src/element.ts
generated
vendored
Normal file
172
node_modules/widget-ui/src/element.ts
generated
vendored
Normal file
@@ -0,0 +1,172 @@
|
||||
|
||||
import computeLayout from "./css-layout";
|
||||
import { getDefaultStyle, scalableStyles, layoutAffectedStyles } from "./style";
|
||||
|
||||
type LayoutData = {
|
||||
left: number,
|
||||
top: number,
|
||||
width: number,
|
||||
height: number
|
||||
};
|
||||
|
||||
type LayoutNode = {
|
||||
id: number,
|
||||
style: Object,
|
||||
children: LayoutNode[],
|
||||
layout?: LayoutData
|
||||
};
|
||||
|
||||
let uuid = 0;
|
||||
|
||||
class Element {
|
||||
public static uuid(): number {
|
||||
return uuid++;
|
||||
}
|
||||
|
||||
public parent: Element | null = null;
|
||||
public id: number = Element.uuid();
|
||||
public style: { [key: string]: any } = {};
|
||||
public computedStyle: { [key: string]: any } = {};
|
||||
public lastComputedStyle: { [key: string]: any } = {};
|
||||
public children: { [key: string]: Element } = {};
|
||||
public layoutBox: LayoutData = { left: 0, top: 0, width: 0, height: 0 };
|
||||
|
||||
constructor(style: { [key: string]: any } = {}) {
|
||||
// 拷贝一份,防止被外部逻辑修改
|
||||
style = Object.assign(getDefaultStyle(), style);
|
||||
this.computedStyle = Object.assign(getDefaultStyle(), style);
|
||||
this.lastComputedStyle = Object.assign(getDefaultStyle(), style);
|
||||
|
||||
Object.keys(style).forEach(key => {
|
||||
Object.defineProperty(this.style, key, {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
get: () => style[key],
|
||||
set: (value: any) => {
|
||||
if (value === style[key] || value === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.lastComputedStyle = this.computedStyle[key]
|
||||
style[key] = value
|
||||
this.computedStyle[key] = value
|
||||
|
||||
// 如果设置的是一个可缩放的属性, 计算自己
|
||||
if (scalableStyles.includes(key) && this.style.scale) {
|
||||
this.computedStyle[key] = value * this.style.scale
|
||||
}
|
||||
|
||||
// 如果设置的是 scale, 则把所有可缩放的属性计算
|
||||
if (key === "scale") {
|
||||
scalableStyles.forEach(prop => {
|
||||
if (style[prop]) {
|
||||
this.computedStyle[prop] = style[prop] * value
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (key === "hidden") {
|
||||
if (value) {
|
||||
layoutAffectedStyles.forEach((key: string) => {
|
||||
this.computedStyle[key] = 0;
|
||||
});
|
||||
} else {
|
||||
layoutAffectedStyles.forEach((key: string) => {
|
||||
this.computedStyle[key] = this.lastComputedStyle[key];
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
if (this.style.scale) {
|
||||
scalableStyles.forEach((key: string) => {
|
||||
if (this.style[key]) {
|
||||
const computedValue = this.style[key] * this.style.scale;
|
||||
this.computedStyle[key] = computedValue;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (style.hidden) {
|
||||
layoutAffectedStyles.forEach((key: string) => {
|
||||
this.computedStyle[key] = 0;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
getAbsolutePosition(element: Element) {
|
||||
if (!element) {
|
||||
return this.getAbsolutePosition(this)
|
||||
}
|
||||
|
||||
if (!element.parent) {
|
||||
return {
|
||||
left: 0,
|
||||
top: 0
|
||||
}
|
||||
}
|
||||
|
||||
const {left, top} = this.getAbsolutePosition(element.parent)
|
||||
|
||||
return {
|
||||
left: left + element.layoutBox.left,
|
||||
top: top + element.layoutBox.top
|
||||
}
|
||||
}
|
||||
|
||||
public add(element: Element) {
|
||||
element.parent = this;
|
||||
this.children[element.id] = element;
|
||||
}
|
||||
|
||||
public remove(element?: Element) {
|
||||
// 删除自己
|
||||
if (!element) {
|
||||
Object.keys(this.children).forEach(id => {
|
||||
const child = this.children[id]
|
||||
child.remove()
|
||||
delete this.children[id]
|
||||
})
|
||||
} else if (this.children[element.id]) {
|
||||
// 是自己的子节点才删除
|
||||
element.remove()
|
||||
delete this.children[element.id];
|
||||
}
|
||||
}
|
||||
|
||||
public getNodeTree(): LayoutNode {
|
||||
return {
|
||||
id: this.id,
|
||||
style: this.computedStyle,
|
||||
children: Object.keys(this.children).map((id: string) => {
|
||||
const child = this.children[id];
|
||||
return child.getNodeTree();
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
public applyLayout(layoutNode: LayoutNode) {
|
||||
["left", "top", "width", "height"].forEach((key: string) => {
|
||||
if (layoutNode.layout && typeof layoutNode.layout[key] === "number") {
|
||||
this.layoutBox[key] = layoutNode.layout[key];
|
||||
if (this.parent && (key === "left" || key === "top")) {
|
||||
this.layoutBox[key] += this.parent.layoutBox[key];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
layoutNode.children.forEach((child: LayoutNode) => {
|
||||
this.children[child.id].applyLayout(child);
|
||||
});
|
||||
}
|
||||
|
||||
layout() {
|
||||
const nodeTree = this.getNodeTree();
|
||||
computeLayout(nodeTree);
|
||||
this.applyLayout(nodeTree);
|
||||
}
|
||||
}
|
||||
|
||||
export default Element;
|
||||
15
node_modules/widget-ui/src/event.ts
generated
vendored
Normal file
15
node_modules/widget-ui/src/event.ts
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
import _EventEmitter from "eventemitter3";
|
||||
const emitter = new _EventEmitter();
|
||||
export default class EventEmitter {
|
||||
public emit(event: string, data?: any) {
|
||||
emitter.emit(event, data);
|
||||
}
|
||||
|
||||
public on(event: string, callback) {
|
||||
emitter.on(event, callback);
|
||||
}
|
||||
|
||||
public off(event: string, callback) {
|
||||
emitter.off(event, callback);
|
||||
}
|
||||
}
|
||||
87
node_modules/widget-ui/src/style.ts
generated
vendored
Normal file
87
node_modules/widget-ui/src/style.ts
generated
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
const textStyles: string[] = ["color", "fontSize", "textAlign", "fontWeight", "lineHeight", "lineBreak"];
|
||||
|
||||
const scalableStyles: string[] = ["left", "top", "right", "bottom", "width", "height",
|
||||
"margin", "marginLeft", "marginRight", "marginTop", "marginBottom",
|
||||
"padding", "paddingLeft", "paddingRight", "paddingTop", "paddingBottom",
|
||||
"borderWidth", "borderLeftWidth", "borderRightWidth", "borderTopWidth", "borderBottomWidth"];
|
||||
|
||||
const layoutAffectedStyles: string[] = [
|
||||
"margin", "marginTop", "marginBottom", "marginLeft", "marginRight",
|
||||
"padding", "paddingTop", "paddingBottom", "paddingLeft", "paddingRight",
|
||||
"width", "height"];
|
||||
|
||||
type Style = {
|
||||
left: number,
|
||||
top: number,
|
||||
right: number,
|
||||
bottom: number,
|
||||
width: number,
|
||||
height: number,
|
||||
maxWidth: number,
|
||||
maxHeight: number,
|
||||
minWidth: number,
|
||||
minHeight: number,
|
||||
margin: number,
|
||||
marginLeft: number,
|
||||
marginRight: number,
|
||||
marginTop: number,
|
||||
marginBottom: number,
|
||||
padding: number,
|
||||
paddingLeft: number,
|
||||
paddingRight: number,
|
||||
paddingTop: number,
|
||||
paddingBottom: number,
|
||||
borderWidth: number,
|
||||
borderLeftWidth: number,
|
||||
borderRightWidth: number,
|
||||
borderTopWidth: number,
|
||||
borderBottomWidth: number,
|
||||
flexDirection: "column" | "row",
|
||||
justifyContent: "flex-start" | "center" | "flex-end" | "space-between" | "space-around",
|
||||
alignItems: "flex-start" | "center" | "flex-end" | "stretch",
|
||||
alignSelf: "flex-start" | "center" | "flex-end" | "stretch",
|
||||
flex: number,
|
||||
flexWrap: "wrap" | "nowrap",
|
||||
position: "relative" | "absolute",
|
||||
|
||||
hidden: boolean,
|
||||
scale: number
|
||||
}
|
||||
|
||||
const getDefaultStyle = () => ({
|
||||
left: undefined,
|
||||
top: undefined,
|
||||
right: undefined,
|
||||
bottom: undefined,
|
||||
width: undefined,
|
||||
height: undefined,
|
||||
maxWidth: undefined,
|
||||
maxHeight: undefined,
|
||||
minWidth: undefined,
|
||||
minHeight: undefined,
|
||||
margin: undefined,
|
||||
marginLeft: undefined,
|
||||
marginRight: undefined,
|
||||
marginTop: undefined,
|
||||
marginBottom: undefined,
|
||||
padding: undefined,
|
||||
paddingLeft: undefined,
|
||||
paddingRight: undefined,
|
||||
paddingTop: undefined,
|
||||
paddingBottom: undefined,
|
||||
borderWidth: undefined,
|
||||
flexDirection: undefined,
|
||||
justifyContent: undefined,
|
||||
alignItems: undefined,
|
||||
alignSelf: undefined,
|
||||
flex: undefined,
|
||||
flexWrap: undefined,
|
||||
position: undefined,
|
||||
|
||||
hidden: false,
|
||||
scale: 1
|
||||
})
|
||||
|
||||
export {
|
||||
getDefaultStyle, scalableStyles, textStyles, layoutAffectedStyles
|
||||
}
|
||||
Reference in New Issue
Block a user