autoformat
This commit is contained in:
		
							parent
							
								
									bfa569853b
								
							
						
					
					
						commit
						7bff008853
					
				
					 4 changed files with 131 additions and 83 deletions
				
			
		| 
						 | 
				
			
			@ -1,5 +1,9 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <SVGContent id="root" url="content/intro.svg" @set-background="setBackground"/>
 | 
			
		||||
  <SVGContent
 | 
			
		||||
    id="root"
 | 
			
		||||
    url="content/intro.svg"
 | 
			
		||||
    @set-background="setBackground"
 | 
			
		||||
  />
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
| 
						 | 
				
			
			@ -10,23 +14,27 @@ import "normalize.css";
 | 
			
		|||
export default defineComponent({
 | 
			
		||||
  name: "App",
 | 
			
		||||
  components: {
 | 
			
		||||
    SVGContent
 | 
			
		||||
    SVGContent,
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    setBackground(background: string) {
 | 
			
		||||
      document.body.style.background = background;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style>
 | 
			
		||||
html, body {
 | 
			
		||||
html,
 | 
			
		||||
body {
 | 
			
		||||
  overflow: hidden;
 | 
			
		||||
  background: black;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
html, body, #app, #root {
 | 
			
		||||
html,
 | 
			
		||||
body,
 | 
			
		||||
#app,
 | 
			
		||||
#root {
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
  cursor: default;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,5 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <audio ref="audio"
 | 
			
		||||
         :src="definition.src"
 | 
			
		||||
         loop preload="auto"/>
 | 
			
		||||
  <audio ref="audio" :src="definition.src" loop preload="auto" />
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
| 
						 | 
				
			
			@ -13,11 +11,11 @@ export default defineComponent({
 | 
			
		|||
  props: {
 | 
			
		||||
    definition: {
 | 
			
		||||
      type: Object as PropType<AudioAreaDef>,
 | 
			
		||||
      required: true
 | 
			
		||||
      required: true,
 | 
			
		||||
    },
 | 
			
		||||
    bbox: {
 | 
			
		||||
      type: Object as PropType<BoundingBox>,
 | 
			
		||||
      required: true
 | 
			
		||||
      required: true,
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  setup(props) {
 | 
			
		||||
| 
						 | 
				
			
			@ -34,18 +32,27 @@ export default defineComponent({
 | 
			
		|||
    const onBBoxChange = () => {
 | 
			
		||||
      const x = props.bbox.x + props.bbox.w / 2;
 | 
			
		||||
      const y = props.bbox.y + props.bbox.h / 2;
 | 
			
		||||
      const distance = Math.sqrt(Math.pow(x - props.definition.cx, 2) + Math.pow(y - props.definition.cy, 2));
 | 
			
		||||
      const distance = Math.sqrt(
 | 
			
		||||
        Math.pow(x - props.definition.cx, 2) +
 | 
			
		||||
          Math.pow(y - props.definition.cy, 2)
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
      if (distance < props.definition.radius) {
 | 
			
		||||
        if (audio.value!.paused) {
 | 
			
		||||
          console.debug(`[AUDIOAREA] Entered audio area "${props.definition.src}", starting playback...`);
 | 
			
		||||
          console.debug(
 | 
			
		||||
            `[AUDIOAREA] Entered audio area "${props.definition.src}", starting playback...`
 | 
			
		||||
          );
 | 
			
		||||
          audio.value!.play();
 | 
			
		||||
        }
 | 
			
		||||
        const volume = (props.definition.radius - distance) / props.definition.radius;
 | 
			
		||||
        audio.value!.volume = volume * (props.bbox.z < 1 ? (props.bbox.z * vol_x + vol_b) : 1);
 | 
			
		||||
        const volume =
 | 
			
		||||
          (props.definition.radius - distance) / props.definition.radius;
 | 
			
		||||
        audio.value!.volume =
 | 
			
		||||
          volume * (props.bbox.z < 1 ? props.bbox.z * vol_x + vol_b : 1);
 | 
			
		||||
      } else {
 | 
			
		||||
        if (!audio.value!.paused) {
 | 
			
		||||
          console.debug(`[AUDIOAREA] Left audio area "${props.definition.src}", pausing playback...`);
 | 
			
		||||
          console.debug(
 | 
			
		||||
            `[AUDIOAREA] Left audio area "${props.definition.src}", pausing playback...`
 | 
			
		||||
          );
 | 
			
		||||
          audio.value!.pause();
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -53,19 +60,18 @@ export default defineComponent({
 | 
			
		|||
    watch(props.bbox, onBBoxChange, { deep: true });
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
      audio
 | 
			
		||||
      audio,
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
  },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export interface AudioAreaDef {
 | 
			
		||||
  id: string,
 | 
			
		||||
  cx: number,
 | 
			
		||||
  cy: number,
 | 
			
		||||
  radius: number,
 | 
			
		||||
  src: string
 | 
			
		||||
  id: string;
 | 
			
		||||
  cx: number;
 | 
			
		||||
  cy: number;
 | 
			
		||||
  radius: number;
 | 
			
		||||
  src: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,10 +5,19 @@
 | 
			
		|||
    </div>
 | 
			
		||||
    <div class="content" ref="root">
 | 
			
		||||
      <div class="video-scrolls">
 | 
			
		||||
        <VideoScroll v-for="scroll in scrolls" :definition="scroll" :key="scroll.id"/>
 | 
			
		||||
        <VideoScroll
 | 
			
		||||
          v-for="scroll in scrolls"
 | 
			
		||||
          :definition="scroll"
 | 
			
		||||
          :key="scroll.id"
 | 
			
		||||
        />
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <AudioArea v-for="audio in audioAreas" :definition="audio" :bbox="bbox" :key="audio.id"/>
 | 
			
		||||
    <AudioArea
 | 
			
		||||
      v-for="audio in audioAreas"
 | 
			
		||||
      :definition="audio"
 | 
			
		||||
      :bbox="bbox"
 | 
			
		||||
      :key="audio.id"
 | 
			
		||||
    />
 | 
			
		||||
    <div class="dev devpanel">
 | 
			
		||||
      <div>
 | 
			
		||||
        <span>Current viewport position:</span>
 | 
			
		||||
| 
						 | 
				
			
			@ -382,10 +391,10 @@ export default defineComponent({
 | 
			
		|||
 | 
			
		||||
          if (gp) {
 | 
			
		||||
            if (gp.buttons[7].pressed) {
 | 
			
		||||
              gamePadZoomSpeed += .1;
 | 
			
		||||
              gamePadZoomSpeed += 0.1;
 | 
			
		||||
            }
 | 
			
		||||
            if (gp.buttons[5].pressed) {
 | 
			
		||||
              gamePadZoomSpeed -= .1;
 | 
			
		||||
              gamePadZoomSpeed -= 0.1;
 | 
			
		||||
            }
 | 
			
		||||
            if (gamePadZoomSpeed < 1) {
 | 
			
		||||
              gamePadZoomSpeed = 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -469,11 +478,14 @@ async function processScrolls(svg: XMLDocument): Promise<VideoScrollDef[]> {
 | 
			
		|||
                direction as VideoScrollDirection
 | 
			
		||||
              )
 | 
			
		||||
            ) {
 | 
			
		||||
              console.error(`Unknown direction definition: "${direction}" (in #${el.id})`);
 | 
			
		||||
              console.error(
 | 
			
		||||
                `Unknown direction definition: "${direction}" (in #${el.id})`
 | 
			
		||||
              );
 | 
			
		||||
              return false;
 | 
			
		||||
            }
 | 
			
		||||
            return direction as VideoScrollDirection;
 | 
			
		||||
          }).filter((d) => Boolean(d)) as VideoScrollDirection[];
 | 
			
		||||
          })
 | 
			
		||||
          .filter((d) => Boolean(d)) as VideoScrollDirection[];
 | 
			
		||||
 | 
			
		||||
        console.debug(`[SVG/VIDEOSCROLLS] Fetching ${filesURL}...`);
 | 
			
		||||
        const fileFetch = await fetch(`content/${filesURL}`);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,18 +1,20 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <div class="video-scroll" ref="root" v-if="definition.directions.length > 0">
 | 
			
		||||
    <img class="visible displayed loaded"
 | 
			
		||||
    <img
 | 
			
		||||
      class="visible displayed loaded"
 | 
			
		||||
      :src="definition.files[0]"
 | 
			
		||||
      :style="{
 | 
			
		||||
        top: `${Math.round(definition.top)}px`,
 | 
			
		||||
        left: `${Math.round(definition.left)}px`,
 | 
			
		||||
        width: isHorizontal ? `${Math.round(definition.width)}px` : 'auto',
 | 
			
		||||
        height: isVertical ? `${Math.round(definition.height)}px` : 'auto',
 | 
			
		||||
              transform: `rotate(${definition.angle}deg)`
 | 
			
		||||
        transform: `rotate(${definition.angle}deg)`,
 | 
			
		||||
      }"
 | 
			
		||||
    />
 | 
			
		||||
 | 
			
		||||
    <!--suppress RequiredAttributes -->
 | 
			
		||||
    <img v-for="(file, idx) in dynamicFiles"
 | 
			
		||||
    <img
 | 
			
		||||
      v-for="(file, idx) in dynamicFiles"
 | 
			
		||||
      :key="`${idx}_${file.src}`"
 | 
			
		||||
      :data-src="file.src"
 | 
			
		||||
      :style="{
 | 
			
		||||
| 
						 | 
				
			
			@ -20,7 +22,7 @@
 | 
			
		|||
        left: `${Math.round(file.left)}px`,
 | 
			
		||||
        width: `${Math.round(definition.width)}px`,
 | 
			
		||||
        height: `${Math.round(definition.height)}px`,
 | 
			
		||||
             transform: `rotate(${definition.angle}deg)`
 | 
			
		||||
        transform: `rotate(${definition.angle}deg)`,
 | 
			
		||||
      }"
 | 
			
		||||
    />
 | 
			
		||||
  </div>
 | 
			
		||||
| 
						 | 
				
			
			@ -35,36 +37,55 @@ export default defineComponent({
 | 
			
		|||
  props: {
 | 
			
		||||
    definition: {
 | 
			
		||||
      type: Object as PropType<VideoScrollDef>,
 | 
			
		||||
      required: true
 | 
			
		||||
    }
 | 
			
		||||
      required: true,
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  computed: {
 | 
			
		||||
    dynamicFiles(): { top: number, left: number, src: string }[] {
 | 
			
		||||
    dynamicFiles(): { top: number; left: number; src: string }[] {
 | 
			
		||||
      return this.definition.files.slice(1).map((src: string, idx: number) => {
 | 
			
		||||
        const cy = this.definition.top +
 | 
			
		||||
            (this.isVertical ? (this.definition.height * (idx + 1) * this.verticalDirection) : 0);
 | 
			
		||||
        const cx = this.definition.left +
 | 
			
		||||
            (this.isHorizontal ? (this.definition.width * (idx + 1) * this.horizontalDirection) : 0);
 | 
			
		||||
        const [left, top] = rotate(cx, cy, this.definition.left, this.definition.top, this.definition.angle);
 | 
			
		||||
        const cy =
 | 
			
		||||
          this.definition.top +
 | 
			
		||||
          (this.isVertical
 | 
			
		||||
            ? this.definition.height * (idx + 1) * this.verticalDirection
 | 
			
		||||
            : 0);
 | 
			
		||||
        const cx =
 | 
			
		||||
          this.definition.left +
 | 
			
		||||
          (this.isHorizontal
 | 
			
		||||
            ? this.definition.width * (idx + 1) * this.horizontalDirection
 | 
			
		||||
            : 0);
 | 
			
		||||
        const [left, top] = rotate(
 | 
			
		||||
          cx,
 | 
			
		||||
          cy,
 | 
			
		||||
          this.definition.left,
 | 
			
		||||
          this.definition.top,
 | 
			
		||||
          this.definition.angle
 | 
			
		||||
        );
 | 
			
		||||
        return { top, left, src };
 | 
			
		||||
      });
 | 
			
		||||
    },
 | 
			
		||||
    isHorizontal(): boolean {
 | 
			
		||||
      return this.definition.directions.some(
 | 
			
		||||
          (dir: VideoScrollDirection) => dir === VideoScrollDirection.LEFT || dir === VideoScrollDirection.RIGHT
 | 
			
		||||
        (dir: VideoScrollDirection) =>
 | 
			
		||||
          dir === VideoScrollDirection.LEFT ||
 | 
			
		||||
          dir === VideoScrollDirection.RIGHT
 | 
			
		||||
      );
 | 
			
		||||
    },
 | 
			
		||||
    isVertical(): boolean {
 | 
			
		||||
      return this.definition.directions.some(
 | 
			
		||||
          (dir: VideoScrollDirection) => dir === VideoScrollDirection.UP || dir === VideoScrollDirection.DOWN
 | 
			
		||||
        (dir: VideoScrollDirection) =>
 | 
			
		||||
          dir === VideoScrollDirection.UP || dir === VideoScrollDirection.DOWN
 | 
			
		||||
      );
 | 
			
		||||
    },
 | 
			
		||||
    horizontalDirection(): number {
 | 
			
		||||
      return this.definition.directions.includes(VideoScrollDirection.RIGHT) ? 1 : -1;
 | 
			
		||||
      return this.definition.directions.includes(VideoScrollDirection.RIGHT)
 | 
			
		||||
        ? 1
 | 
			
		||||
        : -1;
 | 
			
		||||
    },
 | 
			
		||||
    verticalDirection(): number {
 | 
			
		||||
      return this.definition.directions.includes(VideoScrollDirection.DOWN) ? 1 : -1;
 | 
			
		||||
    }
 | 
			
		||||
      return this.definition.directions.includes(VideoScrollDirection.DOWN)
 | 
			
		||||
        ? 1
 | 
			
		||||
        : -1;
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  mounted() {
 | 
			
		||||
    const observer = new IntersectionObserver((entries, _) => {
 | 
			
		||||
| 
						 | 
				
			
			@ -73,7 +94,9 @@ export default defineComponent({
 | 
			
		|||
        if (entry.isIntersecting) {
 | 
			
		||||
          element.classList.add("visible");
 | 
			
		||||
          if (!element.src) {
 | 
			
		||||
            console.debug(`[VIDEOSCROLL] Intersected, loading ${element.dataset.src}`);
 | 
			
		||||
            console.debug(
 | 
			
		||||
              `[VIDEOSCROLL] Intersected, loading ${element.dataset.src}`
 | 
			
		||||
            );
 | 
			
		||||
            element.src = element.dataset.src!;
 | 
			
		||||
            setTimeout(() => {
 | 
			
		||||
              element.classList.add("displayed");
 | 
			
		||||
| 
						 | 
				
			
			@ -98,27 +121,26 @@ export default defineComponent({
 | 
			
		|||
        observer.observe(el);
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export enum VideoScrollDirection {
 | 
			
		||||
  RIGHT = "right",
 | 
			
		||||
  LEFT = "left",
 | 
			
		||||
  UP = "up",
 | 
			
		||||
  DOWN = "down"
 | 
			
		||||
  DOWN = "down",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface VideoScrollDef {
 | 
			
		||||
  id: string,
 | 
			
		||||
  top: number,
 | 
			
		||||
  left: number,
 | 
			
		||||
  angle: number,
 | 
			
		||||
  width: number,
 | 
			
		||||
  height: number,
 | 
			
		||||
  directions: VideoScrollDirection[],
 | 
			
		||||
  files: string[]
 | 
			
		||||
  id: string;
 | 
			
		||||
  top: number;
 | 
			
		||||
  left: number;
 | 
			
		||||
  angle: number;
 | 
			
		||||
  width: number;
 | 
			
		||||
  height: number;
 | 
			
		||||
  directions: VideoScrollDirection[];
 | 
			
		||||
  files: string[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
 | 
			
		||||
| 
						 | 
				
			
			@ -129,7 +151,7 @@ export interface VideoScrollDef {
 | 
			
		|||
  background: grey;
 | 
			
		||||
  visibility: hidden;
 | 
			
		||||
  opacity: 0;
 | 
			
		||||
  transition: opacity .5s;
 | 
			
		||||
  transition: opacity 0.5s;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.video-scroll img.visible {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue