rotate start
This commit is contained in:
@@ -7,6 +7,7 @@ import React from 'react';
|
||||
import { transfer } from '../core/transfer';
|
||||
import { UserConfig } from '../config';
|
||||
import styles from '../index.less';
|
||||
import { RotateResizer } from '../core/rotateHandler';
|
||||
interface BlockProps {
|
||||
data: IBlockType;
|
||||
context: 'edit' | 'preview';
|
||||
@@ -15,7 +16,7 @@ interface BlockProps {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* block在modal中也要使用,所以该组件不应该接收容器ref
|
||||
* 用来从component里拿到渲染进行渲染,由于异步拉代码,所以需要等待代码拉取完毕
|
||||
* @param {*} props
|
||||
* @returns
|
||||
@@ -72,7 +73,8 @@ function Blocks(props: PropsWithChildren<BlockProps>) {
|
||||
props.data.left,
|
||||
props.data.height,
|
||||
props.data.width,
|
||||
props.data.fixed
|
||||
props.data.fixed,
|
||||
props.data.rotate.value
|
||||
);
|
||||
|
||||
setPreviewState({ top, left, width, height });
|
||||
@@ -92,6 +94,7 @@ function Blocks(props: PropsWithChildren<BlockProps>) {
|
||||
props.data.top,
|
||||
props.data.width,
|
||||
props.data.fixed,
|
||||
props.data.rotate,
|
||||
]);
|
||||
|
||||
const animatecss = useMemo(() => {
|
||||
@@ -130,6 +133,7 @@ function Blocks(props: PropsWithChildren<BlockProps>) {
|
||||
zIndex: props.data.zIndex,
|
||||
display: props.data.display,
|
||||
opacity: props.iframe ? 0 : 1,
|
||||
transform: `rotate(${props.data.rotate.value}deg)`,
|
||||
}}
|
||||
{...innerDragData}
|
||||
onContextMenu={(e) => {
|
||||
@@ -138,12 +142,13 @@ function Blocks(props: PropsWithChildren<BlockProps>) {
|
||||
}
|
||||
}}
|
||||
>
|
||||
{/* 绝对定位元素 */}
|
||||
{props.data.position !== 'static' && (
|
||||
<div className={animatecss} style={{ ...style, ...animateCount }}>
|
||||
{state}
|
||||
</div>
|
||||
)}
|
||||
{/* 这里暂不考虑布局影响 */}
|
||||
{/* 静态定位 非行内 这里暂不考虑布局影响 */}
|
||||
{props.data.position === 'static' && props.data.display !== 'inline' && (
|
||||
<div
|
||||
className={animatecss}
|
||||
@@ -157,10 +162,12 @@ function Blocks(props: PropsWithChildren<BlockProps>) {
|
||||
{state}
|
||||
</div>
|
||||
)}
|
||||
{/* 静态定位 行内 这里暂不考虑布局影响 */}
|
||||
{props.data.position === 'static' && props.data.display === 'inline' && (
|
||||
<span style={{ pointerEvents: 'none' }}>{state}</span>
|
||||
)}
|
||||
<BlockResizer data={props.data} config={props.config} rect={ref}></BlockResizer>
|
||||
<RotateResizer data={props.data} config={props.config} rect={ref}></RotateResizer>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
@@ -175,6 +182,7 @@ function Blocks(props: PropsWithChildren<BlockProps>) {
|
||||
height: previewState.height,
|
||||
zIndex: props.data.zIndex,
|
||||
display: props.data.display,
|
||||
transform: `rotate(${props.data.rotate}deg)`,
|
||||
...animateCount,
|
||||
}}
|
||||
>
|
||||
|
@@ -2,8 +2,8 @@
|
||||
* @Author: yehuozhili
|
||||
* @Date: 2021-03-14 04:29:09
|
||||
* @LastEditors: yehuozhili
|
||||
* @LastEditTime: 2021-07-07 16:36:42
|
||||
* @FilePath: \DooringV2\packages\dooringx-lib\src\core\components\createBlock.ts
|
||||
* @LastEditTime: 2021-07-21 20:56:01
|
||||
* @FilePath: \dooringx\packages\dooringx-lib\src\core\components\createBlock.ts
|
||||
*/
|
||||
import { IBlockType } from '../store/storetype';
|
||||
import { createUid } from '../utils';
|
||||
@@ -30,5 +30,9 @@ export function createBlock(top: number, left: number, ComponentItem: ComponentI
|
||||
functionList: ComponentItem.initData.functionList || [],
|
||||
animate: ComponentItem.initData.animate || {},
|
||||
fixed: ComponentItem.initData.fixed || false,
|
||||
rotate: ComponentItem.initData.rotate || {
|
||||
value: 0,
|
||||
canRotate: true,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@@ -10,6 +10,7 @@ import { wrapperMoveMouseUp as iframeWrapperMove } from '../../components/Iframe
|
||||
import { contextMenuState } from '../contextMenu';
|
||||
import { innerDragState } from './state';
|
||||
import UserConfig from '../../config';
|
||||
import { rotateMouseMove, rotateMouseUp } from '../rotateHandler';
|
||||
|
||||
export const innerDrag = function (
|
||||
item: IBlockType,
|
||||
@@ -95,6 +96,7 @@ export const innerContainerDrag = function (config: UserConfig) {
|
||||
store.setData({ ...store.getData(), block: newblock });
|
||||
}
|
||||
resizerMouseMove(e, config);
|
||||
rotateMouseMove(e, config);
|
||||
if (selectData.selectDiv) {
|
||||
selectRangeMouseMove(e);
|
||||
}
|
||||
@@ -115,6 +117,7 @@ export const innerContainerDragUp = function (config: UserConfig, iframe = false
|
||||
innerDragState.ref.current.style.willChange = 'auto';
|
||||
}
|
||||
resizerMouseUp(config);
|
||||
rotateMouseUp(config);
|
||||
if (innerDragState.current) {
|
||||
const endindex = store.getIndex();
|
||||
store.getStoreList().splice(innerDragState.current, endindex - innerDragState.current);
|
||||
|
223
packages/dooringx-lib/src/core/resizeHandler/calcWithRotate.ts
Normal file
223
packages/dooringx-lib/src/core/resizeHandler/calcWithRotate.ts
Normal file
@@ -0,0 +1,223 @@
|
||||
/*
|
||||
* @Author: yehuozhili
|
||||
* @Date: 2021-07-22 16:55:10
|
||||
* @LastEditors: yehuozhili
|
||||
* @LastEditTime: 2021-07-22 20:48:19
|
||||
* @FilePath: \dooringx\packages\dooringx-lib\src\core\resizeHandler\calcWithRotate.ts
|
||||
*/
|
||||
|
||||
import { DirectionType } from '.';
|
||||
import { IBlockType } from '../store/storetype';
|
||||
import { angleToRadian } from '../utils';
|
||||
|
||||
interface Point {
|
||||
x: number;
|
||||
y: number;
|
||||
}
|
||||
|
||||
function getCenterPoint(p1: Point, p2: Point) {
|
||||
return {
|
||||
x: p1.x + (p2.x - p1.x) / 2,
|
||||
y: p1.y + (p2.y - p1.y) / 2,
|
||||
};
|
||||
}
|
||||
function calculateRotatedPointCoordinate(point: Point, center: Point, rotate: number) {
|
||||
return {
|
||||
x:
|
||||
(point.x - center.x) * Math.cos(angleToRadian(rotate)) -
|
||||
(point.y - center.y) * Math.sin(angleToRadian(rotate)) +
|
||||
center.x,
|
||||
y:
|
||||
(point.x - center.x) * Math.sin(angleToRadian(rotate)) +
|
||||
(point.y - center.y) * Math.cos(angleToRadian(rotate)) +
|
||||
center.y,
|
||||
};
|
||||
}
|
||||
|
||||
export function getRect(
|
||||
direction: DirectionType,
|
||||
item: IBlockType,
|
||||
rotate: number,
|
||||
curPositon: Point,
|
||||
symmetricPoint: Point
|
||||
) {
|
||||
switch (direction) {
|
||||
case 'topleft':
|
||||
calculateTopLeft(item, rotate, curPositon, symmetricPoint);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function calculateTopLeft(
|
||||
item: IBlockType,
|
||||
rotate: number,
|
||||
curPositon: Point,
|
||||
symmetricPoint: Point
|
||||
) {
|
||||
let newCenterPoint = getCenterPoint(curPositon, symmetricPoint);
|
||||
let newTopLeftPoint = calculateRotatedPointCoordinate(curPositon, newCenterPoint, -rotate);
|
||||
let newBottomRightPoint = calculateRotatedPointCoordinate(
|
||||
symmetricPoint,
|
||||
newCenterPoint,
|
||||
-rotate
|
||||
);
|
||||
|
||||
let newWidth = newBottomRightPoint.x - newTopLeftPoint.x;
|
||||
let newHeight = newBottomRightPoint.y - newTopLeftPoint.y;
|
||||
console.log(curPositon, symmetricPoint);
|
||||
console.log(newWidth, newHeight);
|
||||
if (newWidth > 0 && newHeight > 0) {
|
||||
item.width = Math.round(newWidth);
|
||||
item.height = Math.round(newHeight);
|
||||
item.left = Math.round(newTopLeftPoint.x);
|
||||
item.top = Math.round(newTopLeftPoint.y);
|
||||
}
|
||||
console.log(item.width, item.height, item.left, item.top);
|
||||
}
|
||||
|
||||
// function calculateRightTop(style, curPositon, pointInfo) {
|
||||
// const { symmetricPoint } = pointInfo
|
||||
// let newCenterPoint = getCenterPoint(curPositon, symmetricPoint)
|
||||
// let newTopRightPoint = calculateRotatedPointCoordinate(curPositon, newCenterPoint, -style.rotate)
|
||||
// let newBottomLeftPoint = calculateRotatedPointCoordinate(symmetricPoint, newCenterPoint, -style.rotate)
|
||||
|
||||
// let newWidth = newTopRightPoint.x - newBottomLeftPoint.x
|
||||
// let newHeight = newBottomLeftPoint.y - newTopRightPoint.y
|
||||
|
||||
// if (newWidth > 0 && newHeight > 0) {
|
||||
// style.width = Math.round(newWidth)
|
||||
// style.height = Math.round(newHeight)
|
||||
// style.left = Math.round(newBottomLeftPoint.x)
|
||||
// style.top = Math.round(newTopRightPoint.y)
|
||||
// }
|
||||
// }
|
||||
|
||||
// function calculateRightBottom(style, curPositon, pointInfo) {
|
||||
// const { symmetricPoint } = pointInfo
|
||||
// let newCenterPoint = getCenterPoint(curPositon, symmetricPoint)
|
||||
// let newTopLeftPoint = calculateRotatedPointCoordinate(symmetricPoint, newCenterPoint, -style.rotate)
|
||||
// let newBottomRightPoint = calculateRotatedPointCoordinate(curPositon, newCenterPoint, -style.rotate)
|
||||
|
||||
// let newWidth = newBottomRightPoint.x - newTopLeftPoint.x
|
||||
// let newHeight = newBottomRightPoint.y - newTopLeftPoint.y
|
||||
|
||||
// if (newWidth > 0 && newHeight > 0) {
|
||||
// style.width = Math.round(newWidth)
|
||||
// style.height = Math.round(newHeight)
|
||||
// style.left = Math.round(newTopLeftPoint.x)
|
||||
// style.top = Math.round(newTopLeftPoint.y)
|
||||
// }
|
||||
// }
|
||||
|
||||
// function calculateLeftBottom(style, curPositon, pointInfo) {
|
||||
// const { symmetricPoint } = pointInfo
|
||||
// let newCenterPoint = getCenterPoint(curPositon, symmetricPoint)
|
||||
// let newTopRightPoint = calculateRotatedPointCoordinate(symmetricPoint, newCenterPoint, -style.rotate)
|
||||
// let newBottomLeftPoint = calculateRotatedPointCoordinate(curPositon, newCenterPoint, -style.rotate)
|
||||
|
||||
// let newWidth = newTopRightPoint.x - newBottomLeftPoint.x
|
||||
// let newHeight = newBottomLeftPoint.y - newTopRightPoint.y
|
||||
|
||||
// if (newWidth > 0 && newHeight > 0) {
|
||||
// style.width = Math.round(newWidth)
|
||||
// style.height = Math.round(newHeight)
|
||||
// style.left = Math.round(newBottomLeftPoint.x)
|
||||
// style.top = Math.round(newTopRightPoint.y)
|
||||
// }
|
||||
// }
|
||||
|
||||
// function calculateTop(style, curPositon, pointInfo) {
|
||||
// const { symmetricPoint, curPoint } = pointInfo
|
||||
// let rotatedcurPositon = calculateRotatedPointCoordinate(curPositon, curPoint, -style.rotate)
|
||||
// let rotatedTopMiddlePoint = calculateRotatedPointCoordinate({
|
||||
// x: curPoint.x,
|
||||
// y: rotatedcurPositon.y,
|
||||
// }, curPoint, style.rotate)
|
||||
|
||||
// let newHeight = Math.sqrt((rotatedTopMiddlePoint.x - symmetricPoint.x) ** 2 + (rotatedTopMiddlePoint.y - symmetricPoint.y) ** 2)
|
||||
|
||||
// if (newHeight > 0) {
|
||||
// const newCenter = {
|
||||
// x: rotatedTopMiddlePoint.x - (rotatedTopMiddlePoint.x - symmetricPoint.x) / 2,
|
||||
// y: rotatedTopMiddlePoint.y + (symmetricPoint.y - rotatedTopMiddlePoint.y) / 2,
|
||||
// }
|
||||
|
||||
// let width = style.width
|
||||
// // 因为调整的是高度 所以只需根据锁定的比例调整宽度即可
|
||||
// style.width = width
|
||||
// style.height = Math.round(newHeight)
|
||||
// style.top = Math.round(newCenter.y - (newHeight / 2))
|
||||
// style.left = Math.round(newCenter.x - (style.width / 2))
|
||||
// }
|
||||
// }
|
||||
|
||||
// function calculateRight(style, curPositon, pointInfo) {
|
||||
// const { symmetricPoint, curPoint } = pointInfo
|
||||
// const rotatedcurPositon = calculateRotatedPointCoordinate(curPositon, curPoint, -style.rotate)
|
||||
// const rotatedRightMiddlePoint = calculateRotatedPointCoordinate({
|
||||
// x: rotatedcurPositon.x,
|
||||
// y: curPoint.y,
|
||||
// }, curPoint, style.rotate)
|
||||
|
||||
// let newWidth = Math.sqrt((rotatedRightMiddlePoint.x - symmetricPoint.x) ** 2 + (rotatedRightMiddlePoint.y - symmetricPoint.y) ** 2)
|
||||
// if (newWidth > 0) {
|
||||
// const newCenter = {
|
||||
// x: rotatedRightMiddlePoint.x - (rotatedRightMiddlePoint.x - symmetricPoint.x) / 2,
|
||||
// y: rotatedRightMiddlePoint.y + (symmetricPoint.y - rotatedRightMiddlePoint.y) / 2,
|
||||
// }
|
||||
|
||||
// let height = style.height
|
||||
|
||||
// style.height = height
|
||||
// style.width = Math.round(newWidth)
|
||||
// style.top = Math.round(newCenter.y - (style.height / 2))
|
||||
// style.left = Math.round(newCenter.x - (newWidth / 2))
|
||||
// }
|
||||
// }
|
||||
|
||||
// function calculateBottom(style, curPositon, pointInfo) {
|
||||
// const { symmetricPoint, curPoint } = pointInfo
|
||||
// const rotatedcurPositon = calculateRotatedPointCoordinate(curPositon, curPoint, -style.rotate)
|
||||
// const rotatedBottomMiddlePoint = calculateRotatedPointCoordinate({
|
||||
// x: curPoint.x,
|
||||
// y: rotatedcurPositon.y,
|
||||
// }, curPoint, style.rotate)
|
||||
|
||||
// const newHeight = Math.sqrt((rotatedBottomMiddlePoint.x - symmetricPoint.x) ** 2 + (rotatedBottomMiddlePoint.y - symmetricPoint.y) ** 2)
|
||||
// if (newHeight > 0) {
|
||||
// const newCenter = {
|
||||
// x: rotatedBottomMiddlePoint.x - (rotatedBottomMiddlePoint.x - symmetricPoint.x) / 2,
|
||||
// y: rotatedBottomMiddlePoint.y + (symmetricPoint.y - rotatedBottomMiddlePoint.y) / 2,
|
||||
// }
|
||||
|
||||
// let width = style.width
|
||||
// style.width = width
|
||||
// style.height = Math.round(newHeight)
|
||||
// style.top = Math.round(newCenter.y - (newHeight / 2))
|
||||
// style.left = Math.round(newCenter.x - (style.width / 2))
|
||||
// }
|
||||
// }
|
||||
|
||||
// function calculateLeft(style, curPositon, pointInfo) {
|
||||
// const { symmetricPoint, curPoint } = pointInfo
|
||||
// const rotatedcurPositon = calculateRotatedPointCoordinate(curPositon, curPoint, -style.rotate)
|
||||
// const rotatedLeftMiddlePoint = calculateRotatedPointCoordinate({
|
||||
// x: rotatedcurPositon.x,
|
||||
// y: curPoint.y,
|
||||
// }, curPoint, style.rotate)
|
||||
|
||||
// const newWidth = Math.sqrt((rotatedLeftMiddlePoint.x - symmetricPoint.x) ** 2 + (rotatedLeftMiddlePoint.y - symmetricPoint.y) ** 2)
|
||||
// if (newWidth > 0) {
|
||||
// const newCenter = {
|
||||
// x: rotatedLeftMiddlePoint.x - (rotatedLeftMiddlePoint.x - symmetricPoint.x) / 2,
|
||||
// y: rotatedLeftMiddlePoint.y + (symmetricPoint.y - rotatedLeftMiddlePoint.y) / 2,
|
||||
// }
|
||||
// let height = style.height
|
||||
// style.height = height
|
||||
// style.width = Math.round(newWidth)
|
||||
// style.top = Math.round(newCenter.y - (style.height / 2))
|
||||
// style.left = Math.round(newCenter.x - (newWidth / 2))
|
||||
// }
|
||||
// }
|
@@ -5,6 +5,7 @@ import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
import styles from '../../index.less';
|
||||
import UserConfig from '../../config';
|
||||
import { getRect } from './calcWithRotate';
|
||||
interface BlockResizerProps {
|
||||
data: IBlockType;
|
||||
rect: RefObject<HTMLDivElement>;
|
||||
@@ -15,11 +16,11 @@ interface resizeStateType {
|
||||
startY: number;
|
||||
item: null | IBlockType;
|
||||
isResize: boolean;
|
||||
direction: directionType;
|
||||
direction: DirectionType;
|
||||
ref: RefObject<HTMLDivElement> | null;
|
||||
current: number;
|
||||
}
|
||||
type directionType =
|
||||
export type DirectionType =
|
||||
| 'top'
|
||||
| 'topleft'
|
||||
| 'topright'
|
||||
@@ -40,7 +41,7 @@ export const resizeState: resizeStateType = {
|
||||
|
||||
const onMouseDown = (
|
||||
e: React.MouseEvent,
|
||||
direction: directionType,
|
||||
direction: DirectionType,
|
||||
item: IBlockType,
|
||||
ref: RefObject<HTMLDivElement>,
|
||||
config: UserConfig
|
||||
@@ -67,7 +68,20 @@ export const resizerMouseUp = (config: UserConfig) => {
|
||||
}
|
||||
resizeState.current = 0;
|
||||
};
|
||||
const changePosition = (
|
||||
|
||||
/**
|
||||
*
|
||||
* 无旋转时计算函数
|
||||
* @param {IBlockType} v
|
||||
* @param {number} durX
|
||||
* @param {number} durY
|
||||
* @param {{
|
||||
* value: number;
|
||||
* maxValue: number;
|
||||
* minValue: number;
|
||||
* }} scaleState
|
||||
*/
|
||||
export const changePosition = (
|
||||
v: IBlockType,
|
||||
durX: number,
|
||||
durY: number,
|
||||
@@ -122,20 +136,81 @@ const changePosition = (
|
||||
}
|
||||
};
|
||||
|
||||
// export const getRealStart = (rect: DOMRect): { realStartX: number; realStartY: number } => {
|
||||
// const direction = resizeState.direction;
|
||||
// switch (direction) {
|
||||
// case 'left':
|
||||
// return {
|
||||
// realStartX: rect.left,
|
||||
// realStartY: rect.top + rect.height / 2,
|
||||
// };
|
||||
// case 'top':
|
||||
// return {
|
||||
// realStartX: rect.left + rect.width / 2,
|
||||
// realStartY: rect.top,
|
||||
// };
|
||||
// case 'right':
|
||||
// return {
|
||||
// realStartX: rect.left + rect.width,
|
||||
// realStartY: rect.top + rect.height / 2,
|
||||
// };
|
||||
// case 'bottom':
|
||||
// return {
|
||||
// realStartX: rect.left + rect.width / 2,
|
||||
// realStartY: rect.top + rect.height,
|
||||
// };
|
||||
// case 'topleft':
|
||||
// return {
|
||||
// realStartX: rect.left,
|
||||
// realStartY: rect.top,
|
||||
// };
|
||||
// case 'topright':
|
||||
// return {
|
||||
// realStartX: rect.left + rect.width,
|
||||
// realStartY: rect.top,
|
||||
// };
|
||||
// case 'bottomleft':
|
||||
// break;
|
||||
// case 'bottomright':
|
||||
// break;
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
// };
|
||||
|
||||
export const resizerMouseMove = (e: React.MouseEvent, config: UserConfig) => {
|
||||
//根据direction修改位置
|
||||
const scaleState = config.getScaleState();
|
||||
const store = config.getStore();
|
||||
if (resizeState.isResize && resizeState.item) {
|
||||
if (resizeState.isResize && resizeState.item && resizeState.ref?.current) {
|
||||
let { clientX: moveX, clientY: moveY } = e;
|
||||
const { startX, startY } = resizeState;
|
||||
const scale = scaleState.value;
|
||||
let durX = (moveX - startX) / scale;
|
||||
let durY = (moveY - startY) / scale;
|
||||
console.log(scale);
|
||||
const rect = resizeState.ref.current.getBoundingClientRect();
|
||||
const centerX = rect.left + rect.width / 2;
|
||||
const centerY = rect.top + rect.height / 2;
|
||||
// const durX = (moveX - startX) / scale;
|
||||
// const durY = (moveY - startY) / scale;
|
||||
// rect经过旋转后
|
||||
// const { realStartX, realStartY } = getRealStart(rect);
|
||||
|
||||
const rotate = resizeState.item.rotate.value;
|
||||
const curPositon = {
|
||||
x: startX,
|
||||
y: startY,
|
||||
};
|
||||
const symmetricPoint = {
|
||||
x: centerX - (startX - centerX),
|
||||
y: centerY - (startY - centerY),
|
||||
};
|
||||
|
||||
console.log(centerX, centerY);
|
||||
const clonedata = deepCopy(store.getData());
|
||||
const id = resizeState.item.id;
|
||||
const newblock: IBlockType[] = clonedata.block.map((v: IBlockType) => {
|
||||
if (v.id === resizeState.item!.id) {
|
||||
changePosition(v, durX, durY, scaleState);
|
||||
if (v.id === id) {
|
||||
getRect(resizeState.direction, v, rotate, curPositon, symmetricPoint);
|
||||
}
|
||||
return v;
|
||||
});
|
||||
@@ -145,7 +220,7 @@ export const resizerMouseMove = (e: React.MouseEvent, config: UserConfig) => {
|
||||
}
|
||||
};
|
||||
|
||||
const directionArr: directionType[] = [
|
||||
const directionArr: DirectionType[] = [
|
||||
'top',
|
||||
'topleft',
|
||||
'left',
|
||||
|
107
packages/dooringx-lib/src/core/rotateHandler/index.tsx
Normal file
107
packages/dooringx-lib/src/core/rotateHandler/index.tsx
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* @Author: yehuozhili
|
||||
* @Date: 2021-07-21 20:51:58
|
||||
* @LastEditors: yehuozhili
|
||||
* @LastEditTime: 2021-07-22 20:51:08
|
||||
* @FilePath: \dooringx\packages\dooringx-lib\src\core\rotateHandler\index.tsx
|
||||
*/
|
||||
import React from 'react';
|
||||
import { RefObject, useMemo } from 'react';
|
||||
import UserConfig from '../../config';
|
||||
import { IBlockType } from '../store/storetype';
|
||||
import styles from '../../index.less';
|
||||
import { deepCopy } from '../utils';
|
||||
|
||||
interface rotateStateType {
|
||||
startX: number;
|
||||
startY: number;
|
||||
item: null | IBlockType;
|
||||
isRotate: boolean;
|
||||
ref: RefObject<HTMLDivElement> | null;
|
||||
current: number;
|
||||
}
|
||||
|
||||
export const rotateState: rotateStateType = {
|
||||
startX: 0,
|
||||
startY: 0,
|
||||
item: null,
|
||||
isRotate: false,
|
||||
ref: null,
|
||||
current: 0,
|
||||
};
|
||||
|
||||
const onMouseDown = (
|
||||
e: React.MouseEvent,
|
||||
item: IBlockType,
|
||||
ref: RefObject<HTMLDivElement>,
|
||||
config: UserConfig
|
||||
) => {
|
||||
e.stopPropagation();
|
||||
const store = config.getStore();
|
||||
rotateState.isRotate = true;
|
||||
rotateState.item = item;
|
||||
rotateState.startX = e.clientX;
|
||||
rotateState.startY = e.clientY;
|
||||
rotateState.ref = ref;
|
||||
rotateState.current = store.getIndex();
|
||||
};
|
||||
|
||||
export const rotateMouseMove = (e: React.MouseEvent, config: UserConfig) => {
|
||||
const store = config.getStore();
|
||||
if (rotateState.isRotate && rotateState.item && rotateState.ref?.current) {
|
||||
let { clientX: moveX, clientY: moveY } = e;
|
||||
const { startX, startY } = rotateState;
|
||||
const rect = rotateState.ref.current.getBoundingClientRect();
|
||||
const centerX = rect.left + rect.width / 2;
|
||||
const centerY = rect.top + rect.height / 2;
|
||||
const rotateDegreeBefore = Math.atan2(startY - centerY, startX - centerX) / (Math.PI / 180);
|
||||
const rotateDegreeAfter = Math.atan2(moveY - centerY, moveX - centerX) / (Math.PI / 180);
|
||||
const startRotate = rotateState.item.rotate.value;
|
||||
const frotate = startRotate + rotateDegreeAfter - rotateDegreeBefore;
|
||||
const clonedata = deepCopy(store.getData());
|
||||
const id = rotateState.item.id;
|
||||
const newblock: IBlockType[] = clonedata.block.map((v: IBlockType) => {
|
||||
if (v.id === id) {
|
||||
v.rotate.value = frotate;
|
||||
}
|
||||
return v;
|
||||
});
|
||||
store.setData({ ...clonedata, block: newblock });
|
||||
}
|
||||
};
|
||||
|
||||
export const rotateMouseUp = (config: UserConfig) => {
|
||||
rotateState.isRotate = false;
|
||||
rotateState.item = null;
|
||||
const store = config.getStore();
|
||||
if (rotateState.current) {
|
||||
const endindex = store.getIndex();
|
||||
store.getStoreList().splice(rotateState.current, endindex - rotateState.current);
|
||||
store.setIndex(rotateState.current);
|
||||
}
|
||||
rotateState.current = 0;
|
||||
};
|
||||
|
||||
interface RotateResizerProps {
|
||||
data: IBlockType;
|
||||
rect: RefObject<HTMLDivElement>;
|
||||
config: UserConfig;
|
||||
}
|
||||
export function RotateResizer(props: RotateResizerProps) {
|
||||
const render = useMemo(() => {
|
||||
if (props.data.focus && props.data.rotate.canRotate) {
|
||||
return (
|
||||
<div
|
||||
onMouseDown={(e) => {
|
||||
onMouseDown(e, props.data, props.rect, props.config);
|
||||
}}
|
||||
className={styles.rotate}
|
||||
></div>
|
||||
);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}, [props.config, props.data, props.rect]);
|
||||
|
||||
return <>{render}</>;
|
||||
}
|
@@ -2,8 +2,8 @@
|
||||
* @Author: yehuozhili
|
||||
* @Date: 2021-03-14 04:29:09
|
||||
* @LastEditors: yehuozhili
|
||||
* @LastEditTime: 2021-07-09 17:22:14
|
||||
* @FilePath: \DooringV2\packages\dooringx-lib\src\core\store\storetype.ts
|
||||
* @LastEditTime: 2021-07-21 20:54:38
|
||||
* @FilePath: \dooringx\packages\dooringx-lib\src\core\store\storetype.ts
|
||||
*/
|
||||
|
||||
import { EventCenterMapType } from '../eventCenter';
|
||||
@@ -37,6 +37,10 @@ export interface IBlockType {
|
||||
syncList: Array<string>;
|
||||
eventMap: EventCenterMapType; //调用的event 与对应的函数名 如果要增加参数,则类型不能是Array<string>,需要[{name:string,...args}]
|
||||
functionList: Array<string>; //抛出的函数名
|
||||
rotate: {
|
||||
value: number;
|
||||
canRotate: boolean;
|
||||
};
|
||||
animate: {
|
||||
animate?: string; //动画名
|
||||
animationIterationCount?: number | string;
|
||||
|
@@ -2,8 +2,8 @@
|
||||
* @Author: yehuozhili
|
||||
* @Date: 2021-04-05 14:55:31
|
||||
* @LastEditors: yehuozhili
|
||||
* @LastEditTime: 2021-07-09 18:31:24
|
||||
* @FilePath: \DooringV2\packages\dooringx-lib\src\core\storeChanger\index.ts
|
||||
* @LastEditTime: 2021-07-21 20:55:03
|
||||
* @FilePath: \dooringx\packages\dooringx-lib\src\core\storeChanger\index.ts
|
||||
*/
|
||||
|
||||
import { message } from 'antd';
|
||||
@@ -42,6 +42,10 @@ function createDefaultModalBlock(): IStoreData['block'] {
|
||||
functionList: [],
|
||||
animate: {},
|
||||
fixed: false,
|
||||
rotate: {
|
||||
value: 0,
|
||||
canRotate: false,
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* @Author: yehuozhili
|
||||
* @Date: 2021-04-21 22:59:57
|
||||
* @LastEditors: yehuozhili
|
||||
* @LastEditTime: 2021-07-20 16:19:21
|
||||
* @LastEditTime: 2021-07-21 14:33:57
|
||||
* @FilePath: \dooringx\packages\dooringx-lib\src\core\transfer\index.ts
|
||||
*/
|
||||
|
||||
@@ -22,8 +22,10 @@ export function transfer(
|
||||
left: number,
|
||||
height: string | number | undefined,
|
||||
width: string | number | undefined,
|
||||
isFixed: boolean
|
||||
isFixed: boolean,
|
||||
rotate: number
|
||||
) {
|
||||
console.log(rotate);
|
||||
if (isFixed) {
|
||||
// 由于是375x667基准,所以top大于667的,那么top为底部高度
|
||||
let newtop = 0;
|
||||
|
@@ -290,3 +290,7 @@ export function postMessage(value: any, src: string, target = 'yh-container-ifra
|
||||
console.warn(`can not find iframe ${search}`);
|
||||
}
|
||||
}
|
||||
|
||||
export function angleToRadian(angle: number) {
|
||||
return (angle * Math.PI) / 180;
|
||||
}
|
||||
|
@@ -171,3 +171,14 @@
|
||||
position: relative;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.rotate {
|
||||
position: absolute;
|
||||
top: -30px;
|
||||
left: calc(50% - 6px);
|
||||
height: 12px;
|
||||
width: 12px;
|
||||
border-radius: 50%;
|
||||
background-color: #2196f3;
|
||||
cursor: grab;
|
||||
}
|
||||
|
Reference in New Issue
Block a user