fix: markline

This commit is contained in:
hufeixiong
2021-07-27 10:58:41 +08:00
parent 8a178c82f0
commit 858273fe11
12 changed files with 234 additions and 81 deletions

View File

@@ -81,7 +81,7 @@ config可以拿到所有数据用来制作事件时使用。
第六个参数resize 是为了判断是否能进行缩放当为false时无法进行缩放。 第六个参数resize 是为了判断是否能进行缩放当为false时无法进行缩放。
第七个参数needPosition某些组件移入画布后会默认采取拖拽的落点该配置项默认为true为false时将使用组件自top和left定位来放置。 第七个参数needPosition某些组件移入画布后会默认采取拖拽的落点该配置项默认为true为false时将使用组件自top和left定位来放置。

View File

@@ -2,7 +2,7 @@
* @Author: yehuozhili * @Author: yehuozhili
* @Date: 2021-07-07 14:35:38 * @Date: 2021-07-07 14:35:38
* @LastEditors: yehuozhili * @LastEditors: yehuozhili
* @LastEditTime: 2021-07-26 14:03:01 * @LastEditTime: 2021-07-27 10:46:07
* @FilePath: \dooringx\packages\dooringx-example\src\plugin\registComponents\button.tsx * @FilePath: \dooringx\packages\dooringx-example\src\plugin\registComponents\button.tsx
*/ */
@@ -131,6 +131,7 @@ const MButton = new ComponentItemFactory(
canRotate: true, canRotate: true,
value: 0, value: 0,
}, },
canDrag: true, // false就不能拖
}, },
(data, context, store, config) => { (data, context, store, config) => {
return <ButtonTemp data={data} store={store} context={context} config={config}></ButtonTemp>; return <ButtonTemp data={data} store={store} context={context} config={config}></ButtonTemp>;

View File

@@ -2,7 +2,7 @@
* @Author: yehuozhili * @Author: yehuozhili
* @Date: 2021-03-14 04:29:09 * @Date: 2021-03-14 04:29:09
* @LastEditors: yehuozhili * @LastEditors: yehuozhili
* @LastEditTime: 2021-07-20 11:25:31 * @LastEditTime: 2021-07-27 10:17:01
* @FilePath: \dooringx\packages\dooringx-lib\src\components\wrapperMove\index.tsx * @FilePath: \dooringx\packages\dooringx-lib\src\components\wrapperMove\index.tsx
*/ */
import { AllHTMLAttributes, CSSProperties, PropsWithChildren, useRef } from 'react'; import { AllHTMLAttributes, CSSProperties, PropsWithChildren, useRef } from 'react';

View File

@@ -2,7 +2,7 @@
* @Author: yehuozhili * @Author: yehuozhili
* @Date: 2021-03-14 04:29:09 * @Date: 2021-03-14 04:29:09
* @LastEditors: yehuozhili * @LastEditors: yehuozhili
* @LastEditTime: 2021-07-20 16:12:55 * @LastEditTime: 2021-07-26 20:42:16
* @FilePath: \dooringx\packages\dooringx-lib\src\core\crossDrag\index.ts * @FilePath: \dooringx\packages\dooringx-lib\src\core\crossDrag\index.ts
*/ */
import { DragEvent, ReactNode } from 'react'; import { DragEvent, ReactNode } from 'react';
@@ -51,8 +51,8 @@ export const containerDragResolve = (config: UserConfig) => {
e.preventDefault(); e.preventDefault();
}, },
onDrop: (e: DragEvent<HTMLDivElement>) => { onDrop: (e: DragEvent<HTMLDivElement>) => {
const offsetX = e.nativeEvent.offsetX; const offsetX = Math.round(e.nativeEvent.offsetX);
const offestY = e.nativeEvent.offsetY; const offestY = Math.round(e.nativeEvent.offsetY);
//drop后修改store //drop后修改store
if (currentDrag) { if (currentDrag) {
// 还需要拿到注册的组件状态 // 还需要拿到注册的组件状态

View File

@@ -39,8 +39,8 @@ export const innerDrag = function (
ref.current.style.cursor = 'move'; ref.current.style.cursor = 'move';
ref.current.style.willChange = 'left,right,width,height'; ref.current.style.willChange = 'left,right,width,height';
} }
innerDragState.startX = e.clientX; innerDragState.startX = Math.round(e.clientX);
innerDragState.startY = e.clientY; innerDragState.startY = Math.round(e.clientY);
innerDragState.item = item; innerDragState.item = item;
innerDragState.isDrag = true; innerDragState.isDrag = true;
innerDragState.ref = ref; innerDragState.ref = ref;
@@ -69,30 +69,30 @@ export const innerContainerDrag = function (config: UserConfig) {
let { clientX: moveX, clientY: moveY } = e; let { clientX: moveX, clientY: moveY } = e;
const { startX, startY } = innerDragState; const { startX, startY } = innerDragState;
const scale = scaleState.value; const scale = scaleState.value;
let durX = (moveX - startX) / scale; let durX = Math.round((moveX - startX) / scale);
let durY = (moveY - startY) / scale; let durY = Math.round((moveY - startY) / scale);
let newblock: IBlockType[]; let newblock: IBlockType[];
if (lastblock !== innerDragState.item) { if (lastblock !== innerDragState.item) {
const cloneblock: IBlockType[] = deepCopy(store.getData().block); const cloneblock: IBlockType[] = deepCopy(store.getData().block);
lastblock = innerDragState.item; lastblock = innerDragState.item;
newblock = cloneblock.map((v) => { newblock = cloneblock.map((v) => {
if (v.focus && v.position !== 'static') { if (v.focus && v.position !== 'static') {
v.left = v.left + durX; v.left = Math.round(v.left + durX);
v.top = v.top + durY; v.top = Math.round(v.top + durY);
} }
return v; return v;
}); });
} else { } else {
newblock = store.getData().block.map((v) => { newblock = store.getData().block.map((v) => {
if (v.focus && v.position !== 'static') { if (v.focus && v.position !== 'static') {
v.left = v.left + durX; v.left = Math.round(v.left + durX);
v.top = v.top + durY; v.top = Math.round(v.top + durY);
} }
return v; return v;
}); });
} }
innerDragState.startX = moveX; innerDragState.startX = Math.round(moveX);
innerDragState.startY = moveY; innerDragState.startY = Math.round(moveY);
store.setData({ ...store.getData(), block: newblock }); store.setData({ ...store.getData(), block: newblock });
} }
resizerMouseMove(e, config); resizerMouseMove(e, config);

View File

@@ -2,22 +2,64 @@
* @Author: yehuozhili * @Author: yehuozhili
* @Date: 2021-03-14 04:29:09 * @Date: 2021-03-14 04:29:09
* @LastEditors: yehuozhili * @LastEditors: yehuozhili
* @LastEditTime: 2021-07-26 11:38:11 * @LastEditTime: 2021-07-26 20:51:41
* @FilePath: \dooringx\packages\dooringx-lib\src\core\markline\calcRender.ts * @FilePath: \dooringx\packages\dooringx-lib\src\core\markline\calcRender.ts
*/ */
import { innerDragState } from '../innerDrag/state'; import { innerDragState } from '../innerDrag/state';
import { switchMarklineDisplay } from './normalMode'; import { newMarklineDisplay } from './normalMode';
import { resizeCurrentCalculate } from './resizeMarkline';
import { marklineConfig } from './marklineConfig'; import { marklineConfig } from './marklineConfig';
import UserConfig from '../../config'; import UserConfig from '../../config';
import { angleToRadian, getContainer } from '../utils';
export interface LinesTypes { export interface LinesTypes {
x: number[]; x: number[];
y: number[]; y: number[];
} }
export function marklineCalRender(config: UserConfig) { export function cos(rotate: number) {
return Math.abs(Math.cos(angleToRadian(rotate)));
}
export function sin(rotate: number) {
return Math.abs(Math.sin(angleToRadian(rotate)));
}
export function getComponentRotatedStyle(
rotate: number,
width: number,
height: number,
left: number,
right: number,
top: number,
bottom: number
) {
const style = {
left,
width,
height,
right,
top,
bottom,
};
if (rotate !== 0) {
const newWidth = style.width * cos(rotate) + style.height * sin(rotate);
const diffX = (style.width - newWidth) / 2; // 旋转后范围变小是正值,变大是负值
style.left += diffX;
style.right = style.left + newWidth;
const newHeight = style.height * cos(rotate) + style.width * sin(rotate);
const diffY = (newHeight - style.height) / 2; // 始终是正
style.top -= diffY;
style.bottom = style.top + newHeight;
style.width = newWidth;
style.height = newHeight;
} else {
style.bottom = style.top + style.height;
style.right = style.left + style.width;
}
return style;
}
export function marklineCalRender(config: UserConfig): LinesTypes {
const store = config.getStore(); const store = config.getStore();
const scaleState = config.getScaleState();
//focus可能好几个做对比的是拖拽那个 //focus可能好几个做对比的是拖拽那个
const lines: LinesTypes = { x: [], y: [] }; const lines: LinesTypes = { x: [], y: [] };
if (innerDragState.item?.position === 'static' || innerDragState.item?.position === 'relative') { if (innerDragState.item?.position === 'static' || innerDragState.item?.position === 'relative') {
@@ -28,7 +70,19 @@ export function marklineCalRender(config: UserConfig) {
const ref = innerDragState.ref; const ref = innerDragState.ref;
if (item && ref && ref.current && innerDragState.isDrag) { if (item && ref && ref.current && innerDragState.isDrag) {
// 这个被拷贝过,所以必须重新获取
const focus = store.getData().block.find((v) => v.id === item.id)!; const focus = store.getData().block.find((v) => v.id === item.id)!;
if (!focus) {
return lines;
}
const container = getContainer();
if (!container) {
return lines;
}
if (typeof focus.width !== 'number' || typeof focus.height !== 'number') {
return lines;
}
if (!marklineConfig.marklineUnfocus) { if (!marklineConfig.marklineUnfocus) {
marklineConfig.marklineUnfocus = store marklineConfig.marklineUnfocus = store
.getData() .getData()
@@ -36,17 +90,25 @@ export function marklineCalRender(config: UserConfig) {
(v) => v.focus === false && v.position !== 'static' && v.position !== 'relative' (v) => v.focus === false && v.position !== 'static' && v.position !== 'relative'
); );
} }
const { width, height } = ref.current.getBoundingClientRect();
// left 和top 被深拷贝过,最新的值需要即时获取 const left = focus.left;
const left = focus?.left; const top = focus.top;
const top = focus?.top; const rotate = focus.rotate.value;
const width = focus.width;
const height = focus.height;
const realStyle = getComponentRotatedStyle(
rotate,
width,
height,
left,
left + width,
top,
top + height
);
if (typeof left !== 'number' || typeof top !== 'number') { if (typeof left !== 'number' || typeof top !== 'number') {
return lines; //莫名可能没有这2值 return lines; //可能没有这2值
} }
const scale = scaleState.value;
const wwidth = width / scale;
const wheight = height / scale;
marklineConfig.marklineUnfocus.forEach((v) => { marklineConfig.marklineUnfocus.forEach((v) => {
let l = v?.left; let l = v?.left;
@@ -54,26 +116,19 @@ export function marklineCalRender(config: UserConfig) {
if (typeof l !== 'number' || typeof t !== 'number') { if (typeof l !== 'number' || typeof t !== 'number') {
console.warn(`${v} component miss top or left`); console.warn(`${v} component miss top or left`);
} else { } else {
// 如果不是由外层容器决定的则没有这2属性 // 如果拿实例可能有性能问题,暂直接计算。
const w = v.width; const w = v.width;
const h = v.height; const h = v.height;
if (typeof w === 'number' && typeof h === 'number') {
// 只有满足要求的才进行push const ro = v.rotate.value;
if (marklineConfig.mode === 'normal') { const r = l + w;
switchMarklineDisplay(l, t, w, h, left, top, wwidth, wheight, lines, focus); const b = t + h;
const rstyle = getComponentRotatedStyle(ro, w, h, l, r, t, b);
newMarklineDisplay(realStyle, rstyle, lines, focus);
} }
} }
}); });
// if (marklineConfig.mode === 'grid' && marklineConfig.isAbsorb) {
// gridModeDisplay(left, top, focus, config);该模式暂废弃
// }
} }
// if (marklineConfig.mode === 'grid') {
// grideModeRender(lines, config);该模式暂废弃
// }
resizeCurrentCalculate(lines, config);
return lines; return lines;
} }

View File

@@ -2,36 +2,14 @@
* @Author: yehuozhili * @Author: yehuozhili
* @Date: 2021-03-14 04:29:09 * @Date: 2021-03-14 04:29:09
* @LastEditors: yehuozhili * @LastEditors: yehuozhili
* @LastEditTime: 2021-07-13 20:38:59 * @LastEditTime: 2021-07-26 15:01:06
* @FilePath: \dooringx\packages\dooringx-lib\src\core\markline\index.tsx * @FilePath: \dooringx\packages\dooringx-lib\src\core\markline\index.tsx
*/ */
import React from 'react'; import React from 'react';
import { useMemo } from 'react'; import { useMemo } from 'react';
import UserConfig from '../../config'; import UserConfig from '../../config';
import { IBlockType } from '../store/storetype';
import { marklineCalRender } from './calcRender'; import { marklineCalRender } from './calcRender';
// 主要逻辑需要注入组件内拖拽
export interface MarklineConfigType {
indent: number;
isAbsorb: boolean;
mode: 'normal' | 'grid';
gridIndent: number;
resizeIndent: number;
marklineUnfocus: null | IBlockType[];
}
// 间隔距离执行吸附
export const marklineConfig: MarklineConfigType = {
indent: 2,
isAbsorb: true,
mode: 'normal',
gridIndent: 50,
resizeIndent: 0,
marklineUnfocus: null,
};
export function MarklineX(props: any) { export function MarklineX(props: any) {
return ( return (
<div <div

View File

@@ -1,6 +1,121 @@
import { IBlockType } from '../store/storetype'; import { IBlockType } from '../store/storetype';
import { LinesTypes } from './calcRender'; import { LinesTypes } from './calcRender';
import { marklineConfig } from './marklineConfig'; import { marklineConfig } from './marklineConfig';
export interface RealStyle {
width: number;
height: number;
left: number;
right: number;
top: number;
bottom: number;
}
export function newMarklineDisplay(
focusStyle: RealStyle,
unFocusStyle: RealStyle,
lines: LinesTypes,
focus: IBlockType
) {
const { top, height, left, width } = focusStyle;
const { top: t, height: h, left: l, width: w } = unFocusStyle;
let diffY = 0;
// 头对头
if (Math.abs(t - top) < marklineConfig.indent) {
lines.x.push(t);
diffY = t - top;
}
// 中对头
else if (Math.abs(t - (top + height / 2)) < marklineConfig.indent) {
lines.x.push(t);
diffY = t - (top + height / 2);
}
// 尾对头
else if (Math.abs(t - (top + height)) < marklineConfig.indent) {
lines.x.push(t);
diffY = t - (top + height);
}
// 头对中
else if (Math.abs(t + h / 2 - top) < marklineConfig.indent) {
lines.x.push(t + h / 2);
diffY = t + h / 2 - top;
}
// 中对中
else if (Math.abs(t + h / 2 - top - height / 2) < marklineConfig.indent) {
lines.x.push(t + h / 2);
diffY = t + h / 2 - top - height / 2;
}
// 尾对中
else if (Math.abs(t + h / 2 - top - height) < marklineConfig.indent) {
lines.x.push(t + h / 2);
diffY = t + h / 2 - top - height;
}
// 头对尾
else if (Math.abs((t + h - top) / 2) < marklineConfig.indent) {
lines.x.push(t + h);
diffY = (t + h - top) / 2;
}
// 中对尾
else if (Math.abs(t + h - top - height / 2) < marklineConfig.indent) {
lines.x.push(t + h);
diffY = t + h - top - height / 2;
}
// 尾对尾
else if (Math.abs((t + h - top - height) / 2) < marklineConfig.indent) {
lines.x.push(t + h);
diffY = (t + h - top - height) / 2;
}
focus.top = Math.round(focus.top + diffY);
// 纵线
// 头对头
let diffX = 0;
if (Math.abs(l - left) < marklineConfig.indent) {
lines.y.push(l);
diffX = l - left;
}
// 中对头
else if (Math.abs(l - (left + width / 2)) < marklineConfig.indent) {
lines.y.push(l);
diffX = l - (left + width / 2);
}
// 尾对头
else if (Math.abs(l - (left + width)) < marklineConfig.indent) {
lines.y.push(l);
diffX = l - (left + width);
}
// 头对中
else if (Math.abs(l + w / 2 - left) < marklineConfig.indent) {
lines.y.push(l + w / 2);
diffX = l + w / 2 - left;
}
// 中对中
else if (Math.abs(l + w / 2 - left - width / 2) < marklineConfig.indent) {
lines.y.push(l + w / 2);
diffX = l + w / 2 - left - width / 2;
}
// 尾对中
else if (Math.abs(l + w / 2 - left - width) < marklineConfig.indent) {
lines.y.push(l + w / 2);
diffX = l + w / 2 - left - width;
}
// 头对尾
else if (Math.abs((l + w - left) / 2) < marklineConfig.indent) {
lines.y.push(l + w);
diffX = (l + w - left) / 2;
}
// 中对尾
else if (Math.abs(l + w - left - width / 2) < marklineConfig.indent) {
lines.y.push(l + w);
diffX = l + w - left - width / 2;
}
// 尾对尾
else if (Math.abs((l + w - left - width) / 2) < marklineConfig.indent) {
lines.y.push(l + w);
diffX = (l + w - left - width) / 2;
}
focus.left = Math.round(focus.left + diffX);
}
export function switchMarklineDisplay( export function switchMarklineDisplay(
l: number, l: number,
t: number, t: number,

View File

@@ -2,7 +2,7 @@
* @Author: yehuozhili * @Author: yehuozhili
* @Date: 2021-03-09 15:19:36 * @Date: 2021-03-09 15:19:36
* @LastEditors: yehuozhili * @LastEditors: yehuozhili
* @LastEditTime: 2021-07-20 11:31:44 * @LastEditTime: 2021-07-27 10:18:34
* @FilePath: \dooringx\packages\dooringx-lib\src\core\resizeHandler\containerResizer.ts * @FilePath: \dooringx\packages\dooringx-lib\src\core\resizeHandler\containerResizer.ts
*/ */
@@ -32,8 +32,9 @@ export const containerResizer = {
const diff = ((e.clientY - containerState.startY) / scale) * 2; //可以直接使用movementy const diff = ((e.clientY - containerState.startY) / scale) * 2; //可以直接使用movementy
const clonedata: IStoreData = deepCopy(store.getData()); const clonedata: IStoreData = deepCopy(store.getData());
const height = clonedata.container.height; const height = clonedata.container.height;
let tmpHeight = let tmpHeight = Math.round(
height + diff < containerState.minHeight ? containerState.minHeight : height + diff; height + diff < containerState.minHeight ? containerState.minHeight : height + diff
);
clonedata.container.height = tmpHeight; clonedata.container.height = tmpHeight;
store.setData(clonedata); store.setData(clonedata);
containerState.startY = e.clientY; containerState.startY = e.clientY;

View File

@@ -1,6 +1,6 @@
import { RefObject, useMemo } from 'react'; import { RefObject, useMemo } from 'react';
import { IBlockType } from '../store/storetype'; import { IBlockType } from '../store/storetype';
import { deepCopy } from '../utils'; import { deepCopy, getContainer } from '../utils';
import React from 'react'; import React from 'react';
import classnames from 'classnames'; import classnames from 'classnames';
import styles from '../../index.less'; import styles from '../../index.less';
@@ -32,10 +32,7 @@ const onMouseDown = (
resizeState.current = store.getIndex(); resizeState.current = store.getIndex();
resizeState.currentTarget = e.nativeEvent.target as HTMLDivElement; resizeState.currentTarget = e.nativeEvent.target as HTMLDivElement;
const curDiv = resizeState.ref.current; const curDiv = resizeState.ref.current;
let container = document.querySelector('#yh-container'); const container = getContainer();
if (!container) {
container = document.querySelector('#yh-container-iframe');
}
if (!container) { if (!container) {
return; return;
} }
@@ -148,13 +145,10 @@ export const resizerMouseMove = (e: React.MouseEvent, config: UserConfig) => {
resizeState.ref?.current && resizeState.ref?.current &&
resizeState.currentTarget resizeState.currentTarget
) { ) {
let { clientX: moveX, clientY: moveY } = e; const { clientX: moveX, clientY: moveY } = e;
const scale = scaleState.value; const scale = scaleState.value;
let container = document.querySelector('#yh-container'); const container = getContainer();
if (!container) {
container = document.querySelector('#yh-container-iframe');
}
if (!container) { if (!container) {
return; return;
} }

View File

@@ -294,3 +294,11 @@ export function postMessage(value: any, src: string, target = 'yh-container-ifra
export function angleToRadian(angle: number) { export function angleToRadian(angle: number) {
return (angle * Math.PI) / 180; return (angle * Math.PI) / 180;
} }
export function getContainer() {
let container = document.querySelector('#yh-container');
if (!container) {
container = document.querySelector('#yh-container-iframe');
}
return container;
}

View File

@@ -2,14 +2,15 @@
* @Author: yehuozhili * @Author: yehuozhili
* @Date: 2021-03-14 05:02:28 * @Date: 2021-03-14 05:02:28
* @LastEditors: yehuozhili * @LastEditors: yehuozhili
* @LastEditTime: 2021-07-04 16:40:17 * @LastEditTime: 2021-07-26 14:55:29
* @FilePath: \DooringV2\packages\dooring-v2-lib\tsdx.config.js * @FilePath: \dooringx\packages\dooringx-lib\tsdx.config.js
*/ */
const postcss = require('rollup-plugin-postcss'); const postcss = require('rollup-plugin-postcss');
const replace = require('@rollup/plugin-replace'); const replace = require('@rollup/plugin-replace');
module.exports = { module.exports = {
rollup(config, options) { rollup(config, options) {
config.output.banner = '// 有问题请加QQ 673632758 by yehuozhili';
config.plugins.push( config.plugins.push(
postcss({ postcss({
inject: false, inject: false,