Skip to content

Commit

Permalink
[Refactor] Code Cleanup & Logic Aggregation (#13)
Browse files Browse the repository at this point in the history
* Aggregate video viewer logic

* Adjust sizing

* Adjust ui

* Modify elementInViewport

* Only auto play changelog videos when in view

* UI tweaks

* Aggregate EqAsset logic to class

* Change emitter view size

* New release
  • Loading branch information
Akkadius authored Jan 16, 2022
1 parent 51f9788 commit d5b4016
Show file tree
Hide file tree
Showing 27 changed files with 376 additions and 572 deletions.
45 changes: 31 additions & 14 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
## [1.5.1]

* Changelog page now only autoplays videos that are in the current viewport
* Adjusted preview video size for emitters
* Improvements to video preview rendering logic

## [1.5.0]

### Player Animation Viewer

* Spire now has an player animation viewer that can be used standalone and in things like a Spell editor where there are casting and target animations when spells are casted
* Spire now has an player animation viewer that can be used standalone and in things like a Spell editor where there are
casting and target animations when spells are casted
* Special thanks to DeadZergling for all of his effort putting together these high quality preview videos

[![](https://img.youtube.com/vi/_WLjso1d9p8/0.jpg)](https://www.youtube.com/watch?v=_WLjso1d9p8)
Expand All @@ -11,7 +18,8 @@

### Emitter Viewer

* Spire now has an emitter viewer that now makes it easy for anyone looking to manipulate emitter text files in the client to find what kind of effects they want to play with or insert into their zones
* Spire now has an emitter viewer that now makes it easy for anyone looking to manipulate emitter text files in the
client to find what kind of effects they want to play with or insert into their zones
* Special thanks to DeadZergling for all of his effort putting together these high quality preview videos

[![](https://img.youtube.com/vi/dpE_xWR2i6o/0.jpg)](https://www.youtube.com/watch?v=dpE_xWR2i6o)
Expand All @@ -26,15 +34,17 @@

### Spire Launch!

**Akkadius**
**Akkadius**

Spire is now available for general release and the repository can be found here [https://github.com/Akkadius/spire](https://github.com/Akkadius/spire)
Spire is now available for general release and the repository can be found
here [https://github.com/Akkadius/spire](https://github.com/Akkadius/spire)

### Spire Desktop Release

Spire can be ran as a standalone executable on Windows.
Spire can be ran as a standalone executable on Windows.

Download the latest release here [https://github.com/Akkadius/spire/releases](https://github.com/Akkadius/spire/releases)
Download the latest release
here [https://github.com/Akkadius/spire/releases](https://github.com/Akkadius/spire/releases)

To run, simply put **spire.exe** in your server directory and double click (On Windows)

Expand All @@ -53,7 +63,8 @@ To run, simply put **spire.exe** in your server directory and double click (On W

#### Hover Selector / Preview Tools

* Item editor comes bundled with many hover selector and preview tools to make development feedback loop the tightest and best experience it can possibly be. Examples of these include:
* Item editor comes bundled with many hover selector and preview tools to make development feedback loop the tightest
and best experience it can possibly be. Examples of these include:
* Item free ID selector (hover over "id")
* Item model selector (hover over "idfile")
* Item icon selector (hover over "icon")
Expand All @@ -64,9 +75,11 @@ To run, simply put **spire.exe** in your server directory and double click (On W

#### Item Editor Sane Defaults

* The item editor does a lot in the way of setting sane defaults for the user. There are a lot of fields that need to be set when other fields are set so there are triggers that are setup to make this more intuitive.
* The item editor does a lot in the way of setting sane defaults for the user. There are a lot of fields that need to be
set when other fields are set so there are triggers that are setup to make this more intuitive.
* When **worneffect** is set to a non-zero value, **worntype** is set to 2
* When **clickeffect** is set to a non-zero value, **clicktype** is set to 5, recast delay set to 12000, maxcharges -1 and casttime to 3000
* When **clickeffect** is set to a non-zero value, **clicktype** is set to 5, recast delay set to 12000, maxcharges -1
and casttime to 3000
* When **scrolleffect** is set to a non-zero value, **scrolltype** is automatically set to 7
* When **bardeffect** is set to a non-zero value, **bardeffecttype** is set to 8
* When **augslot_1_type** is set to a non-zero value, **augslot_1_visible** is set to 1
Expand All @@ -77,15 +90,19 @@ To run, simply put **spire.exe** in your server directory and double click (On W

### Quest API Explorer

* Added a **Refresh** button for local and desktop builds for anyone who wants to refresh their Quest definitions manually. Production and hosted version of Spire receives webhooks when new commits are made to EQEmu/Server and local installations won't receive this and require a manual update.
* Added a **Refresh** button for local and desktop builds for anyone who wants to refresh their Quest definitions
manually. Production and hosted version of Spire receives webhooks when new commits are made to EQEmu/Server and local
installations won't receive this and require a manual update.

### General Fixes
### General Fixes

* (Kinglykrab reported) Dark Elf short name is now DEF, Wood Elf short name is now ELF, High Elf short name is now HIE, Halfling short name is now HFL
* (Kinglykrab reported) Dark Elf short name is now DEF, Wood Elf short name is now ELF, High Elf short name is now HIE,
Halfling short name is now HFL
* (Kinglykrab reported) Powersource icon was using Charm icon and is now the proper icon
* Scrollbar should be twice the size in width now
* (Trust reported) Expansion bitmask calculator now reports 0 (Classic) correctly
* Added an **Only** button to classes in the items search view so that search results can filter on items that are only equipped by selected class.
* Added an **Only** button to classes in the items search view so that search results can filter on items that are only
equipped by selected class.

## [1.0.3]

Expand All @@ -98,7 +115,7 @@ Embed the changelog you're reading into the app
## [1.0.1]

Remove application boot dependency on having `APP_NAME` set

## [1.0.0]

Initial release
File renamed without changes.
60 changes: 60 additions & 0 deletions frontend/src/app/eq-assets/eq-assets.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import PlayerAnimations from '@/app/eq-assets/player-animations.json';
import Emitters from "@/app/eq-assets/emitters.json";
import SpellAnimations from "@/app/eq-assets/spell-animations-map.json";

export default class EqAssets {

public static getPlayerAnimationFileIds() {
let ids = <any>[];
if (PlayerAnimations[0].contents) {
PlayerAnimations[0].contents.forEach((row) => {
const pieces = row.name.split(/\//);
const fileName = pieces[pieces.length - 1].replace(".mp4", "");
const animationId = parseInt(fileName)
ids.push(animationId)
})
}

ids.sort(function (a, b) {
return a - b;
});

return ids
}

public static getEmitterPreviewFileIds() {
let ids = <any>[];
if (Emitters[0].contents) {
Emitters[0].contents.forEach((row) => {
const pieces = row.name.split(/\//);
const fileName = pieces[pieces.length - 1].replace(".mp4", "");
const animationId = parseInt(fileName)
ids.push(animationId)
})
}

ids.sort(function (a, b) {
return a - b;
});

return ids
}

public static getSpellAnimationFileIds() {
let ids = <any>[];
if (SpellAnimations[0].contents) {
SpellAnimations[0].contents.forEach((row) => {
const pieces = row.name.split(/\//);
const fileName = pieces[pieces.length - 1].replace(".mp4", "");
const animationId = parseInt(fileName)
ids.push(animationId)
})
}

ids.sort(function (a, b) {
return a - b;
});

return ids
}
}
File renamed without changes.
156 changes: 156 additions & 0 deletions frontend/src/app/video-viewer/video-viewer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
export default class VideoViewer {
public static rendererEventListener: null;

public static debug = true;

public static log(...args: any[]) {
if (this.debug) {
// @ts-ignore
// 1. Convert args to a normal array
let args = Array.prototype.slice.call(arguments);

// 2. Prepend log prefix log string
args.unshift("[VideoViewer]");

// 3. Pass along arguments to console.log
// @ts-ignore
console.log.apply(console, args);
}
}

public static debounce(func, delay) {
let debounceTimer;
return function () {
// @ts-ignore
const context = this;
const args = arguments;
clearTimeout(debounceTimer);
debounceTimer = setTimeout(() => func.apply(context, args), delay);
};
}

public static handleRender = VideoViewer.debounce(() => {
// @ts-ignore
VideoViewer.log("Render")

let playing = []
let stopping = []
let videos = document.getElementsByClassName("video-preview");
for (let i = 0; i < videos.length; i++) {
let video = <HTMLVideoElement>videos.item(i)
if (video) {
let source = document.createElement("source");
let dataSrc = video.getAttribute("data-src")

// Toggle playing
if (VideoViewer.elementInViewport(video)) {
if (dataSrc) {

// video.setAttribute("src", dataSrc);
video.removeAttribute("data-src");
video.pause()
video.innerHTML = "";
video.removeAttribute("src");

source.setAttribute("src", dataSrc);
source.setAttribute("type", "video/mp4");
video.appendChild(source);
video.load();
video.play();
}

if (!VideoViewer.videoPlaying(video) && VideoViewer.videoLoaded(video)) {
video.play()
// @ts-ignore
playing.push(video.getAttribute("id"))
}
} else {
if (VideoViewer.videoPlaying(video) && VideoViewer.videoLoaded(video)) {
video.pause()
// @ts-ignore
stopping.push(video.getAttribute("id"))
}
}
}
}

if (playing.length > 0) {
VideoViewer.log("Playing", playing)
}
if (stopping.length > 0) {
VideoViewer.log("Stopping", stopping)
}
}, 10);

public static elementInViewport(elem) {
// if (!(elem instanceof Element)) throw Error('DomUtil: elem is not an element.');

let top = elem.offsetTop;
let left = elem.offsetLeft;
let width = elem.offsetWidth;
let height = elem.offsetHeight;

let el = elem;
while (el.offsetParent) {
el = el.offsetParent;
top += el.offsetTop;
left += el.offsetLeft;
}

const found = (
top < (window.pageYOffset + window.innerHeight) &&
left < (window.pageXOffset + window.innerWidth) &&
(top + height) > window.pageYOffset &&
(left + width) > window.pageXOffset
)

if (found) {
return true;
}

const style = getComputedStyle(elem);
if (style.display === 'none') return false;
if (style.visibility !== 'visible') return false;
// @ts-ignore
if (style.opacity < 0.1) return false;
// @ts-ignore
if (elem.offsetWidth + elem.offsetHeight + elem.getBoundingClientRect().height +
elem.getBoundingClientRect().width === 0) {
return false;
}
const elemCenter = {
x: elem.getBoundingClientRect().left + elem.offsetWidth / 2,
y: elem.getBoundingClientRect().top + elem.offsetHeight / 4
};
if (elemCenter.x < 0) return false;
if (elemCenter.x > (document.documentElement.clientWidth || window.innerWidth)) return false;
if (elemCenter.y < 0) return false;
if (elemCenter.y > (document.documentElement.clientHeight || window.innerHeight)) return false;
let pointContainer = document.elementFromPoint(elemCenter.x, elemCenter.y);
// @ts-ignore
do {
if (pointContainer === elem) return true;
} while (pointContainer && pointContainer === pointContainer.parentNode);

return false;
}

public static videoPlaying(el) {
return !!(el.currentTime > 0 && !el.paused && !el.ended && el.readyState > 2);
}

public static videoLoaded(el) {
return el.readyState === 4
}

public static addScrollListener() {
this.destroyScrollListener()

window.addEventListener("scroll", VideoViewer.handleRender);
}

public static destroyScrollListener() {
window.removeEventListener("scroll", VideoViewer.handleRender, false)
}

}
22 changes: 21 additions & 1 deletion frontend/src/views/Home.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import EqWindow from "@/components/eq-ui/EQWindow";
import UserContext from "@/app/user/UserContext";
import {SpireApiClient} from "../app/api/spire-api-client";
import * as util from "util";
import VideoViewer from "../app/video-viewer/video-viewer";
export default {
components: {
Expand Down Expand Up @@ -68,7 +69,7 @@ export default {
// replace markdown code for html
markdownRaw = markdownRaw.replace(
util.format("[![](https://img.youtube.com/vi/%s/0.jpg)](https://www.youtube.com/watch?v=%s)", videoCode, videoCode),
util.format('<div class="container"><iframe allow="autoplay" class="video" src="https://www.youtube.com/embed/%s?autoplay=1&mute=1&showinfo=0&controls=0&modestbranding=1&rel=0&loop=1&showsearch=0&iv_load_policy=3&playlist=%s" title="YouTube video player" frameborder="0" allowfullscreen></iframe></div>\n', videoCode, videoCode)
util.format('<div class="container"><iframe allow="autoplay" class="video" src="https://www.youtube.com/embed/%s?mute=1&showinfo=0&controls=0&modestbranding=1&rel=0&loop=1&showsearch=0&iv_load_policy=3&playlist=%s" title="YouTube video player" frameborder="0" allowfullscreen></iframe></div>\n', videoCode, videoCode)
)
// console.log("Video code is [%s]", videoCode)
Expand Down Expand Up @@ -120,6 +121,25 @@ export default {
}
})
// auto play videos that are in the viewport
window.addEventListener("scroll", this.handleRender);
setTimeout(() => {
this.handleRender()
}, 500)
},
methods: {
handleRender() {
let videos = document.getElementsByClassName("video");
for (let i = 0; i < videos.length; i++) {
let video = videos.item(i)
if (VideoViewer.elementInViewport(video) && !video.src.includes("autoplay")) {
video.src = video.src + "&autoplay=1"
}
}
}
},
deactivated() {
window.removeEventListener("scroll", this.handleRender, false)
}
}
</script>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
</template>

<script>
import ItemIcons from "@/app/asset-maps/item-icons-map.json";
import ItemIcons from "@/app/eq-assets/item-icons-map.json";
import util from "util";
import itemSlots from "@/constants/item-slots.json"
import itemTypes from "@/constants/item-types.json"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
</template>

<script>
import NpcModels from "@/app/asset-maps/npc-models-map";
import NpcModels from "@/app/eq-assets/npc-models-map";
import util from "util";
import {RACES} from "@/app/constants/eq-race-constants"
import PageHeader from "@/components/layout/PageHeader";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
</template>

<script>
import ItemModels from "@/app/asset-maps/objects-map.json";
import ItemModels from "@/app/eq-assets/objects-map.json";
import * as util from "util";
export default {
Expand Down
Loading

0 comments on commit d5b4016

Please sign in to comment.