feat: directional padding and margin

This commit is contained in:
aarthificial
2022-03-20 02:37:08 +01:00
parent 328b7b7f19
commit 441d1210ad
11 changed files with 148 additions and 60 deletions

View File

@@ -1,5 +1,6 @@
import {IRect, Vector2d} from 'konva/lib/types';
import mixColor from 'mix-color';
import {PossibleSpacing, Spacing} from "../types";
export class TimeTween {
public constructor(public value: number) {}
@@ -103,6 +104,15 @@ export class TimeTween {
};
}
public spacing(from: Spacing, to: Spacing, value?: number): PossibleSpacing {
return [
TimeTween.map(from.top, to.top, value ?? this.value),
TimeTween.map(from.right, to.right, value ?? this.value),
TimeTween.map(from.bottom, to.bottom, value ?? this.value),
TimeTween.map(from.left, to.left, value ?? this.value),
];
}
public rectArc(
from: Partial<IRect>,
to: Partial<IRect>,

View File

@@ -1,7 +1,8 @@
import {Node} from 'konva/lib/Node';
import {Project} from '../Project';
import {Surface} from "MC/components/Surface";
import {TimeTween} from "MC/animations/TimeTween";
import {Surface} from "../components/Surface";
import {TimeTween} from "./TimeTween";
import {Spacing} from "../types";
export function showTop(this: Project, node: Node): [Generator, Generator] {
const to = node.offsetY();
@@ -22,6 +23,7 @@ export function showTop(this: Project, node: Node): [Generator, Generator] {
}
export function showSurface(this: Project, surface: Surface): Generator {
const marginFrom = new Spacing();
const margin = surface.getMargin();
const toMask = surface.getMask();
const fromMask = {
@@ -41,7 +43,7 @@ export function showSurface(this: Project, surface: Surface): Generator {
height: value.easeInOutCubic(fromMask.height, toMask.height),
}
)
surface.setMargin(value.easeInOutCubic(0, margin));
surface.setMargin(value.spacing(marginFrom, margin, value.easeInOutCubic()));
surface.opacity(TimeTween.clampRemap(0.3, 1, 0, 1, value.value));
});
}

View File

