Skip to content

JEasings

Video Lecture

Using JEasings Using JEasings

Description

JEasings is a JavaScript Easing engine that can be used for animating.

It allows you to transition values of an objects properties to new values over a time duration.

You can set,

  • The time duration,
  • The new values to ease to,
  • An optional delay to start,
  • An optional script to run on each update,
  • An optional script to run when completed,
  • An optional easing curve function to change the speed of the transition as it propgresses through the duration,
  • Start the JEasing as soon as it is created, or put it into a variable for later use,
  • Chain multiple JEasings together to run in sequence or in a continuous loop.

JEasings provides a more advanced way of controlling animations verses using lerp.

<>

Install JEasings

npm install jeasings --save-dev

JEasings includes type declarations.

To import use,

import JEASINGS from 'jeasings'

Lesson Script

./src/main.ts

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import './style.css'
import * as THREE from 'three'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'
import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'
import Stats from 'three/addons/libs/stats.module.js'
import JEASINGS from 'jeasings'

const scene = new THREE.Scene()

const gridHelper = new THREE.GridHelper()
gridHelper.position.y = -1
scene.add(gridHelper)

await new RGBELoader().loadAsync('img/venice_sunset_1k.hdr').then((texture) => {
  texture.mapping = THREE.EquirectangularReflectionMapping
  scene.environment = texture
})

const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 100)
camera.position.set(0, 1, 4)

const renderer = new THREE.WebGLRenderer({ antialias: true })
renderer.toneMapping = THREE.ACESFilmicToneMapping
renderer.toneMappingExposure = 0.8
renderer.shadowMap.enabled = true
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)

window.addEventListener('resize', () => {
  camera.aspect = window.innerWidth / window.innerHeight
  camera.updateProjectionMatrix()
  renderer.setSize(window.innerWidth, window.innerHeight)
  //render() //this line is unnecessary if you are re-rendering within the animation loop
})

const controls = new OrbitControls(camera, renderer.domElement)
controls.enableDamping = true
//controls.addEventListener('change', render) //this line is unnecessary if you are re-rendering within the animation loop

let suzanne: THREE.Mesh, plane: THREE.Mesh

new GLTFLoader().load('models/suzanne_scene.glb', (gltf) => {
  suzanne = gltf.scene.getObjectByName('Suzanne') as THREE.Mesh
  suzanne.castShadow = true
  ;((suzanne.material as THREE.MeshStandardMaterial).map as THREE.Texture).colorSpace = THREE.LinearSRGBColorSpace

  plane = gltf.scene.getObjectByName('Plane') as THREE.Mesh
  plane.scale.set(50, 1, 50)
  ;(plane.material as THREE.MeshStandardMaterial).envMap = scene.environment // since three@163, we need to set `envMap` before changing `envMapIntensity` has any effect.
  ;(plane.material as THREE.MeshStandardMaterial).envMapIntensity = 0.05
  plane.receiveShadow = true

  const spotLight = gltf.scene.getObjectByName('Spot') as THREE.SpotLight
  spotLight.intensity /= 500
  spotLight.castShadow = true
  spotLight.target = suzanne

  scene.add(gltf.scene)

  //render()
})

const raycaster = new THREE.Raycaster()
const mouse = new THREE.Vector2()

renderer.domElement.addEventListener('dblclick', (e) => {
  mouse.set((e.clientX / renderer.domElement.clientWidth) * 2 - 1, -(e.clientY / renderer.domElement.clientHeight) * 2 + 1)

  raycaster.setFromCamera(mouse, camera)

  const intersects = raycaster.intersectObjects([suzanne, plane], false)

  if (intersects.length) {
    const p = intersects[0].point

    //controls.target.set(p.x, p.y, p.z)

    // // JEasing the controls.target
    // new JEASINGS.JEasing(controls.target)
    //   .to(
    //     {
    //       x: p.x,
    //       y: p.y,
    //       z: p.z
    //     },
    //     500
    //   )
    //   //.delay (1000)
    //   //.easing(JEASINGS.Cubic.Out)
    //   //.onUpdate(() => render())
    //   .start()

    // // slding x,z
    // new JEASINGS.JEasing(suzanne.position)
    //   .to(
    //     {
    //       x: p.x,
    //       z: p.z
    //     },
    //     500
    //   )
    //   .start()

    // // going up
    // new JEASINGS.JEasing(suzanne.position)
    //   .to(
    //     {
    //       y: p.y + 3
    //     },
    //     250
    //   )
    //   //.easing(JEASINGS.Cubic.Out)
    //   .start()
    // //.onComplete(() => {

    // // going down
    // new JEASINGS.JEasing(suzanne.position)
    //   .to(
    //     {
    //       y: p.y + 1
    //     },
    //     250
    //   )
    //   .delay(250)
    //   //.easing(JEASINGS.Cubic.In)
    //   .start()
    // //})
  }
})

const stats = new Stats()
document.body.appendChild(stats.dom)

function animate() {
  requestAnimationFrame(animate)

  controls.update()

  JEASINGS.update()

  render()

  stats.update()
}

function render() {
  renderer.render(scene, camera)
}

animate()

JEasing Curve Functions

JEASINGS._equation_._direction_

JEASINGS*equation*.*direction*

JEASINGS (GitHub)

JEasing Chain

JEasing OrbitControls

Comments