d3.js 如何使用PIXI.Graphics在PIXI.js中绘制可点击的线条?

pxq42qpu  于 2023-10-19  发布在  其他
关注(0)|答案(3)|浏览(284)

我得到了以下代码:

const linksGraphics = new PIXI.Graphics();

const update = () => {
linksGraphics.clear();
linksGraphics.alpha = 1;
if (forceLinkActive) { 
  data.links.forEach(link => {
    let { source, target } = link;
    linksGraphics.lineStyle(2, 0x000000);
    linksGraphics.moveTo(source.x, source.y);
    linksGraphics.lineTo(target.x, target.y);
  });
  linksGraphics.endFill();
}  }

app.ticker.add( () => update() );

其中data.links是一个edge数据数组{source:数量,目标:number}。如果我理解正确的话,所有行都是PIXI.Graphics对象的一部分。但我需要的是:
1.每一行都应该有自己的不透明度
1.每一行都应该有一个鼠标经过的事件
如何修改我的代码?
谢谢.

2vuwiymt

2vuwiymt1#

已经有一段时间了,但我可以给你一个建议。行不会对pixijs中的鼠标/指针事件做出React。
相反,你可能想用alpha值0伴随一个转换的矩形,并用这个矩形监听鼠标/指针。
例如,当鼠标/指针悬停在相应的矩形上时,可以更改线条的alpha值。

const app = new PIXI.Application({
    width: window.innerWidth,
    height: window.innerHeight,
    backgroundColor: 0x283230
});
document.body.appendChild(app.view);

// 1. PRELIMINARY COMPUTATIONS
// Coordinates of the end points of a line
let x0 = 100;
let y0 = 100;
let x1 = 200;
let y1 = 200;
// Find midpoint for translation
let xmid = 0.5*(x0+x1);
let ymid = 0.5*(y0+y1);
// Length of the line
let length = Math.hypot(x0-x1, y0-y1);
// Alignment angle of the line, i.e. angle with the x axis
let angle = Math.atan((y1-y0)/(x1-x0));

// 2. LINE 
line = new PIXI.Graphics();
// Arbitrary line style, say we have a non-white background
line.lineStyle(8,0xffffff,1);
line.moveTo(x0,y0);
line.lineTo(x1,y1);

// 3. ACCOMPANYING RECTANGLE
line.rectangle = new PIXI.Graphics();
line.rectangle.beginFill(0xffffff);
// Since we are going to translate, think of 0,0 is the center point on the rectangle
// Width of the rectangle is selected arbitrarily as 30
const width = 30;
line.rectangle.drawRect(-length/2,-width/2,length,width);
line.rectangle.endFill();
line.rectangle.alpha = 0;
line.rectangle.interactive = true;
line.rectangle.on("pointerover", reactOver);
line.rectangle.on("pointerout", reactOut);
// Apply transformation
line.rectangle.setTransform(xmid, ymid,1,1,angle);

app.stage.addChild(line);
// Add rectangle to the stage too.
app.stage.addChild(line.rectangle);

// Let's change alpha value of the line when user hovers.
function reactOver(){
   line.alpha = 0.5;
}
function reactOut(){
   line.alpha = 1;
}

To the PEN, Hover a line in pixijs
例如,我们可以将此逻辑扩展到矩形。但是这次你需要两个伴随的矩形(alpha=0),其中一个比未填充的矩形宽,另一个比未填充的矩形窄。比如说,

const app = new PIXI.Application({
    width: window.innerWidth,
    height: window.innerHeight,
    backgroundColor: 0x283230
});
document.body.appendChild(app.view);
const x = 100;
const y = 100;
const width = 150;
const height = 100;
const hoverWidth = 20;

const rect = new PIXI.Graphics();
rect.lineStyle(4, 0xffffff,1);
rect.drawRect(x,y,width,height);
rect.outer = new PIXI.Graphics();
rect.inner = new PIXI.Graphics();
// Fill outer
rect.outer.alpha = 0;
rect.outer.beginFill(0xffffff);
rect.outer.drawRect(x-hoverWidth/2, y-hoverWidth/2, width+hoverWidth, height+hoverWidth);
rect.outer.endFill();
// Fill inner
rect.inner.alpha = 0;
rect.inner.beginFill(0xffffff);
rect.inner.drawRect(x+hoverWidth/2, y+hoverWidth/2, width-hoverWidth, height-hoverWidth);
rect.inner.endFill();
// Add interaction and listeners
rect.outer.interactive = true;
rect.inner.interactive = true;
rect.outer.on("pointerover", pOverOuter);
rect.outer.on("pointerout", pOutOuter);
rect.inner.interaction = true;
rect.inner.on("pointerover", pOverInner);
rect.inner.on("pointerout", pOutInner);
app.stage.addChild(rect);
app.stage.addChild(rect.outer);
app.stage.addChild(rect.inner);

// Listeners
let overOuter = false;
let overInner = false;
function pOverOuter(){
  overOuter = true;
  changeAlpha();
  // rect.alpha = 0.5;
}

function pOutOuter(){
  overOuter = false;
  changeAlpha();
}

function pOverInner(){
  overInner = true;
  changeAlpha();
  // rect.alpha = 1;
}

function pOutInner(){
  overInner = false;
  changeAlpha();
  // rect.alpha = 0.5;
}

function changeAlpha(){
  rect.alpha = (overOuter && !overInner)? 0.5: 1;
}

To the PEN, Hover a rectangle in pixijs

l7wslrjt

l7wslrjt2#

您可以在图形上定义hitArea。使用getBounds()可以使一行可单击。完成此操作后,您还可以将pointerEvents分配给图形。

const linksGraphics = new PIXI.Graphics();

const update = () => {
  linksGraphics.clear();
  linksGraphics.alpha = 1;

  if (forceLinkActive) { 
    data.links.forEach(link => {
       let { source, target } = link;
       linksGraphics.lineStyle(2, 0x000000);
       linksGraphics.moveTo(source.x, source.y);
       linksGraphics.lineTo(target.x, target.y);

       //A line itself is not clickable
       linksGraphics.hitArea = linksGraphics.getBounds();
    });
    linksGraphics.endFill();
  }  
}

app.ticker.add( () => update() );
kwvwclae

kwvwclae3#

对于第一个要求,尝试为绘制每一条线创建单独的图形对象,并为每条线设置alpha。对于您的第二个要求,您需要将图形(linksGraphics)对象的交互式属性设置为true,如下所示,

linksGraphics.interactive = true;

然后像下面这样附加一个要在mouseover事件上执行的函数,

var mouseOverAction = function () {
       //Some code
};
linksGraphics.on('mouseover', mouseOverAction);

相关问题