瀏覽代碼

Add v and h unit, hard code size, zoom viewport

Alan Colon 7 年之前
父節點
當前提交
db0a3ceec7
共有 4 個文件被更改,包括 130 次插入98 次删除
  1. 18 6
      src/index.css
  2. 4 2
      src/index.html
  3. 103 89
      src/index.js
  4. 5 1
      src/util.js

+ 18 - 6
src/index.css

@@ -3,19 +3,31 @@
 html {
   outline: solid 2px blue;
   overflow: hidden;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  width: 100vw;
+  height: 100vh;
+  background-color: black;
 }
 body {
   margin: 0;
-  outline: solid 2px red;
   background-color: #252423;
   color: #F6F4F2;
   font-family: Roboto;
-  display: flex;
-  justify-content: center;
-  align-items: center;
   position: absolute;
-  width: 100vw;
-  height: 100vh;
+  width: 1920px;
+  height: 1080px;
+  zoom: 50%;
+}
+
+scene, .scene {
+  display: inline-block;
+  position: absolute;
+  width: 1920px;
+  height: 1080px;
+  xoutline: solid 10px #ff8800aa;
+  xoutline: solid 1000px black;
 }
 
 sprite, .sprite {

+ 4 - 2
src/index.html

@@ -3,7 +3,9 @@
     <title>CHANGEME</title>
   </head>
   <body>
-      <sprite id="frown" left="50" top="50" translateX[0]="-50" translateX[1.5]="0" translateX[3]="-50">🙁</sprite>
-      <sprite id="smile" left="0" top="0" scale[0,1,2,3]="1,2,3,4" translateX[0,1,2,3,4]="0,100vw,100vw,0,50vw" translateY[0,1,2,3,4]="0,0,100vh,100vh,50vh" duration[4]="6" rotate[4]="720" easing[4]="easeOutSine">😊</sprite>
+    <scene duration="10" background="https://www.alanc.net/programphile/computer-code-flythrough-loop-01.mov">
+      <sprite id="frown" left="50%" top="50%" translateX[0]="-50" translateX[1.5]="0" translateX[3]="-50">🙁</sprite>
+      <sprite id="smile" left="0" top="0" scale[0,1,2,3]="1,2,3,4" translateX[0,1,2,3,4]="0,100w,100w,0,50w" translateY[0,1,2,3,4]="0,0,1080,1080,540" duration[4]="6" rotate[4]="720" easing[4]="easeOutSine">😊</sprite>
+    </scene>
   </body>
 </html>

+ 103 - 89
src/index.js

@@ -2,107 +2,121 @@ require('./index.css')
 const anime = require('animejs').default
 const animations = require('./animations')
 const { getAttrs, unit, transforms } = require('./util')
+const WIDTH = 1920
+const HEIGHT = 1080
 document.addEventListener('DOMContentLoaded', () => {
-  const sprites = Array.from(document.querySelectorAll('sprite, .sprite'))
+  const resize = () => {
+    const wScale = window.innerWidth / WIDTH
+    const hScale = window.innerHeight / HEIGHT
+    const scale = Math.min(wScale, hScale)
+    document.body.style.zoom = scale
+  }
+  window.addEventListener('resize', resize)
+  resize()
+  const scenes = Array.from(document.querySelectorAll('scene, .scene'))
+  scenes.forEach(scene => {
 
-  const spritesById = {}
-  sprites
-    .filter(sprite => sprite.id)
-    .forEach(sprite => spritesById[sprite.id] = sprite)
-  const timeline = anime.timeline()
-  const initialize = sprite => {
-    const mover = document.createElement('mover')
-    const centerer = document.createElement('centerer')
-    const scaler = document.createElement('scaler')
-    mover.appendChild(centerer)
-    centerer.appendChild(scaler)
-    sprite.replaceWith(mover)
-    scaler.appendChild(sprite)
-    if (sprite.initialized) return
-    sprite.initialized = true
+    const sprites = Array.from(scene.querySelectorAll('sprite, .sprite'))
 
-    sprite.keyFrames = {}
-    sprite.moverFrames = {}
-    ;['left', 'right', 'top', 'bottom', 'width', 'height', 'opacity'].forEach(key => {
-      const val = sprite.attributes[key]
-      if (val) mover.style[key] = unit(val)
-    })
+    const spritesById = {}
+    sprites
+      .filter(sprite => sprite.id)
+      .forEach(sprite => spritesById[sprite.id] = sprite)
+    const timeline = anime.timeline()
+    const initialize = sprite => {
+      const mover = document.createElement('mover')
+      const centerer = document.createElement('centerer')
+      const scaler = document.createElement('scaler')
+      mover.appendChild(centerer)
+      centerer.appendChild(scaler)
+      sprite.replaceWith(mover)
+      scaler.appendChild(sprite)
+      if (sprite.initialized) return
+      sprite.initialized = true
 
-    const getFrame = (time) => {
-      const key = time.toString()
-      if (!sprite.keyFrames[key]) {
-        sprite.keyFrames[key] = {targets: scaler}
+      sprite.keyFrames = {}
+      sprite.moverFrames = {}
+      ;['left', 'right', 'top', 'bottom', 'width', 'height', 'opacity'].forEach(key => {
+        const val = sprite.attributes[key]
+        if (val) mover.style[key] = unit(val)
+      })
+
+      const getFrame = (time) => {
+        const key = time.toString()
+        if (!sprite.keyFrames[key]) {
+          sprite.keyFrames[key] = {targets: scaler}
+        }
+        return sprite.keyFrames[key]
       }
-      return sprite.keyFrames[key]
-    }
-    const getMoverFrame = (time) => {
-      const key = time.toString()
-      if (!sprite.moverFrames[key]) {
-        sprite.moverFrames[key] = {targets: mover}
+      const getMoverFrame = (time) => {
+        const key = time.toString()
+        if (!sprite.moverFrames[key]) {
+          sprite.moverFrames[key] = {targets: mover}
+        }
+        return sprite.moverFrames[key]
       }
-      return sprite.moverFrames[key]
-    }
 
-    Array.from(sprite.attributes).forEach(attr => {
-      let {1:name, 2:time} = (/^([^\]]*)\[([^\]]*)\]$/.exec(attr.name) || [null, attr.name, "0"])
-      const transform = transforms[name]
-      if (transform) {
-        const times = time.split(',').map(x => +x)
-        const values = attr.value.split(',').map(x => x.trim())
-        if (times.length !== values.length) return console.error('Mismatched time, value arrays', attr)
-        times.forEach((time, i) => {
-          const value = values[i]
-          console.log(`${transform.name} ${value} at ${time}`, attr)
-          if (transform.global) {
-            getMoverFrame(time)[transform.name] = value
-            getFrame(time)[transform.name] = value
-          } else if (transform.mover) {
-            getMoverFrame(time)[transform.name] = value
-          } else {
-            getFrame(time)[transform.name] = value
-          }
-        })
-      }
-      sprite.removeAttribute(attr.name)
-    })
-    // if (anim) {
-    //   anime(Object.assign({
-    //     targets: sprite
-    //   }, animations[anim]))
-    // }
-  }
+      Array.from(sprite.attributes).forEach(attr => {
+        let {1:name, 2:time} = (/^([^\]]*)\[([^\]]*)\]$/.exec(attr.name) || [null, attr.name, "0"])
+        const transform = transforms[name]
+        if (transform) {
+          const times = time.split(',').map(x => +x)
+          const values = attr.value.split(',').map(x => x.trim())
+          if (times.length !== values.length) return console.error('Mismatched time, value arrays', attr)
+          times.forEach((time, i) => {
+            const value = unit(values[i])
+            console.log(`${transform.name} ${value} at ${time}`, attr)
+            if (transform.global) {
+              getMoverFrame(time)[transform.name] = value
+              getFrame(time)[transform.name] = value
+            } else if (transform.mover) {
+              getMoverFrame(time)[transform.name] = value
+            } else {
+              getFrame(time)[transform.name] = value
+            }
+          })
+        }
+        sprite.removeAttribute(attr.name)
+      })
+      // if (anim) {
+      //   anime(Object.assign({
+      //     targets: sprite
+      //   }, animations[anim]))
+      // }
+    }
 
-  sprites.forEach(initialize)
+    sprites.forEach(initialize)
 
-  const allFrames = []
-  sprites.forEach(({keyFrames, moverFrames}) => {
-    const frames = [...Object.entries(keyFrames), ...Object.entries(moverFrames)].map(([time, frame]) => [+time * 1000, frame])
-    frames.sort((a, b) => a[0] - b[0])
-    frames.forEach(frame => {
-      frame[1].targets.lastTime = 0
-      if (frame[1].duration) {
-        frame[1].duration = 1000 * +frame[1].duration
-      }
+    const allFrames = []
+    sprites.forEach(({keyFrames, moverFrames}) => {
+      const frames = [...Object.entries(keyFrames), ...Object.entries(moverFrames)].map(([time, frame]) => [+time * 1000, frame])
+      frames.sort((a, b) => a[0] - b[0])
+      frames.forEach(frame => {
+        frame[1].targets.lastTime = 0
+        if (frame[1].duration) {
+          frame[1].duration = 1000 * +frame[1].duration
+        }
+      })
+      frames.forEach(frame => {
+        allFrames.push(frame)
+        if (frame[0] == 0) {
+          frame[0] = Number.EPSILON
+          frame[1].easing = 'steps(1)'
+        } else {
+          frame[1].duration = frame[1].duration || Math.min(1000, frame[0] - frame[1].targets.lastTime)
+        }
+        frame[1].targets.lastTime = frame[0]
+      })
     })
-    frames.forEach(frame => {
-      allFrames.push(frame)
-      if (frame[0] == 0) {
-        frame[0] = Number.EPSILON
-        frame[1].easing = 'steps(1)'
-      } else {
-        frame[1].duration = frame[1].duration || Math.min(1000, frame[0] - frame[1].targets.lastTime)
-      }
-      frame[1].targets.lastTime = frame[0]
+    allFrames.sort((a, b) => a[0] - b[0])
+
+    console.log(allFrames)
+    allFrames.forEach(([time, keyFrame]) => {
+      timeline.add(keyFrame, time)
+      console.log(time, keyFrame)
     })
-  })
-  allFrames.sort((a, b) => a[0] - b[0])
 
-  console.log(allFrames)
-  allFrames.forEach(([time, keyFrame]) => {
-    timeline.add(keyFrame, time)
-    console.log(time, keyFrame)
+    console.log(timeline)
   })
-
-  console.log(timeline)
 })
 

+ 5 - 1
src/util.js

@@ -5,11 +5,15 @@ const getAttrs = (element) => {
   })
 }
 
-const unit = (value, u = '%') => {
+const unit = (value, u = '') => {
   if (value === undefined || value === null) return null
   if (value instanceof Attr) value = value.value
   if (typeof value === 'number') value = value.toString()
   if (typeof value === 'string' && /^[\d\.]*$/.test(value)) value += u
+  const w = /^([\d\.]+)w$/i.exec(value)
+  if (w) value = `${+w[1] * 1920 / 100}px`
+  const h = /^([\d\.]+)h$/i.exec(value)
+  if (h) value = `${+h[1] * 1080 / 100}px`
   return value
 }