【问题标题】:How to draw clickable line in PIXI.js using PIXI.Graphics?如何使用 PIXI.Graphics 在 PIXI.js 中绘制可点击线?
【发布时间】:2022-03-08 20:14:26
【问题描述】:

我有以下代码:

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 是边缘数据数组 {source: number, target: number}。如果我理解正确,所有线条都是 PIXI.Graphics 对象的一部分。但我需要的是:

  1. 每一行都应该有自己的不透明度
  2. 每一行都应该有一个鼠标悬停事件

任何想法如何修改我的代码?

谢谢。

【问题讨论】:

标签: javascript d3.js pixi.js


【解决方案1】:

已经有一段时间了,但可以提出建议。线条不会对 pixjs 中的鼠标/指针事件做出反应。

相反,您可能希望伴随一个 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

【讨论】:

    【解决方案2】:

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

    linksGraphics.interactive = true;
    

    然后附加一个要在鼠标悬停事件上执行的函数,如下所示,

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

    【讨论】:

    • 鼠标操作不适用于我只对行。此示例适用于矩形和圆形,也可能适用于其他对象。
    猜你喜欢
    • 2015-02-25
    • 2016-03-06
    • 1970-01-01
    • 2016-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-01
    相关资源
    最近更新 更多