Giter VIP home page Giter VIP logo

Comments (8)

Tao-VanJS avatar Tao-VanJS commented on July 30, 2024

Hi @farzher,

Thanks for reaching out! Do you have some code to illustrate the problem that you're encountering? If possible, I can try to see how it can be fixed.

from van.

sirenkovladd avatar sirenkovladd commented on July 30, 2024

I think you are looking for something like this

const {a, div, li, p, ul} = van.tags

const mainObj = {
  i: 0,
  text: 'Hello'
}

const stateObj = Object.fromEntries(Object.entries(mainObj).map(([k,v]) => [k, van.state(v)]));

function update() {
  for (const key of Object.keys(mainObj)) {
    if (stateObj[key].val !== mainObj[key]) {
      stateObj[key].val = mainObj[key]
    }
  }
}

function recursive() {
  if (mainObj.text.length > 15) {
  	return
  }
  const rand = Math.round(Math.random() * 26)
  mainObj.text += String.fromCharCode(65 + rand)
  mainObj.i += rand
  recursive()
}

van.add(document.body, div(stateObj.i), div(stateObj.text))

recursive()
update()

from van.

farzher avatar farzher commented on July 30, 2024

Hi @farzher,

Thanks for reaching out! Do you have some code to illustrate the problem that you're encountering? If possible, I can try to see how it can be fixed.

sure, one use case i have is rendering UI on top of a webgl game canvas.

i have a game state. i have a render function. i simply want to redraw my UI every frame, like a game would.

here's some example code i have of rendering usernames. it mostly works but it's very hairy

<script type="text/javascript" src="https://cdn.jsdelivr.net/gh/vanjs-org/van/public/van-1.2.8.nomodule.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/[email protected]/dist/van-x.nomodule.min.js"></script>

<style>
  html,body,* {margin:0;padding:0;overflow:hidden;}
  body        {background: rgb(26,26,26);}
</style>
<body></body>

<script>



// some example state

const me = {user_id:1, x: 0, y: 0}
const lobby_state = {}
const chat_bubbles = vanX.reactive({})

chat_bubbles[1] = {username: 'farzher', msg: 'sup', user_id: 1}
chat_bubbles[2] = {username: 'Guest', msg: 'hello', user_id: 2}
lobby_state[2] = {x: 50, y: 50, user_id: 2}




window.requestAnimationFrame(update)
function update() {
  window.requestAnimationFrame(update)

  // simulate player walking around
  for(const user_id in lobby_state) {
    const player = lobby_state[user_id]
    player.x += 1
    if(player.x > 200) player.x = -200
  }
}


// called many times per second
window.requestAnimationFrame(render)
function render() {
  window.requestAnimationFrame(render)
  render_chat_bubbles()
}





const manualrender = van.state(0)
function render_chat_bubbles() {
  manualrender.val++
}

function chat_bubbles_vanjs() {

  const {div, a, code, img, input, hr, span} = van.tags

  const van_if = (bool, val) => bool ? val : div()

  return (
    div({style: 'pointer-events: none'},
      vanX.list(div, chat_bubbles, ({val: msginfo}) => {

        const w = window.innerWidth
        const h = window.innerHeight

        const is_me = msginfo.user_id == me.user_id
        if(is_me) return div({class: 'speech-bubble', style: () => `manualrender:${manualrender.val}; max-width:240px; max-height:100px; padding:10px; text-align:center;    position:absolute; left:${w/2}px; top:${h/2 - 80}px; transform: translate(-50%, -50%); color: white;`}, msginfo.msg)

        // the chat bubble is not from me, we need to render it on the player
        const entity = lobby_state[msginfo.user_id]
        return div({class: 'speech-bubble', style: () => `manualrender:${manualrender.val}; max-width:240px; max-height:100px; padding:10px; text-align:center;    position:absolute; left:${entity.x + w/2 - me.x}px; top:${entity.y + h/2 - 80 - me.y}px; transform: translate(-50%, -50%); color: white;`}, msginfo.msg)
      })
    )
  )
}



van.add(document.body, chat_bubbles_vanjs())


</script>

from van.

sirenkovladd avatar sirenkovladd commented on July 30, 2024

If you want to avoid updating the variable immediately after editing, you need to use additional state

here is an example
https://jsfiddle.net/Sirenko/suzw85o3/

from van.

Tao-VanJS avatar Tao-VanJS commented on July 30, 2024

Hi @farzher,

Normally it might not be a good idea to re-render the entire UI. Making the re-rendering as localized as possible is usually better for performance and user experience.

But in case you do want global re-rendering for the entire UI, you can try this pattern:

const frameNum = van.state(0)
const fps = 60  // You can set your desired fps here
setInterval(() => ++frameNum.val, 1000 / fps)

van.add(document.body, () => {
  frameNum.val
  return <The entire DOM tree for your UI>
})

You shouldn't use states or binding functions like vanX.list for the rest of your app, as using states elsewhere might trigger the re-rendering some local parts of the UI.

from van.

farzher avatar farzher commented on July 30, 2024

@sirenkovladd your examples are much better than what i had. but they're still too clumsy to use, for example they still have the problem that window.innerWidth is somehow cached and never recalculated when the window is resized.

from van.

farzher avatar farzher commented on July 30, 2024

@Tao-VanJS this works great, except, yeah, it constantly rewrites the dom which can be a problem. i guess i'm looking for a js library that will let me generate a full virtual dom every frame like that, but it will do a diff on its end and only update on the dom what's necessary. would you happen to know of any lightweight options for this?

from van.

Tao-VanJS avatar Tao-VanJS commented on July 30, 2024

@Tao-VanJS this works great, except, yeah, it constantly rewrites the dom which can be a problem. i guess i'm looking for a js library that will let me generate a full virtual dom every frame like that, but it will do a diff on its end and only update on the dom what's necessary. would you happen to know of any lightweight options for this?

I guess React is a good diff-based re-rendering? In VanJS, you're encouraged to bind states to local scopes to prevent the entire DOM tree from being re-rendered.

from van.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.