vtkBorderWidget:实现一个跟随鼠标移动的方框

#include <vtkActor.h>
#include <vtkBorderRepresentation.h>
#include <vtkBorderWidget.h>
#include <vtkCommand.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkObjectFactory.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSphereSource.h>
#include <vtkWidgetCallbackMapper.h>
#include <vtkWidgetEvent.h>


class vtkCustomBorderWidget : public vtkBorderWidget
{
public:
	static vtkCustomBorderWidget* New();
	vtkTypeMacro(vtkCustomBorderWidget, vtkBorderWidget);

	static void MoveAction(vtkAbstractWidget* w);
	static void EndSelectAction(vtkAbstractWidget* w);

	vtkCustomBorderWidget();
};


class vtkDisappearBorderCallback : public vtkCommand
{
public:
	static	vtkDisappearBorderCallback* New()
	{
		return new vtkDisappearBorderCallback;
	}

	vtkSmartPointer<vtkRenderer> m_renderer;
	vtkSmartPointer<vtkBorderWidget> m_widget;

	void SetRender(vtkSmartPointer<vtkRenderer> renderer)
	{
		m_renderer = renderer;
	}

	void SetWidget(vtkSmartPointer<vtkCustomBorderWidget> widget)
	{
		m_widget = static_cast<vtkBorderWidget*>(widget);
	}

	virtual void Execute(vtkObject* caller, unsigned long, void*)
	{
		std::cout << "Do Not show border! \n";

		this->m_widget->GetBorderRepresentation()->SetShowBorderToOff();
		//this->m_widget->GetBorderRepresentation()->SetVisibility(0);
		//this->m_widget->SetEnabled(0);
	}
	vtkDisappearBorderCallback() { }
};

class vtkShowBorderCallback : public vtkCommand
{
public:
	static	vtkShowBorderCallback* New()
	{
		return new vtkShowBorderCallback;
	}

	vtkSmartPointer<vtkRenderer> m_renderer;
	vtkSmartPointer<vtkBorderWidget> m_widget;

	void SetRender(vtkSmartPointer<vtkRenderer> renderer)
	{
		m_renderer = renderer;
	}

	void SetWidget(vtkSmartPointer<vtkCustomBorderWidget> widget)
	{
		m_widget = static_cast<vtkBorderWidget*>(widget);
	}

	virtual void Execute(vtkObject* caller, unsigned long, void*)
	{
		//this->m_widget->CreateDefaultRepresentation();
		//this->m_widget->SelectableOff();
		//this->m_widget->SetResizable(0);
		//this->m_widget->GetBorderRepresentation()->ProportionalResizeOn();
		//this->m_widget->GetBorderRepresentation()->SetBorderColor(1.0, 0.0, 0.0);
		//this->m_widget->EnabledOn();
		//this->m_widget->GetBorderRepresentation()->SetShowBorderToOn();

		//this->m_widget->GetRepresentation()->VisibilityOn();
		double pos[3];
		pos[0] = this->m_renderer->GetRenderWindow()->GetInteractor()->GetEventPosition()[0];
		pos[1] = this->m_renderer->GetRenderWindow()->GetInteractor()->GetEventPosition()[1];
		pos[2] = 0;

		double WorldPoint[3];
		this->m_renderer->SetDisplayPoint(pos);
		this->m_renderer->DisplayToView();

		WorldPoint[0] = (this->m_renderer->GetViewPoint())[0];
		WorldPoint[1] = (this->m_renderer->GetViewPoint())[1];
		WorldPoint[2] = (this->m_renderer->GetViewPoint())[2];

		//std::cout << "World Position:  " << WorldPoint[0] << "   " << WorldPoint[1] << "   " << WorldPoint[2] << "\n";
		this->m_widget->GetBorderRepresentation()->GetPositionCoordinate()->SetCoordinateSystemToView();
		this->m_widget->GetBorderRepresentation()->GetPosition2Coordinate()->SetCoordinateSystemToView();
		this->m_widget->GetBorderRepresentation()->SetPosition(WorldPoint[0] - 0.1, WorldPoint[1] - 0.1);
		this->m_widget->GetBorderRepresentation()->SetPosition2(WorldPoint[0] + 0.1, WorldPoint[1] + 0.1);
	}
	vtkShowBorderCallback() { }
};


vtkStandardNewMacro(vtkCustomBorderWidget);

// namespace

