mirror of
https://github.com/tidys/cc-inspector-chrome
synced 2025-04-16 07:01:03 +00:00
适配v2,v3的hover,select逻辑
This commit is contained in:
parent
e47cf0d3c0
commit
eac45d1fd0
@ -1,375 +0,0 @@
|
|||||||
import ccui from "@xuyanfeng/cc-ui";
|
|
||||||
import { IUiMenuItem } from "@xuyanfeng/cc-ui/types/cc-menu/const";
|
|
||||||
import { DocumentEvent } from "../const";
|
|
||||||
import { Inspector } from "./inspector";
|
|
||||||
import { Msg } from "../../core/types";
|
|
||||||
declare const cc: any;
|
|
||||||
class Point {
|
|
||||||
x: number;
|
|
||||||
y: number;
|
|
||||||
constructor(x: number, y: number) {
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
class RectPoints {
|
|
||||||
points: Point[] = [];
|
|
||||||
get len() {
|
|
||||||
return this.points.length;
|
|
||||||
}
|
|
||||||
at(index: number) {
|
|
||||||
return this.points[index];
|
|
||||||
}
|
|
||||||
test(width: number, height: number) {
|
|
||||||
this.points.push(new Point(0, 0));
|
|
||||||
this.points.push(new Point(width, 0));
|
|
||||||
this.points.push(new Point(width, height));
|
|
||||||
this.points.push(new Point(0, height));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
interface DrawOptions {
|
|
||||||
fill: boolean;
|
|
||||||
fillColor: string;
|
|
||||||
stroke: boolean;
|
|
||||||
strokeColor: string;
|
|
||||||
}
|
|
||||||
export class Hint {
|
|
||||||
private draw = null;
|
|
||||||
public engineVersion: string = "";
|
|
||||||
private inspector: Inspector = null;
|
|
||||||
constructor(inspector: Inspector) {
|
|
||||||
this.inspector = inspector;
|
|
||||||
document.addEventListener(DocumentEvent.GameInspectorBegan, (event: CustomEvent) => {
|
|
||||||
const el = this.getTargetElement();
|
|
||||||
if (!el) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const cursor = el.style.cursor;
|
|
||||||
el.style.cursor = "zoom-in";
|
|
||||||
const test = (event: MouseEvent) => {
|
|
||||||
event.stopPropagation();
|
|
||||||
event.preventDefault();
|
|
||||||
el.removeEventListener("mousedown", test, true);
|
|
||||||
el.style.cursor = cursor;
|
|
||||||
const e = new CustomEvent(DocumentEvent.GameInspectorEnd);
|
|
||||||
document.dispatchEvent(e);
|
|
||||||
this.updateHint(event, el);
|
|
||||||
};
|
|
||||||
el.addEventListener("mousedown", test, true);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
private nodeVisible(node) {
|
|
||||||
let parent = node;
|
|
||||||
while (parent) {
|
|
||||||
if (parent) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private updateHint(event: MouseEvent, canvas: HTMLCanvasElement) {
|
|
||||||
this.cleanHover();
|
|
||||||
this.cleanSelected();
|
|
||||||
const rect = canvas.getBoundingClientRect();
|
|
||||||
let x = event.clientX - rect.x;
|
|
||||||
let y = rect.y + rect.height - event.clientY;
|
|
||||||
x *= window.devicePixelRatio;
|
|
||||||
y *= window.devicePixelRatio;
|
|
||||||
|
|
||||||
this.inspector.updateTreeInfo(false);
|
|
||||||
const nodes = [];
|
|
||||||
this.inspector.forEachNode((item) => {
|
|
||||||
const b = item._uiProps?.uiTransformComp?.hitTest({ x, y }, 0);
|
|
||||||
if (b && item.active && item.activeInHierarchy) {
|
|
||||||
nodes.push(item);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (nodes.length === 1) {
|
|
||||||
const item = nodes[0];
|
|
||||||
this.setSelected(item);
|
|
||||||
this.sendInspectNodeMsg(item);
|
|
||||||
} else {
|
|
||||||
nodes.reverse();
|
|
||||||
const menu = nodes.map((item) => {
|
|
||||||
const path = this.getPath(item);
|
|
||||||
return {
|
|
||||||
name: path,
|
|
||||||
callback: () => {
|
|
||||||
this.cleanHover();
|
|
||||||
this.setSelected(item);
|
|
||||||
this.sendInspectNodeMsg(item);
|
|
||||||
},
|
|
||||||
enter: () => {
|
|
||||||
this.setHover(item);
|
|
||||||
},
|
|
||||||
leave: () => {
|
|
||||||
this.cleanHover();
|
|
||||||
},
|
|
||||||
} as IUiMenuItem;
|
|
||||||
});
|
|
||||||
ccui.menu.showMenuByMouseEvent(event, menu, 0.8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private sendInspectNodeMsg(node: any) {
|
|
||||||
if (node.uuid) {
|
|
||||||
this.inspector.sendMsgToContent(Msg.InspectNode, node.uuid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private getPath(node: any) {
|
|
||||||
let path = [];
|
|
||||||
let parent = node;
|
|
||||||
while (parent) {
|
|
||||||
path.push(parent.name);
|
|
||||||
parent = parent.parent;
|
|
||||||
}
|
|
||||||
path = path.reverse();
|
|
||||||
return path.join("/");
|
|
||||||
}
|
|
||||||
private getTargetElement(): HTMLCanvasElement | null {
|
|
||||||
// @ts-ignore
|
|
||||||
if (typeof cc !== "undefined" && cc.game && cc.game.canvas) {
|
|
||||||
// @ts-ignore
|
|
||||||
return cc.game.canvas;
|
|
||||||
} else {
|
|
||||||
null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private get isEngineV2() {
|
|
||||||
return this.engineVersion.startsWith("2.");
|
|
||||||
}
|
|
||||||
private get isEngineV3() {
|
|
||||||
return this.engineVersion.startsWith("3.");
|
|
||||||
}
|
|
||||||
public cleanHover() {
|
|
||||||
this.hoverNodes = [];
|
|
||||||
if (this.draw) {
|
|
||||||
this.draw.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public cleanSelected() {
|
|
||||||
this.selectedNodes = [];
|
|
||||||
if (this.draw) {
|
|
||||||
this.draw.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private initDrawNode() {
|
|
||||||
if (this.draw && !this.draw.isValid) {
|
|
||||||
this.draw = null;
|
|
||||||
}
|
|
||||||
if (this.draw) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const scene = cc.director.getScene();
|
|
||||||
if (!scene) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let node = new cc.Node("draw-node");
|
|
||||||
const canvas = cc.find("Canvas");
|
|
||||||
if (canvas) {
|
|
||||||
// 3.x 需要放到canvas下边
|
|
||||||
if (canvas.layer) {
|
|
||||||
node.layer = canvas.layer;
|
|
||||||
}
|
|
||||||
canvas.addChild(node);
|
|
||||||
} else {
|
|
||||||
scene.addChild(node);
|
|
||||||
}
|
|
||||||
this.draw = node.addComponent(cc.Graphics);
|
|
||||||
}
|
|
||||||
private hoverNodes = [];
|
|
||||||
private selectedNodes = [];
|
|
||||||
private resetIndex() {
|
|
||||||
if (this.isEngineV3) {
|
|
||||||
const len = this.draw.node.parent.children.length;
|
|
||||||
this.draw.node.setSiblingIndex(len);
|
|
||||||
} else if (this.isEngineV2) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public update() {
|
|
||||||
this.initDrawNode();
|
|
||||||
if (!this.draw) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.draw.clear();
|
|
||||||
this.resetIndex();
|
|
||||||
// this.testRect();
|
|
||||||
this.hoverNodes.forEach((node) => {
|
|
||||||
if (node.isValid) {
|
|
||||||
this.hintNode(node, {
|
|
||||||
fill: true,
|
|
||||||
fillColor: "#00ff0055",
|
|
||||||
stroke: true,
|
|
||||||
strokeColor: "#ffffff44",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.selectedNodes.forEach((node) => {
|
|
||||||
if (node.isValid) {
|
|
||||||
this.hintNode(node, {
|
|
||||||
fill: false,
|
|
||||||
fillColor: "#ff0000",
|
|
||||||
stroke: true,
|
|
||||||
strokeColor: "#ff0000",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
private testRect() {
|
|
||||||
const points = new RectPoints();
|
|
||||||
points.test(100, 100);
|
|
||||||
this.drawRect(points, {
|
|
||||||
fill: true,
|
|
||||||
fillColor: "#00ff0099",
|
|
||||||
stroke: true,
|
|
||||||
strokeColor: "#ff000099",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
public setHover(node: any) {
|
|
||||||
if (node.isValid) {
|
|
||||||
this.hoverNodes = [node];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public setSelected(node: any) {
|
|
||||||
if (node.isValid) {
|
|
||||||
this.selectedNodes = [node];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private getRectPoints(node: any): RectPoints | null {
|
|
||||||
if (this.isEngineV2) {
|
|
||||||
const points: RectPoints = new RectPoints();
|
|
||||||
return points;
|
|
||||||
} else if (this.isEngineV3) {
|
|
||||||
// v3版本
|
|
||||||
if (!node.worldPosition) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
const transform = cc.UITransformComponent || cc.UITransform;
|
|
||||||
if (!transform) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
const tr = node.getComponent(transform);
|
|
||||||
if (!tr) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
const { anchorPoint, width, height } = tr;
|
|
||||||
const points: RectPoints = new RectPoints();
|
|
||||||
const x = -anchorPoint.x * width;
|
|
||||||
const y = -anchorPoint.y * height;
|
|
||||||
const m = node.worldMatrix;
|
|
||||||
|
|
||||||
[
|
|
||||||
new Point(x, y), //
|
|
||||||
new Point(x + width, y),
|
|
||||||
new Point(x + width, y + height),
|
|
||||||
new Point(x, y + height),
|
|
||||||
].forEach(({ x, y }: Point) => {
|
|
||||||
let rhw = m.m03 * x + m.m07 * y + m.m15;
|
|
||||||
rhw = rhw ? 1 / rhw : 1;
|
|
||||||
let worldX = (m.m00 * x + m.m04 * y + m.m12) * rhw;
|
|
||||||
let worldY = (m.m01 * x + m.m05 * y + m.m13) * rhw;
|
|
||||||
let worldZ = (m.m02 * x + m.m06 * y + m.m14) * rhw;
|
|
||||||
const pos = this.draw.getComponent(transform).convertToNodeSpaceAR(cc.v3(worldX, worldY, worldZ));
|
|
||||||
points.points.push(new Point(pos.x, pos.y));
|
|
||||||
});
|
|
||||||
|
|
||||||
return points;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 尝试实现wireframe模式
|
|
||||||
*/
|
|
||||||
private getTrangles(node: any) {
|
|
||||||
const comps = node._components;
|
|
||||||
if (comps && Array.isArray(comps)) {
|
|
||||||
const m = node.worldMatrix;
|
|
||||||
comps.forEach((comp) => {
|
|
||||||
const { renderData } = comp;
|
|
||||||
if (!renderData) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const { data, _vc: VertexCount, _ic: IndexCount, chunk } = renderData;
|
|
||||||
if (!data) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取indexBuffer的索引顺序
|
|
||||||
const ib = chunk.meshBuffer.iData;
|
|
||||||
let indexOffset = chunk.meshBuffer.indexOffset;
|
|
||||||
const vidOrigin = chunk.vertexOffset;
|
|
||||||
const arr = [];
|
|
||||||
for (let i = 0; i < IndexCount; i++) {
|
|
||||||
const index = ib[indexOffset + i] - vidOrigin;
|
|
||||||
arr.push(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let j = 0; j < data.length; j++) {
|
|
||||||
const item = data[j];
|
|
||||||
const { x, y, z, u, v, color } = item;
|
|
||||||
let rhw = m.m03 * x + m.m07 * y + m.m15;
|
|
||||||
rhw = rhw ? 1 / rhw : 1;
|
|
||||||
|
|
||||||
let worldX = (m.m00 * x + m.m04 * y + m.m12) * rhw;
|
|
||||||
let worldY = (m.m01 * x + m.m05 * y + m.m13) * rhw;
|
|
||||||
let worldZ = (m.m02 * x + m.m06 * y + m.m14) * rhw;
|
|
||||||
// const pos = this.draw.getComponent(transform).convertToNodeSpaceAR(cc.v3(worldX, worldY, worldZ));
|
|
||||||
// points.points.push(new Point(pos.x, pos.y));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private getBox(node: any) {
|
|
||||||
if (node.getBoundingBoxToWorld) {
|
|
||||||
return node.getBoundingBoxToWorld();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cc.UITransformComponent) {
|
|
||||||
const tr = node.getComponent(cc.UITransformComponent);
|
|
||||||
if (tr && tr.getBoundingBoxToWorld) {
|
|
||||||
return tr.getBoundingBoxToWorld();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
private hintNode(node: any, opts: DrawOptions) {
|
|
||||||
const points = this.getRectPoints(node);
|
|
||||||
if (!points) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.drawRect(points, opts);
|
|
||||||
}
|
|
||||||
|
|
||||||
private drawRect(points: RectPoints, opts: DrawOptions) {
|
|
||||||
this.draw.lineWidth = 2;
|
|
||||||
for (let i = 0; i < points.len; i++) {
|
|
||||||
const p = points.at(i);
|
|
||||||
if (i === 0) {
|
|
||||||
this.draw.moveTo(p.x, p.y);
|
|
||||||
} else {
|
|
||||||
this.draw.lineTo(p.x, p.y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.draw.close();
|
|
||||||
if (opts.stroke) {
|
|
||||||
this.draw.strokeColor = new cc.Color().fromHEX(opts.strokeColor);
|
|
||||||
this.draw.stroke();
|
|
||||||
}
|
|
||||||
if (opts.fill) {
|
|
||||||
this.draw.fillColor = new cc.Color().fromHEX(opts.fillColor);
|
|
||||||
this.draw.fill();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private fillRect(points: RectPoints, color: string) {
|
|
||||||
this.draw.fillColor = new cc.Color().fromHEX(color);
|
|
||||||
for (let i = 0; i < points.len; i++) {
|
|
||||||
const p = points.at(i);
|
|
||||||
if (i === 0) {
|
|
||||||
this.draw.moveTo(p.x, p.y);
|
|
||||||
} else {
|
|
||||||
this.draw.lineTo(p.x, p.y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.draw.close();
|
|
||||||
this.draw.fill();
|
|
||||||
}
|
|
||||||
}
|
|
92
cc-inspector/src/scripts/inject/hint/adapter.ts
Normal file
92
cc-inspector/src/scripts/inject/hint/adapter.ts
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
declare const cc: any;
|
||||||
|
export interface DrawOptions {
|
||||||
|
fill: boolean;
|
||||||
|
fillColor: string;
|
||||||
|
stroke: boolean;
|
||||||
|
strokeColor: string;
|
||||||
|
}
|
||||||
|
export class Point {
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
constructor(x: number, y: number) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export class RectPoints {
|
||||||
|
points: Point[] = [];
|
||||||
|
get len() {
|
||||||
|
return this.points.length;
|
||||||
|
}
|
||||||
|
add(point: Point) {
|
||||||
|
this.points.push(point);
|
||||||
|
}
|
||||||
|
at(index: number) {
|
||||||
|
return this.points[index];
|
||||||
|
}
|
||||||
|
test(width: number, height: number) {
|
||||||
|
this.points.push(new Point(0, 0));
|
||||||
|
this.points.push(new Point(width, 0));
|
||||||
|
this.points.push(new Point(width, height));
|
||||||
|
this.points.push(new Point(0, height));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export class HintAdapter {
|
||||||
|
protected draw = null;
|
||||||
|
constructor() {}
|
||||||
|
resetIndex() {
|
||||||
|
throw new Error("not implemented");
|
||||||
|
}
|
||||||
|
getRectPoints(node: any): RectPoints | null {
|
||||||
|
throw new Error("not implemented");
|
||||||
|
}
|
||||||
|
clear() {
|
||||||
|
if (this.draw) {
|
||||||
|
this.draw.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
initDrawNode() {
|
||||||
|
if (this.draw && !this.draw.isValid) {
|
||||||
|
this.draw = null;
|
||||||
|
}
|
||||||
|
if (this.draw) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const scene = cc.director.getScene();
|
||||||
|
if (!scene) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let node = new cc.Node("draw-node");
|
||||||
|
const canvas = cc.find("Canvas");
|
||||||
|
this.addDraw(scene, canvas, node);
|
||||||
|
this.draw = node.addComponent(cc.Graphics);
|
||||||
|
}
|
||||||
|
public isDrawValid() {
|
||||||
|
return this.draw && this.draw.isValid;
|
||||||
|
}
|
||||||
|
protected addDraw(scene: any, canvas: any, node: any) {
|
||||||
|
throw new Error("not implemented");
|
||||||
|
}
|
||||||
|
public drawRect(points: RectPoints, opts: DrawOptions) {
|
||||||
|
this.draw.lineWidth = 2;
|
||||||
|
for (let i = 0; i < points.len; i++) {
|
||||||
|
const p = points.at(i);
|
||||||
|
if (i === 0) {
|
||||||
|
this.draw.moveTo(p.x, p.y);
|
||||||
|
} else {
|
||||||
|
this.draw.lineTo(p.x, p.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (points.len) {
|
||||||
|
this.draw.close();
|
||||||
|
}
|
||||||
|
if (opts.stroke) {
|
||||||
|
this.draw.strokeColor = new cc.Color().fromHEX(opts.strokeColor);
|
||||||
|
this.draw.stroke();
|
||||||
|
}
|
||||||
|
if (opts.fill) {
|
||||||
|
this.draw.fillColor = new cc.Color().fromHEX(opts.fillColor);
|
||||||
|
this.draw.fill();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
99
cc-inspector/src/scripts/inject/hint/hint-v2.ts
Normal file
99
cc-inspector/src/scripts/inject/hint/hint-v2.ts
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
import { HintAdapter, Point, RectPoints } from "./adapter";
|
||||||
|
declare const cc: any;
|
||||||
|
|
||||||
|
export class HintV2 extends HintAdapter {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
protected addDraw(scene: any, canvas: any, node: any): void {
|
||||||
|
scene.addChild(node);
|
||||||
|
}
|
||||||
|
private canvasBoundingRect = {
|
||||||
|
left: 0,
|
||||||
|
top: 0,
|
||||||
|
width: 0,
|
||||||
|
height: 0,
|
||||||
|
};
|
||||||
|
private _updateCanvasBoundingRect() {
|
||||||
|
// @ts-ignore
|
||||||
|
const element: any = cc.game.canvas;
|
||||||
|
var docElem = document.documentElement;
|
||||||
|
var leftOffset = window.pageXOffset - docElem.clientLeft;
|
||||||
|
var topOffset = window.pageYOffset - docElem.clientTop;
|
||||||
|
if (element.getBoundingClientRect) {
|
||||||
|
var box = element.getBoundingClientRect();
|
||||||
|
this.canvasBoundingRect.left = box.left + leftOffset;
|
||||||
|
this.canvasBoundingRect.top = box.top + topOffset;
|
||||||
|
this.canvasBoundingRect.width = box.width;
|
||||||
|
this.canvasBoundingRect.height = box.height;
|
||||||
|
} else if (element instanceof HTMLCanvasElement) {
|
||||||
|
this.canvasBoundingRect.left = leftOffset;
|
||||||
|
this.canvasBoundingRect.top = topOffset;
|
||||||
|
this.canvasBoundingRect.width = element.width;
|
||||||
|
this.canvasBoundingRect.height = element.height;
|
||||||
|
} else {
|
||||||
|
this.canvasBoundingRect.left = leftOffset;
|
||||||
|
this.canvasBoundingRect.top = topOffset;
|
||||||
|
this.canvasBoundingRect.width = parseInt(element.style.width);
|
||||||
|
this.canvasBoundingRect.height = parseInt(element.style.height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getPointByEvent(event: MouseEvent) {
|
||||||
|
this._updateCanvasBoundingRect();
|
||||||
|
if (event.pageX != null)
|
||||||
|
//not avalable in <= IE8
|
||||||
|
return { x: event.pageX, y: event.pageY };
|
||||||
|
|
||||||
|
this.canvasBoundingRect.left -= document.body.scrollLeft;
|
||||||
|
this.canvasBoundingRect.top -= document.body.scrollTop;
|
||||||
|
|
||||||
|
return { x: event.clientX, y: event.clientY };
|
||||||
|
}
|
||||||
|
private hit(event: MouseEvent) {
|
||||||
|
let location = this.getPointByEvent(event);
|
||||||
|
// @ts-ignore
|
||||||
|
cc.view._convertMouseToLocationInView(location, this.canvasBoundingRect);
|
||||||
|
}
|
||||||
|
resetIndex(): void {
|
||||||
|
const node = this.draw.node;
|
||||||
|
node.zIndex = node.parent.children.length;
|
||||||
|
}
|
||||||
|
getRectPoints(node: any): RectPoints | null {
|
||||||
|
const points: RectPoints = new RectPoints();
|
||||||
|
const { anchorX, anchorY, width, height } = node;
|
||||||
|
const x = -anchorX * width;
|
||||||
|
const y = -anchorY * height;
|
||||||
|
const matrixm = node._worldMatrix.m;
|
||||||
|
const m00 = matrixm[0],
|
||||||
|
m01 = matrixm[1],
|
||||||
|
m04 = matrixm[4],
|
||||||
|
m05 = matrixm[5],
|
||||||
|
m12_tx = matrixm[12],
|
||||||
|
m13_ty = matrixm[13];
|
||||||
|
[
|
||||||
|
new Point(x, y), //
|
||||||
|
new Point(x + width, y),
|
||||||
|
new Point(x + width, y + height),
|
||||||
|
new Point(x, y + height),
|
||||||
|
].forEach(({ x, y }: Point) => {
|
||||||
|
const worldX = x * m00 + y * m04 + m12_tx; // x
|
||||||
|
const worldY = x * m01 + y * m05 + m13_ty; // y
|
||||||
|
const pos = this.draw.node.convertToNodeSpaceAR(cc.v2(worldX, worldY));
|
||||||
|
points.add(new Point(pos.x, pos.y));
|
||||||
|
});
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
private getBox(node: any) {
|
||||||
|
if (node.getBoundingBoxToWorld) {
|
||||||
|
return node.getBoundingBoxToWorld();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cc.UITransformComponent) {
|
||||||
|
const tr = node.getComponent(cc.UITransformComponent);
|
||||||
|
if (tr && tr.getBoundingBoxToWorld) {
|
||||||
|
return tr.getBoundingBoxToWorld();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
98
cc-inspector/src/scripts/inject/hint/hint-v3.ts
Normal file
98
cc-inspector/src/scripts/inject/hint/hint-v3.ts
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
import { HintAdapter, Point, RectPoints } from "./adapter";
|
||||||
|
declare const cc: any;
|
||||||
|
|
||||||
|
export class HintV3 extends HintAdapter {
|
||||||
|
resetIndex(): void {
|
||||||
|
const node = this.draw.node;
|
||||||
|
const len = node.parent.children.length;
|
||||||
|
node.setSiblingIndex(len);
|
||||||
|
}
|
||||||
|
protected addDraw(scene: any, canvas: any, node: any): void {
|
||||||
|
if (canvas) {
|
||||||
|
// 3.x 需要放到canvas下边
|
||||||
|
if (canvas.layer) {
|
||||||
|
node.layer = canvas.layer;
|
||||||
|
}
|
||||||
|
canvas.addChild(node);
|
||||||
|
} else {
|
||||||
|
scene.addChild(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getRectPoints(node: any): RectPoints | null {
|
||||||
|
if (!node.worldPosition) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const transform = cc.UITransformComponent || cc.UITransform;
|
||||||
|
if (!transform) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const tr = node.getComponent(transform);
|
||||||
|
if (!tr) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const { anchorPoint, width, height } = tr;
|
||||||
|
const points: RectPoints = new RectPoints();
|
||||||
|
const x = -anchorPoint.x * width;
|
||||||
|
const y = -anchorPoint.y * height;
|
||||||
|
const m = node.worldMatrix;
|
||||||
|
|
||||||
|
[
|
||||||
|
new Point(x, y), //
|
||||||
|
new Point(x + width, y),
|
||||||
|
new Point(x + width, y + height),
|
||||||
|
new Point(x, y + height),
|
||||||
|
].forEach(({ x, y }: Point) => {
|
||||||
|
let rhw = m.m03 * x + m.m07 * y + m.m15;
|
||||||
|
rhw = rhw ? 1 / rhw : 1;
|
||||||
|
let worldX = (m.m00 * x + m.m04 * y + m.m12) * rhw;
|
||||||
|
let worldY = (m.m01 * x + m.m05 * y + m.m13) * rhw;
|
||||||
|
let worldZ = (m.m02 * x + m.m06 * y + m.m14) * rhw;
|
||||||
|
const pos = this.draw.getComponent(transform).convertToNodeSpaceAR(cc.v3(worldX, worldY, worldZ));
|
||||||
|
points.add(new Point(pos.x, pos.y));
|
||||||
|
});
|
||||||
|
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 尝试实现wireframe模式
|
||||||
|
*/
|
||||||
|
private getTrangles(node: any) {
|
||||||
|
const comps = node._components;
|
||||||
|
if (comps && Array.isArray(comps)) {
|
||||||
|
const m = node.worldMatrix;
|
||||||
|
comps.forEach((comp) => {
|
||||||
|
const { renderData } = comp;
|
||||||
|
if (!renderData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { data, _vc: VertexCount, _ic: IndexCount, chunk } = renderData;
|
||||||
|
if (!data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取indexBuffer的索引顺序
|
||||||
|
const ib = chunk.meshBuffer.iData;
|
||||||
|
let indexOffset = chunk.meshBuffer.indexOffset;
|
||||||
|
const vidOrigin = chunk.vertexOffset;
|
||||||
|
const arr = [];
|
||||||
|
for (let i = 0; i < IndexCount; i++) {
|
||||||
|
const index = ib[indexOffset + i] - vidOrigin;
|
||||||
|
arr.push(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let j = 0; j < data.length; j++) {
|
||||||
|
const item = data[j];
|
||||||
|
const { x, y, z, u, v, color } = item;
|
||||||
|
let rhw = m.m03 * x + m.m07 * y + m.m15;
|
||||||
|
rhw = rhw ? 1 / rhw : 1;
|
||||||
|
|
||||||
|
let worldX = (m.m00 * x + m.m04 * y + m.m12) * rhw;
|
||||||
|
let worldY = (m.m01 * x + m.m05 * y + m.m13) * rhw;
|
||||||
|
let worldZ = (m.m02 * x + m.m06 * y + m.m14) * rhw;
|
||||||
|
// const pos = this.draw.getComponent(transform).convertToNodeSpaceAR(cc.v3(worldX, worldY, worldZ));
|
||||||
|
// points.points.push(new Point(pos.x, pos.y));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
189
cc-inspector/src/scripts/inject/hint/index.ts
Normal file
189
cc-inspector/src/scripts/inject/hint/index.ts
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
import ccui from "@xuyanfeng/cc-ui";
|
||||||
|
import { IUiMenuItem } from "@xuyanfeng/cc-ui/types/cc-menu/const";
|
||||||
|
import { DocumentEvent } from "../../const";
|
||||||
|
import { Inspector } from "../inspector";
|
||||||
|
import { Msg } from "../../../core/types";
|
||||||
|
import { DrawOptions, HintAdapter, RectPoints } from "./adapter";
|
||||||
|
import { HintV2 } from "./hint-v2";
|
||||||
|
import { HintV3 } from "./hint-v3";
|
||||||
|
declare const cc: any;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 只负责管理hint的流程
|
||||||
|
*/
|
||||||
|
export class Hint {
|
||||||
|
private engineVersion: string = "";
|
||||||
|
private hintAdapter: HintAdapter = null;
|
||||||
|
public setEngineVersion(version: string) {
|
||||||
|
this.engineVersion = version;
|
||||||
|
if (version.startsWith("2.")) {
|
||||||
|
this.hintAdapter = new HintV2();
|
||||||
|
} else if (version.startsWith("3.")) {
|
||||||
|
this.hintAdapter = new HintV3();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private inspector: Inspector = null;
|
||||||
|
constructor(inspector: Inspector) {
|
||||||
|
this.inspector = inspector;
|
||||||
|
document.addEventListener(DocumentEvent.GameInspectorBegan, (event: CustomEvent) => {
|
||||||
|
const el = this.getTargetElement();
|
||||||
|
if (!el) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const cursor = el.style.cursor;
|
||||||
|
el.style.cursor = "zoom-in";
|
||||||
|
const test = (event: MouseEvent) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
event.preventDefault();
|
||||||
|
el.removeEventListener("mousedown", test, true);
|
||||||
|
el.style.cursor = cursor;
|
||||||
|
const e = new CustomEvent(DocumentEvent.GameInspectorEnd);
|
||||||
|
document.dispatchEvent(e);
|
||||||
|
this.updateHint(event, el);
|
||||||
|
};
|
||||||
|
el.addEventListener("mousedown", test, true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateHint(event: MouseEvent, canvas: HTMLCanvasElement) {
|
||||||
|
this.cleanHover();
|
||||||
|
this.cleanSelected();
|
||||||
|
const rect = canvas.getBoundingClientRect();
|
||||||
|
let x = event.clientX - rect.x;
|
||||||
|
let y = rect.y + rect.height - event.clientY;
|
||||||
|
x *= window.devicePixelRatio;
|
||||||
|
y *= window.devicePixelRatio;
|
||||||
|
|
||||||
|
this.inspector.updateTreeInfo(false);
|
||||||
|
const nodes = [];
|
||||||
|
this.inspector.forEachNode((item) => {
|
||||||
|
let b = false;
|
||||||
|
if (this.inspector.isCreatorV3) {
|
||||||
|
b = item._uiProps?.uiTransformComp?.hitTest({ x, y }, 0);
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
if (b && item.active && item.activeInHierarchy) {
|
||||||
|
nodes.push(item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (nodes.length === 1) {
|
||||||
|
const item = nodes[0];
|
||||||
|
this.setSelected(item);
|
||||||
|
this.sendInspectNodeMsg(item);
|
||||||
|
} else {
|
||||||
|
nodes.reverse();
|
||||||
|
const menu = nodes.map((item) => {
|
||||||
|
const path = this.getPath(item);
|
||||||
|
return {
|
||||||
|
name: path,
|
||||||
|
callback: () => {
|
||||||
|
this.cleanHover();
|
||||||
|
this.setSelected(item);
|
||||||
|
this.sendInspectNodeMsg(item);
|
||||||
|
},
|
||||||
|
enter: () => {
|
||||||
|
this.setHover(item);
|
||||||
|
},
|
||||||
|
leave: () => {
|
||||||
|
this.cleanHover();
|
||||||
|
},
|
||||||
|
} as IUiMenuItem;
|
||||||
|
});
|
||||||
|
ccui.menu.showMenuByMouseEvent(event, menu, 0.8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private sendInspectNodeMsg(node: any) {
|
||||||
|
if (node.uuid) {
|
||||||
|
this.inspector.sendMsgToContent(Msg.InspectNode, node.uuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private getPath(node: any) {
|
||||||
|
let path = [];
|
||||||
|
let parent = node;
|
||||||
|
while (parent) {
|
||||||
|
path.push(parent.name);
|
||||||
|
parent = parent.parent;
|
||||||
|
}
|
||||||
|
path = path.reverse();
|
||||||
|
return path.join("/");
|
||||||
|
}
|
||||||
|
private getTargetElement(): HTMLCanvasElement | null {
|
||||||
|
// @ts-ignore
|
||||||
|
if (typeof cc !== "undefined" && cc.game && cc.game.canvas) {
|
||||||
|
// @ts-ignore
|
||||||
|
return cc.game.canvas;
|
||||||
|
} else {
|
||||||
|
null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public cleanHover() {
|
||||||
|
this.hoverNodes = [];
|
||||||
|
this.hintAdapter.clear();
|
||||||
|
}
|
||||||
|
public cleanSelected() {
|
||||||
|
this.selectedNodes = [];
|
||||||
|
this.hintAdapter.clear();
|
||||||
|
}
|
||||||
|
private hoverNodes = [];
|
||||||
|
private selectedNodes = [];
|
||||||
|
|
||||||
|
public update() {
|
||||||
|
this.hintAdapter.initDrawNode();
|
||||||
|
if (!this.hintAdapter.isDrawValid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.hintAdapter.clear();
|
||||||
|
this.hintAdapter.resetIndex();
|
||||||
|
// this.testRect();
|
||||||
|
this.hoverNodes.forEach((node) => {
|
||||||
|
if (node.isValid) {
|
||||||
|
this.hintNode(node, {
|
||||||
|
fill: true,
|
||||||
|
fillColor: "#00ff0055",
|
||||||
|
stroke: true,
|
||||||
|
strokeColor: "#ffffff44",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.selectedNodes.forEach((node) => {
|
||||||
|
if (node.isValid) {
|
||||||
|
this.hintNode(node, {
|
||||||
|
fill: false,
|
||||||
|
fillColor: "#ff0000",
|
||||||
|
stroke: true,
|
||||||
|
strokeColor: "#ff0000",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
private testRect() {
|
||||||
|
const points = new RectPoints();
|
||||||
|
points.test(100, 100);
|
||||||
|
this.hintAdapter.drawRect(points, {
|
||||||
|
fill: true,
|
||||||
|
fillColor: "#00ff0099",
|
||||||
|
stroke: true,
|
||||||
|
strokeColor: "#ff000099",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public setHover(node: any) {
|
||||||
|
if (node.isValid) {
|
||||||
|
this.hoverNodes = [node];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public setSelected(node: any) {
|
||||||
|
if (node.isValid) {
|
||||||
|
this.selectedNodes = [node];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private hintNode(node: any, opts: DrawOptions) {
|
||||||
|
const points = this.hintAdapter.getRectPoints(node);
|
||||||
|
if (!points) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.hintAdapter.drawRect(points, opts);
|
||||||
|
}
|
||||||
|
}
|
@ -110,7 +110,7 @@ export class Inspector extends InjectEvent {
|
|||||||
const uuid: string = pluginEvent.data;
|
const uuid: string = pluginEvent.data;
|
||||||
if (uuid) {
|
if (uuid) {
|
||||||
const node = this.inspectorGameMemoryStorage[uuid];
|
const node = this.inspectorGameMemoryStorage[uuid];
|
||||||
if (node.isValid) {
|
if (node && node.isValid) {
|
||||||
this.hint.setHover(node);
|
this.hint.setHover(node);
|
||||||
} else {
|
} else {
|
||||||
this.hint.cleanHover();
|
this.hint.cleanHover();
|
||||||
@ -124,7 +124,7 @@ export class Inspector extends InjectEvent {
|
|||||||
const uuid: string = pluginEvent.data;
|
const uuid: string = pluginEvent.data;
|
||||||
if (uuid) {
|
if (uuid) {
|
||||||
const node = this.inspectorGameMemoryStorage[uuid];
|
const node = this.inspectorGameMemoryStorage[uuid];
|
||||||
if (node.isValid) {
|
if (node && node.isValid) {
|
||||||
this.hint.setSelected(node);
|
this.hint.setSelected(node);
|
||||||
} else {
|
} else {
|
||||||
this.hint.cleanSelected();
|
this.hint.cleanSelected();
|
||||||
@ -159,7 +159,7 @@ export class Inspector extends InjectEvent {
|
|||||||
this.hint.update();
|
this.hint.update();
|
||||||
});
|
});
|
||||||
const version = this.getEngineVersion();
|
const version = this.getEngineVersion();
|
||||||
this.hint.engineVersion = version;
|
this.hint.setEngineVersion(version);
|
||||||
if (b && version) {
|
if (b && version) {
|
||||||
this.uploadEngineVersion(version);
|
this.uploadEngineVersion(version);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user