diff --git a/pr-preview/pr-65/js/draw/add-box.js b/pr-preview/pr-65/js/draw/add-box.js deleted file mode 100644 index 768f5c5b..00000000 --- a/pr-preview/pr-65/js/draw/add-box.js +++ /dev/null @@ -1,11 +0,0 @@ -import { Graphics } from "../pixi.min.mjs"; -import { pixi } from "./app.js"; - -export function addBox(box) { - const { container } = pixi; - const boxGraphic = new Graphics(); - boxGraphic.rect(box.x, box.y, box.width, box.height); - boxGraphic.fill(box.color); - container.addChild(boxGraphic); - pixi.elements.push(boxGraphic); -} diff --git a/pr-preview/pr-65/js/draw/app.js b/pr-preview/pr-65/js/draw/app.js index bc146837..2f045b71 100644 --- a/pr-preview/pr-65/js/draw/app.js +++ b/pr-preview/pr-65/js/draw/app.js @@ -1,6 +1,11 @@ import { Application, Container } from "../pixi.min.mjs"; -export const pixi = { +const SPEED = 0.3; +const MARGIN = 100; + +const pixi = { + app: null, + container: null, elements: [], }; @@ -17,28 +22,38 @@ const createApp = async () => { return app; }; -const worldSize = 5000; - const addScroll = (app) => { - let x = 0; - let y = 0; + const container = pixi.container; + const renderer = app.renderer; - app.canvas.addEventListener("mousemove", (e) => { - x = e.clientX; - y = e.clientY; - }); + container.x = 0; + container.y = 0; + + const screenWidth = renderer.width; + const screenHeight = renderer.height; - const { container } = pixi; + app.canvas.addEventListener("wheel", (e) => { + const deltaX = parseInt(e.deltaX) * SPEED; + const deltaY = parseInt(e.deltaY) * SPEED; - app.ticker.add(() => { - const screenWidth = app.renderer.width; - const screenHeight = app.renderer.height; + const newXPosition = container.x - deltaX; + const newYPosition = container.y - deltaY; - const targetX = (x / screenWidth) * (worldSize - screenWidth); - const targetY = (y / screenHeight) * (worldSize - screenHeight); + const absXPosition = Math.abs(newXPosition); + const absYPosition = Math.abs(newYPosition); - container.x += (-targetX - container.x) * 0.1; - container.y += (-targetY - container.y) * 0.1; + const isXInBounds = + newXPosition < 0 && absXPosition + screenWidth < container.width + MARGIN; + const isYInBounds = + newYPosition < 0 && + absYPosition + screenHeight < container.height + MARGIN; + + if (isXInBounds) { + container.x = newXPosition; + } + if (isYInBounds) { + container.y = newYPosition; + } }); }; @@ -50,6 +65,24 @@ const createContainer = (app) => { app.stage.addChild(container); }; +export const setContainerSize = (width, height) => { + const container = getContainer(); + container.width = width; + container.height = height; +}; + +export const getApp = () => { + return pixi.app; +}; + +export const getContainer = () => { + return pixi.container; +}; + +export const getElements = () => { + return pixi.elements; +}; + export const startPixi = async () => { const app = await createApp(); createContainer(app); diff --git a/pr-preview/pr-65/js/draw/box.js b/pr-preview/pr-65/js/draw/box.js new file mode 100644 index 00000000..69603e57 --- /dev/null +++ b/pr-preview/pr-65/js/draw/box.js @@ -0,0 +1,75 @@ +import { Graphics, BitmapText, Assets } from "../pixi.min.mjs"; +import { getContainer, getElements } from "./app.js"; + +const TOP_MARGIN = 20; + +export function addBox(box) { + const elements = getElements(); + const container = getContainer(); + container.addChild(box); + elements.push(box); +} + +export function buildBox(object) { + const box = new Graphics(); + box.roundRect(object.x, object.y, object.width, object.height, object.radius); + box.fill(object.color); + box.stroke({ width: 2, color: "#000000" }); + return box; +} + +export function addTitleToBox(title, box) { + const boxTitle = new BitmapText({ + text: title, + style: { + fontFamiliy: "sans-serif", + fontSize: 16, + align: "center", + fill: "black", + fontWeight: "bold", + }, + }); + box.addChild(boxTitle); + boxTitle.y = box.y + TOP_MARGIN; + boxTitle.x = box.x + (box.width - boxTitle.width) / 2; + return boxTitle.y; +} + +export function addLinesToBox(lines, box, y) { + let prevY = y; + lines.forEach((line) => { + const boxLine = new BitmapText({ + text: line, + style: { + fontFamily: "sans-serif", + fontSize: 14, + align: "center", + fill: "black", + }, + }); + box.addChild(boxLine); + boxLine.y = prevY + 10; + boxLine.x = box.x + (box.width - boxLine.width) / 2; + prevY = boxLine.y + boxLine.height; + }); + + return prevY; +} + +export async function svgElementToPixiSprite(src) { + const sprite = await Assets.load({ + src, + data: { + parseAsGraphicsContext: true, + }, + }); + const graphics = new Graphics(sprite); + return graphics; +} + +export function addImageToBox(sprite, box, y) { + box.addChild(sprite); + sprite.y = y; + sprite.x = box.x + (box.width - sprite.width) / 2; + return sprite.y + sprite.height; +} diff --git a/pr-preview/pr-65/js/draw/scroll.js b/pr-preview/pr-65/js/draw/scroll.js new file mode 100644 index 00000000..5bcf6c5b --- /dev/null +++ b/pr-preview/pr-65/js/draw/scroll.js @@ -0,0 +1,22 @@ +import { getContainer, getApp } from "./app.js"; + +export const scrollTopLeft = () => { + const container = getContainer(); + container.x = 0; + container.y = 0; +}; + +export const scrollTopCenter = () => { + const container = getContainer(); + const app = getApp(); + + const screenWidth = app.renderer.width; + const containerWidth = container.width; + + const x = (screenWidth - containerWidth) / 2; + const y = 0; + container.x = x; + container.y = y; + + return { x, y }; +}; diff --git a/pr-preview/pr-65/js/lib/generate-svg.js b/pr-preview/pr-65/js/lib/generate-svg.js index 69773f1d..e0490f1b 100644 --- a/pr-preview/pr-65/js/lib/generate-svg.js +++ b/pr-preview/pr-65/js/lib/generate-svg.js @@ -1,4 +1,12 @@ -export async function textToSVGElement(text) { - const element = await MathJax.tex2svgPromise(text); - return element.firstElementChild; +export async function textToSVG(text) { + const svg = await MathJax.tex2svg(text).firstElementChild; + + const src = + "data:image/svg+xml;base64," + + btoa( + '\n' + + svg.outerHTML + ); + + return src; } diff --git a/pr-preview/pr-65/js/types/objects.js b/pr-preview/pr-65/js/types/objects.js index 95274b1e..133b6e51 100644 --- a/pr-preview/pr-65/js/types/objects.js +++ b/pr-preview/pr-65/js/types/objects.js @@ -2,8 +2,15 @@ import { getName } from "../lib/getName.js"; import { linkTypes } from "./links.js"; import { parseCharge } from "../lib/parseCharge.js"; import { getSimStatusDisplayValuesFromBit } from "../../mappings/sim-status.js"; -import { addBox } from "../draw/add-box.js"; -import { textToSVGElement } from "../lib/generate-svg.js"; +import { + buildBox, + addBox, + addTitleToBox, + addLinesToBox, + svgElementToPixiSprite, + addImageToBox, +} from "../draw/box.js"; +import { textToSVG } from "../lib/generate-svg.js"; const TOP_MARGIN = 45; @@ -20,7 +27,12 @@ class EDMObject { this.color = "white"; } - draw(app) {} + async draw() { + const box = buildBox(this); + const nextY = addTitleToBox(this.collectionName, box); + addBox(box); + return [box, nextY]; + } isHere(mouseX, mouseY) { return ( @@ -59,9 +71,21 @@ export class MCParticle extends EDMObject { } async draw() { - const boxCenterX = this.x + this.width / 2; + // const boxCenterX = this.x + this.width / 2; + // const topY = this.y + TOP_MARGIN; + + // const bottomY = this.y + this.height * 0.65; + // const bottomLines = []; + // bottomLines.push("p = " + this.momentum + " GeV"); + // bottomLines.push("d = " + this.vertex + " mm"); + // bottomLines.push("t = " + this.time + " ns"); + // bottomLines.push("m = " + this.mass + " GeV"); + // bottomLines.push(parseCharge(this.charge)); + // const svgElement = textToSVGElement(this.name); + // addBox(this); + + let [box, nextY] = await super.draw(); - const topY = this.y + TOP_MARGIN; const topLines = []; topLines.push("ID: " + this.index); topLines.push("Gen. stat.: " + this.generatorStatus); @@ -77,16 +101,10 @@ export class MCParticle extends EDMObject { : this.simulatorStatus; topLines.push("Sim. stat.: " + simulatorStatusString); - const bottomY = this.y + this.height * 0.65; - const bottomLines = []; - bottomLines.push("p = " + this.momentum + " GeV"); - bottomLines.push("d = " + this.vertex + " mm"); - bottomLines.push("t = " + this.time + " ns"); - bottomLines.push("m = " + this.mass + " GeV"); - bottomLines.push(parseCharge(this.charge)); - - const svgElement = textToSVGElement(this.name); - addBox(this); + nextY = addLinesToBox(topLines, box, nextY); + const svg = await textToSVG(this.name); + const sprite = await svgElementToPixiSprite(svg); + nextY = addImageToBox(sprite, box, nextY); } showObjectTip(ctx) { diff --git a/pr-preview/pr-65/js/views/mcparticletree.js b/pr-preview/pr-65/js/views/mcparticletree.js index c42c795a..20952f66 100644 --- a/pr-preview/pr-65/js/views/mcparticletree.js +++ b/pr-preview/pr-65/js/views/mcparticletree.js @@ -92,6 +92,8 @@ export function mcParticleTree(viewCurrentObjects) { box.y = i * verticalGap + verticalGap + i * boxHeight; } } + + return [width, height]; } export function preFilterMCTree(currentObjects, viewObjects) { diff --git a/pr-preview/pr-65/js/views/scrolls.js b/pr-preview/pr-65/js/views/scrolls.js deleted file mode 100644 index 48e392cf..00000000 --- a/pr-preview/pr-65/js/views/scrolls.js +++ /dev/null @@ -1,9 +0,0 @@ -export function scrollTopCenter() { - const canvas = document.querySelector("canvas"); - const x = canvas.width / 2; - return { x, y: 0 }; -} - -export function scrollTopLeft() { - return { x: 0, y: 0 }; -} diff --git a/pr-preview/pr-65/js/views/views-dictionary.js b/pr-preview/pr-65/js/views/views-dictionary.js index 894b8e14..833e3f3d 100644 --- a/pr-preview/pr-65/js/views/views-dictionary.js +++ b/pr-preview/pr-65/js/views/views-dictionary.js @@ -4,7 +4,6 @@ import { recoParticleTree, preFilterRecoTree } from "./recoparticletree.js"; import { setupMCParticleFilter } from "../filter/mcparticle.js"; import { trackTree, preFilterTrackTree } from "./tracktree.js"; import { clusterTree, preFilterClusterTree } from "./clustertree.js"; -import { scrollTopCenter, scrollTopLeft } from "./scrolls.js"; import { preFilterMCTrack, mcTrackAssociation } from "./mctrackassociation.js"; import { preFilterMCCluster, @@ -19,6 +18,7 @@ import { vertexList, preFilterVertexList } from "./vertexlist.js"; import { particleIDList, preFilterParticleIDList } from "./particleidlist.js"; import { recoParticleID, preFilterRecoParticleID } from "./recoparticleid.js"; import { spanWithColor } from "../lib/html-string.js"; +import { scrollTopCenter } from "../draw/scroll.js"; export const views = { "Monte Carlo Particle Tree": { @@ -37,7 +37,7 @@ export const views = { "Reconstructed Particle Tree": { filters: setupNoFilter, viewFunction: recoParticleTree, - scrollFunction: scrollTopLeft, + scrollFunction: null, preFilterFunction: preFilterRecoTree, description: `
A tree of the Reconstructed Particles. ${spanWithColor( "Purple", @@ -47,21 +47,21 @@ export const views = { "Track Tree": { filters: setupNoFilter, viewFunction: trackTree, - scrollFunction: scrollTopLeft, + scrollFunction: null, preFilterFunction: preFilterTrackTree, description: `
A tree of the Tracks.
`, }, "Cluster Tree": { filters: setupNoFilter, viewFunction: clusterTree, - scrollFunction: scrollTopLeft, + scrollFunction: null, preFilterFunction: preFilterClusterTree, description: `A tree of the Clusters.
`, }, "RecoParticle-Cluster-Track-Vertex": { filters: setupNoFilter, viewFunction: recoClusterTrackVertex, - scrollFunction: scrollTopCenter, + scrollFunction: null, preFilterFunction: preFilterRecoClusterTrackVertex, description: `Relations that a Reconstruced Particle has with other objects. ${spanWithColor( "Green", @@ -74,42 +74,42 @@ export const views = { "Monte Carlo-Reconstructed Particle": { filters: setupNoFilter, viewFunction: mcRecoAssociation, - scrollFunction: scrollTopCenter, + scrollFunction: null, preFilterFunction: preFilterMCReco, description: `
Association between Monte Carlo Particles and Reconstructed Particles. 1:1 relation.
`, }, "Monte Carlo Particle-Track": { filters: setupNoFilter, viewFunction: mcTrackAssociation, - scrollFunction: scrollTopCenter, + scrollFunction: null, preFilterFunction: preFilterMCTrack, description: `Association between Monte Carlo Particles and Tracks. 1:1 relation.
`, }, "Monte Carlo Particle-Cluster": { filters: setupNoFilter, viewFunction: mcClusterAssociation, - scrollFunction: scrollTopCenter, + scrollFunction: null, preFilterFunction: preFilterMCCluster, description: `Association between Monte Carlo Particles and Clusters. 1:1 relation.
`, }, "ParticleID List": { filters: setupNoFilter, viewFunction: particleIDList, - scrollFunction: scrollTopLeft, + scrollFunction: null, preFilterFunction: preFilterParticleIDList, description: `A list of ParticleIDs found in the event.
`, }, "Vertex List": { filters: setupNoFilter, viewFunction: vertexList, - scrollFunction: scrollTopLeft, + scrollFunction: null, preFilterFunction: preFilterVertexList, description: `A list of Vertices found in the event.
`, }, "ParticleID-Reconstructed Particle": { filters: setupNoFilter, viewFunction: recoParticleID, - scrollFunction: scrollTopCenter, + scrollFunction: null, preFilterFunction: preFilterRecoParticleID, description: `1:1 relation from ParticleID to Reconstructed Particle.
`, }, diff --git a/pr-preview/pr-65/js/views/views.js b/pr-preview/pr-65/js/views/views.js index 936cd266..ee9c9efd 100644 --- a/pr-preview/pr-65/js/views/views.js +++ b/pr-preview/pr-65/js/views/views.js @@ -5,6 +5,7 @@ import { views } from "./views-dictionary.js"; import { emptyViewMessage, hideEmptyViewMessage } from "../lib/messages.js"; import { showViewInformation, hideViewInformation } from "../information.js"; import { renderObjects } from "../draw/render.js"; +import { setContainerSize } from "../draw/app.js"; const currentView = {}; @@ -60,19 +61,20 @@ const drawView = async (view) => { } showViewInformation(view, description); hideEmptyViewMessage(); - viewFunction(viewObjects); + const [width, height] = viewFunction(viewObjects); + setContainerSize(width, height); copyObject(viewObjects, viewCurrentObjects); - const scrollIndex = getViewScrollIndex(); + // const scrollIndex = getViewScrollIndex(); - if (scrollLocations[scrollIndex] === undefined) { - const viewScrollLocation = scrollFunction(); - scrollLocations[scrollIndex] = viewScrollLocation; - } + // if (scrollLocations[scrollIndex] === undefined) { + // const viewScrollLocation = scrollFunction(); + // scrollLocations[scrollIndex] = viewScrollLocation; + // } - scroll(); await renderObjects(viewObjects); setInfoButtonName(getView()); + scrollFunction(); // filters(viewObjects, viewCurrentObjects, viewVisibleObjects); };