Browse Source

add emoji

schtonn 2 years ago
parent
commit
74e15f8118
2 changed files with 245 additions and 0 deletions
  1. 241 0
      js/springyEmojiCursor.js
  2. 4 0
      poets/index.html

+ 241 - 0
js/springyEmojiCursor.js

@@ -0,0 +1,241 @@
+// The springy emoji effect has been translated over from this old
+// code, to modern js & canvas
+// - http://www.yaldex.com/FSMessages/ElasticBullets.htm
+function springyEmojiCursor(options) {
+    let emoji = (options && options.emoji) || "🤪"
+    let hasWrapperEl = options && options.element
+    let element = hasWrapperEl || document.body
+  
+    let nDots = 7
+    let DELTAT = 0.01
+    let SEGLEN = 10
+    let SPRINGK = 10
+    let MASS = 1
+    let GRAVITY = 50
+    let RESISTANCE = 10
+    let STOPVEL = 0.1
+    let STOPACC = 0.1
+    let DOTSIZE = 11
+    let BOUNCE = 0.7
+  
+    let width = window.innerWidth
+    let height = window.innerHeight
+    let cursor = { x: width / 2, y: width / 2 }
+    let particles = []
+    let canvas, context
+  
+    let emojiAsImage
+  
+    function init() {
+      canvas = document.createElement("canvas")
+      context = canvas.getContext("2d")
+      canvas.style.top = "0px"
+      canvas.style.left = "0px"
+      canvas.style.pointerEvents = "none"
+  
+      if (hasWrapperEl) {
+        canvas.style.position = "absolute"
+        element.appendChild(canvas)
+        canvas.width = element.clientWidth
+        canvas.height = element.clientHeight
+      } else {
+        canvas.style.position = "fixed"
+        document.body.appendChild(canvas)
+        canvas.width = width
+        canvas.height = height
+      }
+  
+      // Save emoji as an image for performance
+      context.font = "16px serif"
+      context.textBaseline = "middle"
+      context.textAlign = "center"
+  
+      let measurements = context.measureText(emoji)
+      let bgCanvas = document.createElement("canvas")
+      let bgContext = bgCanvas.getContext("2d")
+  
+      bgCanvas.width = measurements.width
+      bgCanvas.height = measurements.actualBoundingBoxAscent * 2
+  
+      bgContext.textAlign = "center"
+      bgContext.font = "16px serif"
+      bgContext.textBaseline = "middle"
+      bgContext.fillText(
+        emoji,
+        bgCanvas.width / 2,
+        measurements.actualBoundingBoxAscent
+      )
+  
+      emojiAsImage = bgCanvas
+  
+      let i = 0
+      for (i = 0; i < nDots; i++) {
+        particles[i] = new Particle(emojiAsImage)
+      }
+  
+      bindEvents()
+      loop()
+    }
+  
+    // Bind events that are needed
+    function bindEvents() {
+      element.addEventListener("mousemove", onMouseMove)
+      element.addEventListener("touchmove", onTouchMove, { passive: true })
+      element.addEventListener("touchstart", onTouchMove, { passive: true })
+      window.addEventListener("resize", onWindowResize)
+    }
+  
+    function onWindowResize(e) {
+      width = window.innerWidth
+      height = window.innerHeight
+  
+      if (hasWrapperEl) {
+        canvas.width = element.clientWidth
+        canvas.height = element.clientHeight
+      } else {
+        canvas.width = width
+        canvas.height = height
+      }
+    }
+  
+    function onTouchMove(e) {
+      if (e.touches.length > 0) {
+        if (hasWrapperEl) {
+          const boundingRect = element.getBoundingClientRect()
+          cursor.x = e.touches[0].clientX - boundingRect.left
+          cursor.y = e.touches[0].clientY - boundingRect.top
+        } else {
+          cursor.x = e.touches[0].clientX
+          cursor.y = e.touches[0].clientY
+        }
+      }
+    }
+  
+    function onMouseMove(e) {
+      if (hasWrapperEl) {
+        const boundingRect = element.getBoundingClientRect()
+        cursor.x = e.clientX - boundingRect.left
+        cursor.y = e.clientY - boundingRect.top
+      } else {
+        cursor.x = e.clientX
+        cursor.y = e.clientY
+      }
+    }
+  
+    function updateParticles() {
+      canvas.width = canvas.width
+  
+      // follow mouse
+      particles[0].position.x = cursor.x
+      particles[0].position.y = cursor.y
+  
+      // Start from 2nd dot
+      for (i = 1; i < nDots; i++) {
+        let spring = new vec(0, 0)
+  
+        if (i > 0) {
+          springForce(i - 1, i, spring)
+        }
+  
+        if (i < nDots - 1) {
+          springForce(i + 1, i, spring)
+        }
+  
+        let resist = new vec(
+          -particles[i].velocity.x * RESISTANCE,
+          -particles[i].velocity.y * RESISTANCE
+        )
+  
+        let accel = new vec(
+          (spring.X + resist.X) / MASS,
+          (spring.Y + resist.Y) / MASS + GRAVITY
+        )
+  
+        particles[i].velocity.x += DELTAT * accel.X
+        particles[i].velocity.y += DELTAT * accel.Y
+  
+        if (
+          Math.abs(particles[i].velocity.x) < STOPVEL &&
+          Math.abs(particles[i].velocity.y) < STOPVEL &&
+          Math.abs(accel.X) < STOPACC &&
+          Math.abs(accel.Y) < STOPACC
+        ) {
+          particles[i].velocity.x = 0
+          particles[i].velocity.y = 0
+        }
+  
+        particles[i].position.x += particles[i].velocity.x
+        particles[i].position.y += particles[i].velocity.y
+  
+        let height, width
+        height = canvas.clientHeight
+        width = canvas.clientWidth
+  
+        if (particles[i].position.y >= height - DOTSIZE - 1) {
+          if (particles[i].velocity.y > 0) {
+            particles[i].velocity.y = BOUNCE * -particles[i].velocity.y
+          }
+          particles[i].position.y = height - DOTSIZE - 1
+        }
+  
+        if (particles[i].position.x >= width - DOTSIZE) {
+          if (particles[i].velocity.x > 0) {
+            particles[i].velocity.x = BOUNCE * -particles[i].velocity.x
+          }
+          particles[i].position.x = width - DOTSIZE - 1
+        }
+  
+        if (particles[i].position.x < 0) {
+          if (particles[i].velocity.x < 0) {
+            particles[i].velocity.x = BOUNCE * -particles[i].velocity.x
+          }
+          particles[i].position.x = 0
+        }
+  
+        particles[i].draw(context)
+      }
+    }
+  
+    function loop() {
+      updateParticles()
+      requestAnimationFrame(loop)
+    }
+  
+    function vec(X, Y) {
+      this.X = X
+      this.Y = Y
+    }
+  
+    function springForce(i, j, spring) {
+      let dx = particles[i].position.x - particles[j].position.x
+      let dy = particles[i].position.y - particles[j].position.y
+      let len = Math.sqrt(dx * dx + dy * dy)
+      if (len > SEGLEN) {
+        let springF = SPRINGK * (len - SEGLEN)
+        spring.X += (dx / len) * springF
+        spring.Y += (dy / len) * springF
+      }
+    }
+  
+    function Particle(canvasItem) {
+      this.position = { x: cursor.x, y: cursor.y }
+      this.velocity = {
+        x: 0,
+        y: 0,
+      }
+  
+      this.canv = canvasItem
+  
+      this.draw = function(context) {
+        context.drawImage(
+          this.canv,
+          this.position.x - this.canv.width / 2,
+          this.position.y - this.canv.height / 2,
+          this.canv.width,
+          this.canv.height
+        )
+      }
+    }
+  
+    init()
+  }

+ 4 - 0
poets/index.html

@@ -1,5 +1,9 @@
 <head>
     <title>智慧诗集</title>
+    <script src="/js/springyEmojiCursor.js"></script>
+    <script>
+        new springyEmojiCursor({emoji:"🤐"});
+    </script>
 </head>
 <body>
     <h3>间或</h3>