Created
August 5, 2025 19:59
-
-
Save mmpataki/bba644d9ace0caab03fb6de7db772e42 to your computer and use it in GitHub Desktop.
movable ladybug
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| function MoveableItem(img, initX, initY) { | |
| /* non class functions */ | |
| function now() { return +(new Date()) } | |
| function move(img, x, y) { | |
| img.style.left = `${x}px` | |
| img.style.bottom = `${y}px` | |
| } | |
| function rotate(img, deg) { | |
| img.style.transform = `rotate(${deg}deg)` | |
| } | |
| function decideMoveParams(curX, curY, newX, newY) { | |
| console.debug(curX, curY, newX, newY) | |
| // find the distance | |
| let dist = Math.sqrt(Math.pow(newX - curX, 2) + Math.pow(newY - curY, 2)) | |
| // move these many pixels per frame | |
| let pxPerFrame = 5; | |
| // these many steps | |
| let steps = dist / pxPerFrame; | |
| // delta X move per step | |
| let dx = (newX - curX) / steps; | |
| let dy = (newY - curY) / steps; | |
| // find the angle too | |
| let theta = Math.atan2((newY - curY), (newX - curX)) * (180 / Math.PI) | |
| console.debug(steps, dx, dy, theta) | |
| return { steps, dx, dy, theta } | |
| } | |
| /* class functions */ | |
| this.mouseMoved = () => { | |
| this.lastMove = now(); | |
| if (this.moving) { | |
| clearInterval(this.moving); | |
| this.moving = undefined; | |
| this.setupMotionChecker() | |
| move(this.img, this.initX, this.initY) | |
| } | |
| } | |
| this.move_look_repeat = () => { | |
| let moveState = this.moveState; | |
| if (moveState.steps <= 0) { | |
| let bcr = document.body.getBoundingClientRect(); | |
| let MX = bcr.width, MY = bcr.height; | |
| //let MX = 400, MY = 400; | |
| this.moveState = moveState = { ...moveState, ...decideMoveParams(moveState.curX, moveState.curY, Math.random() * MX, Math.random() * MY) } | |
| rotate(this.img, 90 - moveState.theta); | |
| } | |
| //console.log(JSON.stringify(moveState)) | |
| move(this.img, moveState.curX += moveState.dx, moveState.curY += moveState.dy); | |
| moveState.steps--; | |
| } | |
| // image to move | |
| this.img = img; | |
| this.initX = initX; | |
| this.initY = initY; | |
| // state of the movement | |
| this.moveState = { curX: initX, curY: initY, steps: 0, dx: 0, dy: 0, theta: 90 }; | |
| // when did mouse move last? | |
| this.lastMove = now(); | |
| // move schedule | |
| this.moving = undefined; | |
| this.motionChecker = undefined; | |
| this.scheduleMove = () => { | |
| this.moving = setInterval(_ => this.move_look_repeat(), 50); | |
| } | |
| this.checkMotion = () => { | |
| if (now() - this.lastMove > 5000) { | |
| clearInterval(this.motionChecker); | |
| this.scheduleMove(); | |
| } | |
| } | |
| this.setupMotionChecker = () => { | |
| this.motionChecker = setInterval(_ => this.checkMotion(), 5000); | |
| } | |
| window.addEventListener('mousemove', _ => this.mouseMoved()) | |
| this.setupMotionChecker() | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| let btn = document.createElement('button') | |
| btn.innerText = 'hello' | |
| new MoveableItem(btn, 15, 15) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment