Skip to content

Latest commit

 

History

History
219 lines (184 loc) · 9.78 KB

README.md

File metadata and controls

219 lines (184 loc) · 9.78 KB

kooljs

kooljs is a multithreaded animation tool for the web.

what can it do?

  • compute lerp animations on a worker thread
  • custom logic (lambdas) that run on the worker
  • timelines to orchestrate animations
  • MatrixLerps to animate multiple values at once
  • stores and accesses the values requied for animations efficiently on the worker using TypedArray and Map Datatypes
  • avoid prop drilling for values that are only used for animations by storing and updating them on the worker

LiveDemo v0.1.7

  • check out the LiveDemo
  • I will add adding additional Examples over time

Components

Animator

The animator serves as our Middleware to communicate with the worker:

  • its one task/worker thread per animator instance
  • creates the animated objects
  • creates the registry on the worker
  • update values
  • start/stop animations

Components that are updated in the render loop

Those are Components we iterate over for a certain amount of time in the render loop on the worker.

  • Lerp
    • uses a series of numbers to lerp through as the input of steps
    • use the render_callback to pass the computed values to a callback on the main thread
    • you can either call document.get in the callback directly to apply the styling using the animated value, or you can store the values (eg usecallback) to store and process them
  • MatrixLerp
    • The same as Lerp, but it requires a list of subarrays (Matrices) instead a list of numbers as the input of steps
    • MatrixLerp lets you animate multipe values, but they only require a single render_callback call to pass them to the mainthread at once
      • this can be handy if you dont want to create multiple animations for a single div and therefore prevents overhead
  • Timeline
    • Timeline act like a Lerp-Animation that does not fire a callback after a each animation-frame.
    • They can be used to trigger and control other timelines, lerps, matrixLerps, lambdas or constants on the worker.

Arguments

|L-Lerp|M-MatrixLerp|T-Timeline|

arg description default Components
render_callback a function that gets called on the mainthread after the render loop none L,M
duration the max amount of computations pro step 10 All
steps a list of values to lerp through undefined All
steps_max_length the max length of steps for this animation. steps.length L
loop if this animation will get reseted after a lifecycle false All
render_interval computations pro step = render_interval // duration 1 All
smoothstep the amount of smooth step/easing that is applied 1 L,M
delay the amount of steps to wait before starting the animation 0 All
animationTriggers a list of animationtrigger objects undefined All
callback a callback object that gets called on the worker undefined All

callback

should be a list of dicts with this structure

{
condition: true || string,
callback: string
}

the callback field should be a string that includes valid code like this:

`({id}=> console.log(id))`

Constants

Constants are either matrices or numbers that get stored on the worker. They are called Constants since they are not getting animated in the render loop.

However you can update them from both the mainthread (Animator.update_constant) and the worker (using lambdas or Lerp callbacks).

Constants serve as a way to update multiple animation values on the worker instead of calling animator.update() for every related animation from the mainthread, which requires to serialize the values.

But they can also get used as Middleware to update values on the mainthread.

  • when updating Constants, they can also trigger animations by using render_triggers, or call lambdas by using render_lamba_calls

Lambdas

Lambdas lets you use youre custom logic on the worker.

  • you can fire callbacks eventbased (eg onMouseOver) without having to start a animation and its callback function
  • you can also call them using the callback argument of the animated components on the worker directly
  • just like with the callback of the animated components, they require a string as input that gets evaluated on the worker

worker utility functions

There are a bunch of mehtods you can use in your custom callback logic (Lambdas, MatrixLerp, Lerp) to manipulate, start, or stop animations. Some of them will just set, or return a value from the registry.

Method Description Arguments
addTrigger triggers another animation at a certain step and delta_t value id, target, step, time
removeTrigger removes a trigger id, target, step, time
get_time gets the delta_t value of an animation id
set_delta_t sets the delta_t value of an animation id, val
current_step returns the current step of an animation id
set_step sets the current step of an animation id, val
is_active returns true if an animations is currently running id
get_active get all avtive animation indices .
start_animations a list of animation indices to start indices
stop_animations a list of animation indices to stop indices
setLerp set a Lerp target value for a certain step of an animation index, step, value
setMatrix set the matrix lerp target value for a certain step of an animation index, step, value
get_lerp_value returnt the lerp result vlaue of an animation id
soft_reset starts and resets an animation if its finished, or not playing id
hard_reset starts and resets the animation without checking if its finished id
get_duration get the duration of an animation id
set_duration set the duraiton of an animation id, val
set_sequence_length set the lengths of steps that get lerped through id, val
change_framerate set the fps fps_new
get_constant returns a constant (matrix, or number) id, type
get_constant_number returns a constant (number) id
get_constant_row returns a row of a matrix constant id, row
render_constant messages the mainthread and sends the updated constant value id, type
update_constant set a constant value id, type, value
set_delay set the delay of an animaiton id, val
get_delay get the delay of an animation id
get_delay_delta get the delay_delta (delay progress) of an animation id
set_delay_delta set the delay_delta (delay progress) of an animation id, val
lambda_call perform a lambda call id, args

Examples

Timeline

  • in this example we are using lambdas to edit edit the registry on the worker to alter the animations during certain events.

the full example can be found here

    animProps.idle_animation= animator.Timeline({ 
      duration: 100,
      render_interval:20, 
      steps: [[0],[1]],
      loop:true,
      callback:{
        callback:`(({time})=>{
          console.log("----------timeline animation----------")
          console.log("time " + time)
          if(time==0){
                  update_constant(${animProps.selected.id},"number",-1)
                  // those are some additional lambdas we defined earlier         
                  lambda_call(${animProps.stop_active.id}) 
                  lambda_call(${animProps.start_random.id}) 
          }
          else if(time==80){
            const random_index = get_constant_number(${animProps.selected.id})
            console.log("random selection is " + random_index)
            // those are some additional lambdas we defined earlier 
            lambda_call(${animProps.replace_indices.id},{index:random_index,ref_step:0})
            console.log("updated values")
            console.log("started animation with index " + random_index)
            soft_reset(random_index)
          }
            console.log("--------------------------------")
        })`
      }
      })

contrbuting examples

Feel free to contribute your own examples or open a feature request.

  • I deployed to gh-pages branch using bun deploy

how to run the example project

  • git clone [email protected]:ji-podhead/kooljs.git

  • cd example_project

  • bun start

  • I left the vscode folder in the branch so you can directly debug it with chrome

    • firefox is apprently having some issues with triggering breakpoints on rhel

how to use

  • since kooljs is using workers and typed arrays, the procedure is as follows:
      1. create an animator instance
      import { Animator } from "./kooljs/animations"
      
      const animator = new Animator(30)
      1. create a Lerp instance
        const new_lerp=animator.Lerp({ 
          accessor: [undefined, ((val,id) => {document.getElementById(`e3_${id}`).style.transform = `translate(0%,${val}%)`;})],
          duration: 10,
          steps: [10,100],
      })
      1. initialize the worker
      animator.init()

each time you call animator.init() it will recreate the entire registry in the worker, so do that only if you really have to and pass down the animator where ever you can

roadmap

  • rendering canvas
  • spline
  • spring
  • constant renderevents, when changing constants via worker_callback
  • lerp_divs
  • GPU acceleration
  • matrix lerp and complex magrix calculcations via callback function

Enhancements

  • removeing accessor and exchange with render_callback (using setter only)
  • use fixed size for results
    - use special keywords in the callback to use the registry of the worker thread
    - triggering animations on the worker thread

info

a cool animation tool for js. name provided by thebusinessman0920_55597 and bomi from the programers hangout helped with the name!