import React from "react"; import Moveable from "./react-moveable"; import logo from "./logo.svg"; import "./App.css"; import { ref } from "framework-utils"; import KeyController from "keycon"; import { setAlias, Frame } from "scenejs"; import { IObject } from "@daybrush/utils"; setAlias("tx", ["transform", "translateX"]); setAlias("ty", ["transform", "translateY"]); setAlias("tz", ["transform", "translateZ"]); setAlias("rotate", ["transform", "rotate"]); setAlias("sx", ["transform", "scaleX"]); setAlias("sy", ["transform", "scaleY"]); setAlias("matrix3d", ["transform", "matrix3d"]); class App extends React.Component { public moveable!: Moveable; public state = { target: null, container: null, targets: [], isResizable: true, emo: null, } as { container: any, target: any, emo: any, targets: Array, isResizable: boolean, }; private itemMap: Map = new Map(); private items: IObject = {}; public render() { const selectedTarget = this.state.target; const isResizable = true; // this.state.isResizable; const item = this.itemMap.get(selectedTarget)!; (window as any).a = this; return (
{ console.log("start", e); e.events.forEach(ev => { const groupItem = this.itemMap.get(ev.target)!; ev.set([ parseFloat(groupItem.get("tx")), parseFloat(groupItem.get("ty")), ]); }); }} onDragGroup={e => { // console.log(e.beforeDelta); e.events.forEach(ev => { const groupItem = this.itemMap.get(ev.target)!; groupItem.set("tx", `${ev.beforeTranslate[0]}px`); groupItem.set("ty", `${ev.beforeTranslate[1]}px`); ev.target.style.cssText += groupItem.toCSS(); }); }} onRotateGroupStart={e => { console.log("rgs", e); }} onRotateGroup={e => { e.events.forEach(ev => { const groupItem = this.itemMap.get(ev.target)!; if (!e.isPinch) { groupItem.set("tx", `${parseFloat(groupItem.get("tx")) + ev.drag.beforeDelta[0]}px`); groupItem.set("ty", `${parseFloat(groupItem.get("ty")) + ev.drag.beforeDelta[1]}px`); } console.log("A", parseFloat(groupItem.get("rotate")), ev.beforeDelta); groupItem.set("rotate", `${parseFloat(groupItem.get("rotate")) + ev.beforeDelta}deg`); ev.target.style.cssText += groupItem.toCSS(); }); }} onResizeGroupStart={e => { console.log("rgs", e); e.events.forEach(ev => { const groupItem = this.itemMap.get(ev.target)!; ev.setOrigin(["%", "%"]); ev.dragStart && ev.dragStart.set([ parseFloat(groupItem.get("tx")), parseFloat(groupItem.get("ty")), ]); }); }} onResizeGroup={e => { e.events.forEach(ev => { const groupItem = this.itemMap.get(ev.target)!; // groupItem.set("tx", `${parseFloat(groupItem.get("tx")) + ev.drag.beforeDelta[0]}px`); // groupItem.set("ty", `${parseFloat(groupItem.get("ty")) + ev.drag.beforeDelta[1]}px`); console.log(ev.drag.beforeTranslate[0]); groupItem.set("tx", `${ev.drag.beforeTranslate[0]}px`); groupItem.set("ty", `${ev.drag.beforeTranslate[1]}px`); groupItem.set("width", `${ev.width}px`); groupItem.set("height", `${ev.height}px`); ev.target.style.cssText += groupItem.toCSS(); }); }} onScaleGroupStart={e => { console.log("scs", e); }} onScaleGroup={e => { e.events.forEach(ev => { // console.log("sca", ev.drag.dist); const groupItem = this.itemMap.get(ev.target)!; groupItem.set("tx", `${parseFloat(groupItem.get("tx")) + ev.drag.beforeDelta[0]}px`); groupItem.set("ty", `${parseFloat(groupItem.get("ty")) + ev.drag.beforeDelta[1]}px`); groupItem.set("sx", groupItem.get("sx") * ev.delta[0]); groupItem.set("sy", groupItem.get("sy") * ev.delta[1]); ev.target.style.cssText += groupItem.toCSS(); }); }} onClickGroup={e => { console.log(e); }} /> ("#con")} ref={ref(this, "moveable")} keepRatio={true} origin={false} dragArea={true} draggable={true} snappable={true} scrollable={true} transformOrigin="% %" bounds={{ left: 30, top: 20 }} verticalGuidelines={[100, 200, 400, 500]} horizontalGuidelines={[100, 200, 400, 500]} // renderDirections={["n", "ne", "nw"]} elementGuidelines={[document.querySelector(".box1 span")!, document.querySelector(".emo img")!]} snapCenter={false} // snapThreshold={10} // scalable={!isResizable} // scalable={true} resizable={isResizable} // warpable={true} throttleDrag={0} throttleScale={0} throttleResize={0} throttleRotate={1} rotatable={true} pinchable={true} onScroll={({ scrollContainer, direction }) => { scrollContainer.scrollBy(direction[0] * 10, direction[1] * 10); }} onRotateStart={({ set }) => { const rotate = parseFloat(item.get("rotate")) || 0; set(rotate); }} onRotate={({ target, beforeRotate }) => { item.set("rotate", `${beforeRotate}deg`); target.style.cssText += item.toCSS(); }} onDragStart={({ set }) => { const tx = parseFloat(item.get("tx")) || 0; const ty = parseFloat(item.get("ty")) || 0; set([tx, ty]); }} onDrag={({ target, beforeTranslate }) => { item.set("tx", `${beforeTranslate[0]}px`); item.set("ty", `${beforeTranslate[1]}px`); // target!.style.left = `${left}px`; // target!.style.top = `${top}px`; target.style.cssText += item.toCSS(); }} onScaleStart={({ set, dragStart }) => { const sx = parseFloat(item.get("sx")) || 0; const sy = parseFloat(item.get("sy")) || 0; const tx = parseFloat(item.get("tx")) || 0; const ty = parseFloat(item.get("ty")) || 0; set([sx, sy]); dragStart && dragStart.set([tx, ty]); }} onScale={({ target, scale, drag }) => { item.set("sx", scale[0]); item.set("sy", scale[1]); item.set("tx", `${drag.beforeTranslate[0]}px`); item.set("ty", `${drag.beforeTranslate[1]}px`); target.style.cssText += item.toCSS(); }} onResizeStart={({ dragStart, setOrigin }) => { const tx = parseFloat(item.get("tx")) || 0; const ty = parseFloat(item.get("ty")) || 0; setOrigin(["%", "%"]); dragStart && dragStart.set([tx, ty]); }} onResize={({ target, width, height, drag, delta }) => { // console.log(width, height); item.set("width", `${width}px`); item.set("height", `${height}px`); item.set("tx", `${drag.beforeTranslate[0]}px`); item.set("ty", `${drag.beforeTranslate[1]}px`); target.style.cssText += item.toCSS(); }} onWarp={({ target, delta, matrix, multiply }) => { const matrix3d = item.get("matrix3d"); if (!matrix3d) { item.set("matrix3d", delta); } else { item.set("matrix3d", multiply(item.get("matrix3d"), delta, 4)); } // item.set("matrix3d", matrix); target.style.cssText += item.toCSS(); }} onClick={e => { console.log(e); }} />
ABC
{this.state.container && { e.target.style.transform = e.transform; }} />}
A
logo

Edit src/App.tsx and save to reload.

Learn React
); } public onCLickOuside = (e: any) => { } public onClickInside = (e: any) => { const target = e.target; } public setItem(el: HTMLElement | SVGElement) { this.itemMap.set(el, new Frame({ tz: "5px", tx: "0px", ty: "0px", rotate: "0deg", sx: 1, sy: 1, })); } public onClick = (e: any) => { const target = e.target; const id = target.getAttribute("data-target"); e.preventDefault(); const clientX = e.clientX; const clientY = e.clientY; // console.log(this.moveable.isInside(clientX, clientY)); // this.state.target && this.moveable.isInside(clientX, clientY) if (!id) { return; } if (!this.itemMap.get(target)) { this.setItem(target); } if (!this.moveable.isMoveableElement(e.target)) { if (this.state.target === e.target) { this.moveable.updateRect(); } else { const nativeEvent = e.nativeEvent; this.setState({ target: e.target, }, () => { }); this.moveable.dragStart(nativeEvent); } } } public componentDidMount() { const keycon = new KeyController(window); keycon.keydown("shift", () => { this.setState({ isResizable: false }); }).keyup("shift", () => { this.setState({ isResizable: true }); }); const targets: any[] = [].slice.call(document.querySelectorAll(`[data-target="box"] span`)); targets.forEach(target => { this.setItem(target); }); this.setState({ targets, }); setTimeout(() => { this.setState({ emo: document.querySelector(".emo") as HTMLElement, }, () => { this.setState({ container: document.querySelector(".App-header"), }); }); }, 100); } } export default App;