three.js创建光线_如何使用Three.js创建具有图像失真的运动悬停效果

three.js创建光线

three.js创建光线

Motion_feat

The reveal hover effect on images has become a very popular pattern in modern websites. It plays an important role in taking the user experience to a higher level. But usually these kind of animations remain too “flat”. Natural movements with a realistic feel are much more enjoyable for the user. In this tutorial we’re going to build some special interactive reveal effects for images when a link is hovered. The aim is to add fluid and interesting motion to the effects. We will be exploring three different types of animations. This dynamic experience consists of two parts:

在图像上显示悬停效果已成为现代网站中非常流行的模式。 它在将用户体验提升到更高水平方面起着重要作用。 但是通常这些动画仍然太“平坦”。 具有逼真的感觉的自然运动对于用户而言更加令人愉悦。 在本教程中,我们将在悬停链接时为图像构建一些特殊的交互式显示效果。 目的是为效果添加流畅而有趣的运动。 我们将探索三种不同类型的动画。 这种动态体验包括两个部分:

  1. Distortion Image Effect (main effect)

    失真图像效果(主要效果)

  2. RGB Displacement, Image Trail Effect, Image Stretch (additional effects)

    RGB位移,图像拖尾效果,图像拉伸(附加效果)

We assume that you are confident with JavaScript and have some basic understanding of Three.js and WebGL.

我们假设您对JavaScript充满信心,并且对Three.js和WebGL有一些基本的了解。

入门 (Getting started)

The markup for this effect will include a link element that contains an image (and some other elements that are not of importance for our effect):

此效果的标记将包括一个链接元素,其中包含一个图像(以及一些其他对我们的效果不重要的元素):

<a class="link" href="#">
	<!-- ... -->
	<img src="img/demo1/img1.jpg" alt="Some image" />
</a>

The EffectShell class will group common methods and properties of the three distinct effects we’ll be creating. As a result, each effect will extend EffectShell.

EffectShell类将对我们将要创建的三个不同效果的通用方法和属性进行分组。 结果,每个效果都会扩展EffectShell。

Three.js设置 (Three.js setup)

First of all, we need to create the Three.js scene.

首先,我们需要创建Three.js场景

class EffectShell {
 constructor(container = document.body, itemsWrapper = null) {
   this.container = container
   this.itemsWrapper = itemsWrapper
   if (!this.container || !this.itemsWrapper) return
   this.setup()
 }
 
 setup() {
   window.addEventListener('resize', this.onWindowResize.bind(this), false)
 
   // renderer
   this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true })
   this.renderer.setSize(this.viewport.width, this.viewport.height)
   this.renderer.setPixelRatio = window.devicePixelRatio
   this.container.appendChild(this.renderer.domElement)
 
   // scene
   this.scene = new THREE.Scene()
 
   // camera
   this.camera = new THREE.PerspectiveCamera(
     40,
     this.viewport.aspectRatio,
     0.1,
     100
   )
   this.camera.position.set(0, 0, 3)
 
   // animation loop
   this.renderer.setAnimationLoop(this.render.bind(this))
 }
 
 render() {
   // called every frame
   this.renderer.render(this.scene, this.camera)
 }
 
 get viewport() {
   let width = this.container.clientWidth
   let height = this.container.clientHeight
   let aspectRatio = width / height
   return {
     width,
     height,
     aspectRatio
   }
 }
 
 onWindowResize() {
   this.camera.aspect = this.viewport.aspectRatio
   this.camera.updateProjectionMatrix()
   this.renderer.setSize(this.viewport.width, this.viewport.height)
 }
}

获取项目并加载纹理 (Get items and load textures)

In our markup we have links with images inside. The next step is to get each link from the DOM and put them in an array.

在我们的标记中,我们具有内部图像的链接。 下一步是从DOM获取每个链接,并将它们放入数组中。

class EffectShell {
 ...
 get itemsElements() {
   // convert NodeList to Array
   const items = [...this.itemsWrapper.querySelectorAll('.link')]
 
   //create Array of items including element, image and index
   return items.map((item, index) => ({
     element: item,
     img: item.querySelector('img') || null,
     index: index
   }))
 }
}

Because we will use the images as a texture, we have to load the textures through Three.js’ TextureLoader. It’s an asynchronous operation so we shouldn’t initialize the effect without all textures being loaded. Otherwise our texture will be fully black. That’s why we use Promises here:

因为我们将图像

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值