int main(int, char* [])
{
	vtkNew<vtkNamedColors> colors;

	// Sphere
	vtkNew<vtkSphereSource> sphereSource;
	sphereSource->SetRadius(4.0);
	sphereSource->Update();

	vtkNew<vtkPolyDataMapper> mapper;
	mapper->SetInputConnection(sphereSource->GetOutputPort());

	vtkNew<vtkActor> actor;
	actor->SetMapper(mapper);
	actor->GetProperty()->SetColor(
		colors->GetColor3d("DarkOliveGreen").GetData());

	// A renderer and render window
	vtkNew<vtkRenderer> renderer;
	vtkNew<vtkRenderWindow> renderWindow;
	renderWindow->AddRenderer(renderer);
	renderWindow->SetWindowName("BorderWidget");

	// An interactor
	vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
	renderWindowInteractor->SetRenderWindow(renderWindow);

	vtkNew<vtkCustomBorderWidget> borderWidget;
	borderWidget->SetInteractor(renderWindowInteractor);
	borderWidget->CreateDefaultRepresentation();
	//borderWidget->SelectableOff();
	//borderWidget->SetResizable(1);
	borderWidget->On();
	borderWidget->GetBorderRepresentation()->ProportionalResizeOn();
	borderWidget->GetBorderRepresentation()->SetBorderColor(1.0, 0.0, 0.0);
	borderWidget->GetBorderRepresentation()->SetShowBorderToOff();

	renderer->AddActor(actor);
	renderer->SetBackground(colors->GetColor3d("SteelBlue").GetData());

	vtkShowBorderCallback* show_border = vtkShowBorderCallback::New();
	show_border->SetRender(renderer);
	show_border->SetWidget(borderWidget);
	renderWindowInteractor->AddObserver(vtkCommand::LeftButtonPressEvent, show_border);

	vtkDisappearBorderCallback* disappear_border = vtkDisappearBorderCallback::New();
	disappear_border->SetRender(renderer);
	disappear_border->SetWidget(borderWidget);
	renderWindowInteractor->AddObserver(vtkCommand::RightButtonPressEvent, disappear_border);

	//borderWidget->On();

	renderWindowInteractor->Initialize();
	renderWindow->Render();
	renderWindowInteractor->Start();

	return EXIT_SUCCESS;
}


vtkCustomBorderWidget::vtkCustomBorderWidget()
{
	this->CallbackMapper->SetCallbackMethod(
		vtkCommand::LeftButtonReleaseEvent, vtkWidgetEvent::EndSelect, this,
		vtkCustomBorderWidget::EndSelectAction);

	this->CallbackMapper->SetCallbackMethod(
		vtkCommand::MouseMoveEvent, vtkWidgetEvent::Move, this,
		vtkCustomBorderWidget::MoveAction);
}

void vtkCustomBorderWidget::MoveAction(vtkAbstractWidget* w)
{
	vtkBorderWidget* borderWidget = dynamic_cast<vtkBorderWidget*>(w);
	borderWidget->GetBorderRepresentation()->SetShowBorderToOn();

	vtkBorderWidget::MoveAction(w);

	double pos[3];

	pos[0] = borderWidget->GetInteractor()->GetEventPosition()[0];
	pos[1] = borderWidget->GetInteractor()->GetEventPosition()[1];
	pos[2] = 0;

	double WorldPoint[3];
	borderWidget->GetRepresentation()->GetRenderer()->SetDisplayPoint(pos);
	borderWidget->GetRepresentation()->GetRenderer()->DisplayToView();

	WorldPoint[0] = (borderWidget->GetRepresentation()->GetRenderer()->GetViewPoint())[0];
	WorldPoint[1] = (borderWidget->GetRepresentation()->GetRenderer()->GetViewPoint())[1];
	WorldPoint[2] = (borderWidget->GetRepresentation()->GetRenderer()->GetViewPoint())[2];

	borderWidget->GetBorderRepresentation()->GetPositionCoordinate()->SetCoordinateSystemToView();
	borderWidget->GetBorderRepresentation()->GetPosition2Coordinate()->SetCoordinateSystemToView();
	borderWidget->GetBorderRepresentation()->SetPosition(WorldPoint[0] - 0.1, WorldPoint[1] - 0.1);
	borderWidget->GetBorderRepresentation()->SetPosition2(WorldPoint[0] + 0.1, WorldPoint[1] + 0.1);
}

void vtkCustomBorderWidget::EndSelectAction(vtkAbstractWidget* w)
{
	vtkBorderWidget* borderWidget = dynamic_cast<vtkBorderWidget*>(w);

	vtkBorderWidget::EndSelectAction(w);

	borderWidget->GetBorderRepresentation()->SetShowBorderToOff();
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您可以使用CSS中的:hover伪类和transform属性来实现这个效果。具体步骤如下: 1. 首先,在CSS中,给图片添加一个:hover伪类来设置鼠标悬停时的样式。 ```css img:hover { transform: scale(1.2); } ``` 2. 接着,在:hover伪类中添加transform属性,设置scale值来放大图片。这里的scale值可以根据实际情况自行调整。 ```css img:hover { transform: scale(1.2); } ``` 3. 最后,在:hover伪类中添加一个伪元素,使用绝对定位(position:absolute)来创建一个跟随鼠标移动方框,使用transform属性来调整方框的位置。 ```css img:hover::after { content: ""; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 100px; height: 100px; border: 2px solid #000; box-sizing: border-box; pointer-events: none; /* 使鼠标事件能够穿透伪元素到达图片元素 */ } ``` 这里使用::after伪元素来创建方框,使用translate()函数和top、left属性来将方框居中在鼠标位置,使用width、height、border、box-sizing属性来设置方框的大小和边框样式,使用pointer-events属性来使鼠标事件能够穿透伪元素到达图片元素。 完整的代码示例如下: ```css img:hover { transform: scale(1.2); } img:hover::after { content: ""; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 100px; height: 100px; border: 2px solid #000; box-sizing: border-box; pointer-events: none; } ``` 希望这个解答能够帮到您!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值