@@ -1,4 +1,4 @@
import {Size, Origin, Direction} from '../types';
import {Size, Origin, Direction, PossibleSpacing, Spacing} from '../types';
import {Node} from 'konva/lib/Node';
import {LayoutGroup} from 'MC/components/LayoutGroup';
import {LayoutShape} from 'MC/components/LayoutShape';
@@ -10,16 +10,16 @@ export const LAYOUT_CHANGE_EVENT = 'layoutChange';
export interface LayoutAttrs {
radius: number;
margin: number;
padding: number;
margin: PossibleSpacing;
padd: PossibleSpacing;
color: string;
origin: Origin;
}
export interface ILayoutNode {
getRadius(): number;
getMargin(): number;
getPadding(): number;
getMargin(): Spacing;
getPadd(): Spacing;
getColor(): string;
getOrigin(): Origin;
getOriginOffset(custom?: Partial<LayoutAttrs>): Vector2d;

View File

@@ -20,10 +20,10 @@ export class Layout extends LayoutGroup {
}
getLayoutSize(): Size {
return {
width: (this.contentSize?.width ?? 0) + this.getPadding() * 2,
height: (this.contentSize?.height ?? 0) + this.getPadding() * 2,
};
return this.getPadd().apply({
width: this.contentSize?.width ?? 0,
height: this.contentSize?.height ?? 0,
});
}
//TODO Recalculate upon removing children as well.
@@ -48,9 +48,9 @@ export class Layout extends LayoutGroup {
const scale = child.getAbsoluteScale(this);
this.contentSize.width = Math.max(
this.contentSize.width,
(size.width + margin * 2) * scale.x,
(size.width + margin.x) * scale.x,
);
this.contentSize.height += (size.height + margin * 2) * scale.y;
this.contentSize.height += (size.height + margin.y) * scale.y;
}
let height = this.contentSize.height / -2;
@@ -62,9 +62,9 @@ export class Layout extends LayoutGroup {
child.position({
x: -offset.x * scale.x,
y: height + (-offset.y + margin) * scale.y,
y: height + (-offset.y + margin.top) * scale.y,
});
height += (size.height + margin * 2) * scale.y;
height += (size.height + margin.y) * scale.y;
}
this.offset(this.getOriginOffset());

View File

@@ -1,6 +1,6 @@
import {Group} from 'konva/lib/Group';
import {Container, ContainerConfig} from 'konva/lib/Container';
import {Origin, Size} from '../types';
import {Origin, Size, PossibleSpacing, Spacing} from '../types';
import {
getClientRect,
getOriginDelta,
@@ -18,8 +18,6 @@ import {Project} from '../Project';
export type LayoutGroupConfig = Partial<LayoutAttrs> & ContainerConfig;
export abstract class LayoutGroup extends Group implements ILayoutNode {
public attrs: LayoutGroupConfig;
public get project(): Project {
return <Project>this.getStage();
}
@@ -45,22 +43,22 @@ export abstract class LayoutGroup extends Group implements ILayoutNode {
return this.attrs.radius ?? 0;
}
public setMargin(value: number): this {
this.attrs.margin = value;
public setMargin(value: PossibleSpacing): this {
this.attrs.margin = new Spacing(value);
return this;
}
public getMargin(): Origin {
return this.attrs.margin ?? 0;
public getMargin(): Spacing {
return this.attrs.margin ?? new Spacing();
}
public setPadding(value: number): this {
this.attrs.padding = value;
public setPadd(value: PossibleSpacing): this {
this.attrs.padd = new Spacing(value);
return this;
}
public getPadding(): number {
return this.attrs.padding ?? 0;
public getPadd(): Spacing {
return this.attrs.padd ?? new Spacing();
}
public setColor(value: string): this {

View File

@@ -1,5 +1,4 @@
import {Container} from 'konva/lib/Container';
import {Origin} from 'MC/types/Origin';
import {Shape, ShapeConfig} from 'konva/lib/Shape';
import {
getOriginDelta,
@@ -10,15 +9,13 @@ import {
LayoutAttrs,
getClientRect,
} from './ILayoutNode';
import {Size} from '../types';
import {Origin, Size, PossibleSpacing, Spacing} from '../types';
import {IRect, Vector2d} from 'konva/lib/types';
import {Project} from "../Project";
export type LayoutShapeConfig = Partial<LayoutAttrs> & ShapeConfig;
export abstract class LayoutShape extends Shape implements ILayoutNode {
public attrs: LayoutShapeConfig;
public get project(): Project {
return <Project>this.getStage();
}
@@ -40,22 +37,22 @@ export abstract class LayoutShape extends Shape implements ILayoutNode {
return this.attrs.radius ?? 0;
}
public setMargin(value: number): this {
this.attrs.margin = value;
public setMargin(value: PossibleSpacing): this {
this.attrs.margin = new Spacing(value);
return this;
}
public getMargin(): Origin {
return this.attrs.margin ?? 0;
public getMargin(): Spacing {
return this.attrs.margin ?? new Spacing();
}
public setPadding(value: number): this {
this.attrs.padding = value;
public setPadd(value: PossibleSpacing): this {
this.attrs.padd = new Spacing(value);
return this;
}
public getPadding(): number {
return this.attrs.padding ?? 0;
public getPadd(): Spacing {
return this.attrs.padd ?? new Spacing();
}
public setColor(value: string): this {

View File

@@ -10,7 +10,7 @@ import {
LayoutAttrs,
} from './ILayoutNode';
import {Project} from '../Project';
import {Origin, Size} from '../types';
import {Origin, Size, PossibleSpacing, Spacing} from '../types';
export interface LayoutTextConfig extends Partial<LayoutAttrs>, TextConfig {
minWidth?: number;
@@ -28,7 +28,7 @@ export class LayoutText extends Text implements ILayoutNode {
super({
color: '#c0b3a3',
radius: 40,
padding: 30,
padd: new Spacing(30),
align: 'center',
verticalAlign: 'middle',
height: 20,
@@ -44,13 +44,14 @@ export class LayoutText extends Text implements ILayoutNode {
}
public getLayoutSize(custom?: LayoutTextConfig): Size {
const padding = this.getPadd();
const size = this.measureSize(custom?.text ?? this.text());
return {
width: Math.max(
custom?.minWidth ?? this.getMinWidth(),
this.overrideWidth ?? (size.width + this.getPadding() * 2),
this.overrideWidth ?? (size.width + padding.x),
),
height: (this.isConstructed ? this.getHeight() : 0) + this.getPadding() * 2,
height: (this.isConstructed ? this.getHeight() : 0) + padding.y,
};
}
@@ -63,22 +64,22 @@ export class LayoutText extends Text implements ILayoutNode {
return this.attrs.radius ?? 0;
}
public setMargin(value: number): this {
this.attrs.margin = value;
public setMargin(value: PossibleSpacing): this {
this.attrs.margin = new Spacing(value);
return this;
}
public getMargin(): Origin {
return this.attrs.margin ?? 0;
public getMargin(): Spacing {
return this.attrs.margin ?? new Spacing();
}
public setPadding(value: number): this {
this.attrs.padding = value;
public setPadd(value: PossibleSpacing): this {
this.attrs.padd = new Spacing(value);
return this;
}
public getPadding(): number {
return this.attrs.padding ?? 0;
public getPadd(): Spacing {
return this.attrs.padd ?? new Spacing();
}
public setColor(value: string): this {
@@ -99,7 +100,7 @@ export class LayoutText extends Text implements ILayoutNode {
return this.attrs.minWidth ?? 0;
}
setText(text: string): this {
public setText(text: string): this {
super.setText(text);
this.offset(this.getOriginOffset());
this.fireLayoutChange();
@@ -130,10 +131,11 @@ export class LayoutText extends Text implements ILayoutNode {
}
public getOriginOffset(custom?: LayoutTextConfig): Vector2d {
const padding = this.getPadd();
const size = this.getLayoutSize({minWidth: 0, ...custom});
const offset = getOriginOffset(size, custom?.origin ?? this.getOrigin());
offset.x += size.width / 2;
offset.y += size.height / 2 - this.getPadding();
offset.x += size.width / 2 - padding.left;
offset.y += size.height / 2 - padding.top;
return offset;
}

View File

@@ -152,7 +152,7 @@ export class Surface extends LayoutGroup {
const contentMargin = this.child.getMargin();
const scale = Math.min(
1,
data.width / (contentSize.width + contentMargin * 2),
data.width / (contentSize.width + contentMargin.x),
);
this.mask = data;
@@ -178,7 +178,7 @@ export class Surface extends LayoutGroup {
color: '#F0F',
height: 0,
width: 0,
padding: 0,
padd: 0,
margin: 0,
radius: 0,
};
@@ -188,12 +188,12 @@ export class Surface extends LayoutGroup {
const size = this.child.getLayoutSize();
const margin = this.child.getMargin();
const scale = this.child.getAbsoluteScale(this);
const padding = this.getPadding();
const padding = this.getPadd();
this.layoutData = {
...this.layoutData,
width: (size.width + margin * 2 + padding * 2) * scale.x,
height: (size.height + margin * 2 + padding * 2) * scale.y,
width: (size.width + margin.x + padding.x) * scale.x,
height: (size.height + margin.y + padding.y) * scale.y,
radius: this.child.getRadius(),
color: this.child.getColor(),
};

View File

@@ -84,6 +84,7 @@ export class ThreeView extends LayoutShape {
public setCanvasSize(value: Size): this {
this.attrs.canvasSize = value;
this.handleCanvasSizeChange();
return this;
}
@@ -95,6 +96,7 @@ export class ThreeView extends LayoutShape {
public setCameraScale(value: number): this {
this.attrs.cameraScale = value;
this.handleCanvasSizeChange();
return this;
}
@@ -104,6 +106,7 @@ export class ThreeView extends LayoutShape {
public setQuality(value: number): this {
this.attrs.quality = value;
this.handleCanvasSizeChange();
return this;
}

75
src/types/Spacing.ts Normal file
View File

@@ -0,0 +1,75 @@
import {Size} from './Size';
interface ISpacing {
top: number;
right: number;
bottom: number;
left: number;
}
export type PossibleSpacing =
| ISpacing
| number
| [number, number]
| [number, number, number]
| [number, number, number, number];
export class Spacing implements ISpacing {
public top = 0;
public right = 0;
public bottom = 0;
public left = 0;
public get x(): number {
return this.left + this.right;
}
public get y(): number {
return this.top + this.bottom;
}
public constructor(value?: PossibleSpacing) {
if (value !== undefined) {
this.set(value);
}
}
public set(value: PossibleSpacing): this {
if (Array.isArray(value)) {
switch (value.length) {
case 2:
this.top = this.bottom = value[0];
this.right = this.left = value[1];
break;
case 3:
this.top = value[0];
this.right = this.left = value[1];
this.bottom = value[2];
break;
case 4:
this.top = value[0];
this.right = value[1];
this.bottom = value[2];
this.left = value[3];
break;
}
} else if (typeof value === 'object') {
this.top = value.top ?? 0;
this.right = value.right ?? 0;
this.bottom = value.bottom ?? 0;
this.left = value.left ?? 0;
return this;
} else {
this.top = this.right = this.bottom = this.left = value;
}
return this;
}
public apply(size: Size): Size {
return {
width: size.width + this.x,
height: size.height + this.y,
};
}
}

View File

@@ -1,2 +1,3 @@
export * from './Size';
export * from './Origin';
export * from './Origin';
export * from './Spacing';