mirror of
https://gitlab.com/lecarore/breakout71.git
synced 2025-04-23 21:46:15 -04:00
Build 29058459
This commit is contained in:
parent
b19cc5c0b4
commit
de99dd9ba8
17 changed files with 160 additions and 147 deletions
|
@ -1,5 +1,5 @@
|
|||
// The version of the cache.
|
||||
const VERSION = "29057568";
|
||||
const VERSION = "29058459";
|
||||
|
||||
// The name of the cache
|
||||
const CACHE_NAME = `breakout-71-${VERSION}`;
|
||||
|
|
|
@ -105,7 +105,8 @@ export async function asyncAlert<t>({
|
|||
help,
|
||||
disabled,
|
||||
className = "",
|
||||
icon = "",tooltip,
|
||||
icon = "",
|
||||
tooltip,
|
||||
} = entry;
|
||||
|
||||
const button = document.createElement("button");
|
||||
|
@ -117,8 +118,8 @@ ${icon}
|
|||
<em>${help || ""}</em>
|
||||
</div>`;
|
||||
|
||||
if(tooltip){
|
||||
button.setAttribute('data-tooltip',tooltip)
|
||||
if (tooltip) {
|
||||
button.setAttribute("data-tooltip", tooltip);
|
||||
}
|
||||
if (disabled) {
|
||||
button.setAttribute("disabled", "disabled");
|
||||
|
@ -165,4 +166,3 @@ function updateAlertsOpen(delta: number) {
|
|||
}
|
||||
document.body.classList[alertsOpen ? "add" : "remove"]("has-alert-open");
|
||||
}
|
||||
|
||||
|
|
|
@ -4,15 +4,17 @@ import { t } from "./i18n/i18n";
|
|||
import { getSettingValue, getTotalScore, setSettingValue } from "./settings";
|
||||
import { confirmRestart, creativeModeThreshold, restart } from "./game";
|
||||
import { asyncAlert, requiredAsyncAlert } from "./asyncAlert";
|
||||
import {describeLevel, highScoreForMode} from "./game_utils";
|
||||
import { describeLevel, highScoreForMode } from "./game_utils";
|
||||
|
||||
export function creativeMode(gameState: GameState) {
|
||||
return {
|
||||
icon: icons["icon:sandbox"],
|
||||
text: t("lab.menu_entry"),
|
||||
help: highScoreForMode('creative')||(
|
||||
getTotalScore() < creativeModeThreshold && t("lab.unlocks_at", { score: creativeModeThreshold })) ||
|
||||
t("lab.help"),
|
||||
help:
|
||||
highScoreForMode("creative") ||
|
||||
(getTotalScore() < creativeModeThreshold &&
|
||||
t("lab.unlocks_at", { score: creativeModeThreshold })) ||
|
||||
t("lab.help"),
|
||||
disabled: getTotalScore() < creativeModeThreshold,
|
||||
async value() {
|
||||
if (await confirmRestart(gameState)) {
|
||||
|
@ -68,14 +70,14 @@ export async function openCreativeModePerksPicker(
|
|||
className: creativeModePerks[u.id]
|
||||
? "sandbox"
|
||||
: "sandbox grey-out-unless-hovered",
|
||||
tooltip: u.help(creativeModePerks[u.id]||1)
|
||||
tooltip: u.help(creativeModePerks[u.id] || 1),
|
||||
})),
|
||||
t("lab.select_level"),
|
||||
...allLevels.map((l) => ({
|
||||
icon: icons[l.name],
|
||||
text: l.name,
|
||||
value: l,
|
||||
tooltip:describeLevel(l)
|
||||
tooltip: describeLevel(l),
|
||||
})),
|
||||
],
|
||||
}))
|
||||
|
@ -95,5 +97,3 @@ export async function openCreativeModePerksPicker(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1108,4 +1108,4 @@
|
|||
"color": "",
|
||||
"credit": "https://prohama.com/balloon-1/"
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
|
@ -1 +1 @@
|
|||
"29057568"
|
||||
"29058459"
|
||||
|
|
|
@ -184,12 +184,14 @@ body:not(.has-alert-open) #popup {
|
|||
&.actionsAsGrid > div {
|
||||
max-width: none;
|
||||
|
||||
&>div,&>p,&>h1,&>h2{
|
||||
& > div,
|
||||
& > p,
|
||||
& > h1,
|
||||
& > h2 {
|
||||
width: 100%;
|
||||
max-width: 550px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
|
||||
}
|
||||
section {
|
||||
display: grid;
|
||||
|
@ -423,13 +425,13 @@ h2.histogram-title strong {
|
|||
|
||||
#tooltip {
|
||||
display: block;
|
||||
position:fixed;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top:0;
|
||||
background:black;
|
||||
color:white;
|
||||
padding:10px;
|
||||
z-index:11;
|
||||
top: 0;
|
||||
background: black;
|
||||
color: white;
|
||||
padding: 10px;
|
||||
z-index: 11;
|
||||
|
||||
border-radius: 2px;
|
||||
pointer-events: none;
|
||||
|
@ -437,4 +439,4 @@ h2.histogram-title strong {
|
|||
opacity: 1;
|
||||
border: 1px solid white;
|
||||
max-width: 300px;
|
||||
}
|
||||
}
|
||||
|
|
39
src/game.ts
39
src/game.ts
|
@ -13,8 +13,10 @@ import {
|
|||
} from "./types";
|
||||
import { getAudioContext, playPendingSounds } from "./sounds";
|
||||
import {
|
||||
currentLevelInfo, describeLevel,
|
||||
getRowColIndex, highScoreForMode,
|
||||
currentLevelInfo,
|
||||
describeLevel,
|
||||
getRowColIndex,
|
||||
highScoreForMode,
|
||||
levelsListHTMl,
|
||||
max_levels,
|
||||
pickedUpgradesHTMl,
|
||||
|
@ -65,7 +67,7 @@ import { hashCode } from "./getLevelBackground";
|
|||
import { hoursSpentPlaying } from "./pure_functions";
|
||||
import { helpMenuEntry } from "./help";
|
||||
import { creativeMode } from "./creative";
|
||||
import {setupTooltips} from "./tooltip";
|
||||
import { setupTooltips } from "./tooltip";
|
||||
|
||||
export function play() {
|
||||
if (applyFullScreenChoice()) return;
|
||||
|
@ -471,16 +473,14 @@ export const creativeModeThreshold = Math.max(
|
|||
...upgrades.map((u) => u.threshold),
|
||||
);
|
||||
|
||||
|
||||
export async function openMainMenu() {
|
||||
pause(true);
|
||||
|
||||
|
||||
const actions: AsyncAlertAction<() => void>[] = [
|
||||
{
|
||||
icon: icons["icon:7_levels_run"],
|
||||
text: t("main_menu.normal"),
|
||||
help: highScoreForMode('short')||t("main_menu.normal_help"),
|
||||
help: highScoreForMode("short") || t("main_menu.normal_help"),
|
||||
value: () => {
|
||||
restart({
|
||||
levelToAvoid: currentLevelInfo(gameState).name,
|
||||
|
@ -490,12 +490,12 @@ export async function openMainMenu() {
|
|||
},
|
||||
{
|
||||
icon: icons["icon:loop"],
|
||||
text: t("main_menu.loop_run"),
|
||||
help:highScoreForMode('long')||
|
||||
|
||||
(getTotalScore() < creativeModeThreshold && t("lab.unlocks_at", { score: creativeModeThreshold })) ||
|
||||
|
||||
t("main_menu.loop_run_help"),
|
||||
text: t("main_menu.loop_run"),
|
||||
help:
|
||||
highScoreForMode("long") ||
|
||||
(getTotalScore() < creativeModeThreshold &&
|
||||
t("lab.unlocks_at", { score: creativeModeThreshold })) ||
|
||||
t("main_menu.loop_run_help"),
|
||||
|
||||
value: () => {
|
||||
restart({
|
||||
|
@ -831,8 +831,7 @@ async function openUnlocksList() {
|
|||
disabled: ts < threshold,
|
||||
value: { perks: { [id]: 1 } } as RunParams,
|
||||
icon,
|
||||
tooltip:help(1)
|
||||
|
||||
tooltip: help(1),
|
||||
}));
|
||||
|
||||
const levelActions = allLevels
|
||||
|
@ -844,7 +843,7 @@ async function openUnlocksList() {
|
|||
disabled: !available,
|
||||
value: { level: l.name } as RunParams,
|
||||
icon: icons[l.name],
|
||||
tooltip:describeLevel(l)
|
||||
tooltip: describeLevel(l),
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -998,6 +997,10 @@ restart(
|
|||
);
|
||||
|
||||
tick();
|
||||
setupTooltips()
|
||||
document.getElementById('menu')?.setAttribute('data-tooltip', t('play.menu_tooltip'))
|
||||
document.getElementById('score')?.setAttribute('data-tooltip', t('play.score_tooltip'))
|
||||
setupTooltips();
|
||||
document
|
||||
.getElementById("menu")
|
||||
?.setAttribute("data-tooltip", t("play.menu_tooltip"));
|
||||
document
|
||||
.getElementById("score")
|
||||
?.setAttribute("data-tooltip", t("play.score_tooltip"));
|
||||
|
|
|
@ -551,7 +551,6 @@ export function schedulGameSound(
|
|||
ex.vol += vol;
|
||||
}
|
||||
|
||||
|
||||
export function addToScore(gameState: GameState, coin: Coin) {
|
||||
gameState.score += coin.points;
|
||||
gameState.lastScoreIncrease = gameState.levelTime;
|
||||
|
@ -1488,7 +1487,7 @@ export function ballTick(gameState: GameState, ball: Ball, delta: number) {
|
|||
if (gameState.perks.top_is_lava && borderHitCode >= 2) {
|
||||
resetCombo(gameState, ball.x, ball.y + gameState.ballSize);
|
||||
}
|
||||
if (gameState.perks.trampoline ) {
|
||||
if (gameState.perks.trampoline) {
|
||||
decreaseCombo(
|
||||
gameState,
|
||||
gameState.perks.trampoline,
|
||||
|
|
|
@ -1,26 +1,27 @@
|
|||
import {Ball, GameState, Level, PerkId, PerksMap} from "./types";
|
||||
import { Ball, GameState, Level, PerkId, PerksMap } from "./types";
|
||||
import { icons, upgrades } from "./loadGameData";
|
||||
import { t } from "./i18n/i18n";
|
||||
|
||||
export function describeLevel(level:Level){
|
||||
let bricks=0, colors=new Set(), bombs=0;
|
||||
level.bricks.forEach(color=>{
|
||||
if(!color) return
|
||||
if(color==='black') {
|
||||
bombs++
|
||||
export function describeLevel(level: Level) {
|
||||
let bricks = 0,
|
||||
colors = new Set(),
|
||||
bombs = 0;
|
||||
level.bricks.forEach((color) => {
|
||||
if (!color) return;
|
||||
if (color === "black") {
|
||||
bombs++;
|
||||
return;
|
||||
} else {
|
||||
colors.add(color);
|
||||
bricks++;
|
||||
}
|
||||
else {
|
||||
colors.add(color)
|
||||
bricks++
|
||||
}
|
||||
})
|
||||
return t('unlocks.level_description',{
|
||||
size:level.size,
|
||||
});
|
||||
return t("unlocks.level_description", {
|
||||
size: level.size,
|
||||
bricks,
|
||||
colors:colors.size,
|
||||
bombs
|
||||
})
|
||||
colors: colors.size,
|
||||
bombs,
|
||||
});
|
||||
}
|
||||
|
||||
export function getMajorityValue(arr: string[]): string {
|
||||
|
@ -227,17 +228,15 @@ export function countBricksBelow(gameState: GameState, index: number) {
|
|||
}
|
||||
return count;
|
||||
}
|
||||
export function highScoreForMode(mode:GameState['mode']){
|
||||
try{
|
||||
const score = parseInt(localStorage.getItem(
|
||||
"breakout-3-hs-" + mode,
|
||||
|
||||
)||"0")
|
||||
if(score){
|
||||
return t('main_menu.high_score',{score})
|
||||
export function highScoreForMode(mode: GameState["mode"]) {
|
||||
try {
|
||||
const score = parseInt(
|
||||
localStorage.getItem("breakout-3-hs-" + mode) || "0",
|
||||
);
|
||||
if (score) {
|
||||
return t("main_menu.high_score", { score });
|
||||
}
|
||||
}catch (e){
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
return''
|
||||
return "";
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@
|
|||
"main_menu.mobile": "Mobile mode",
|
||||
"main_menu.mobile_help": "Leaves space under the puck.",
|
||||
"main_menu.normal": "New short game",
|
||||
"main_menu.normal_help": "Start a quick game with random starting perk",
|
||||
"main_menu.normal_help": "Play 7 levels with a random starting perk",
|
||||
"main_menu.pointer_lock": "Mouse pointer lock",
|
||||
"main_menu.pointer_lock_help": "Locks and hides the mouse cursor.",
|
||||
"main_menu.record": "Record gameplay videos",
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
"main_menu.footer_html": " <p> \n<span>Programmé en France par <a href=\"https://lecaro.me\">Renan LE CARO</a>.</span>\n<a href=\"https://paypal.me/renanlecaro\" target=\"_blank\">Donner</a>\n<a href=\"https://discord.gg/bbcQw4x5zA\" target=\"_blank\">Discord</a>\n<a href=\"https://f-droid.org/en/packages/me.lecaro.breakout/\" target=\"_blank\">F-Droid</a>\n<a href=\"https://play.google.com/store/apps/details?id=me.lecaro.breakout\" target=\"_blank\">Google Play</a>\n<a href=\"https://renanlecaro.itch.io/breakout71\" target=\"_blank\">itch.io</a>\n<a href=\"https://gitlab.com/lecarore/breakout71\" target=\"_blank\">Gitlab</a>\n<a href=\"https://breakout.lecaro.me/\" target=\"_blank\">Version web</a>\n<a href=\"https://news.ycombinator.com/item?id=43183131\" target=\"_blank\">HackerNews</a>\n<a href=\"https://breakout.lecaro.me/privacy.html\" target=\"_blank\">Politique de confidentialité</a> \n<span>v.{{appVersion}}</span>\n</p>",
|
||||
"main_menu.fullscreen": "Plein écran",
|
||||
"main_menu.fullscreen_help": "Le jeu essaiera de passer en plein écran quand vous le démarrez",
|
||||
"main_menu.help_content": "# Objectif\n\nLe but est d'attraper un maximum de pièces au cours des 7 niveaux.\nLes pièces apparaissent lorsque vous cassez des briques.\nElles volent, rebondissent et roulent, et vous devez les attraper avec votre palet pour augmenter votre score.\nVotre score est affiché en haut à droite de l'écran.\nVous devez supprimer toutes les briques pour passer au niveau suivant.\nSi vous laissez tomber la balle, la partie est terminée, sauf si vous aviez l'amélioration « Vie supplémentaire ».\n\n# Améliorations\n\nAprès avoir terminé un niveau, vous pourrez choisir des améliorations parmi une petite sélection qui vous sera présentée.\nL'amélioration choisie sera valable jusqu'à la fin de la partie. Vous aurez plus de choix d'améliorations, et même la possibilité d'en choisir plusieurs à la fin du niveau si vous jouez bien : attrapez toutes les pièces, terminez le niveau rapidement et ne ratez jamais votre cible.\nVous obtenez également une amélioration aléatoire gratuite au début de chaque partie. Vous pouvez voir vos améliorations (et quelques détails supplémentaires) en cliquant sur votre score en haut à droite de l'écran.\n\nLes améliorations s'appliquent à l'ensemble de la partie et peuvent être synergiques. Par exemple, si vous combinez « sapeur » et « perforant », la première brique que vous touchez après un rebond de palet se transformera immédiatement en brique explosive et explosera avec la même balle, vous donnant ainsi une balle explosive.\n\nCertaines améliorations facilitent la visée, comme les « balles de contrôle de palet ». Certaines améliorations peuvent être sélectionnées plusieurs fois pour augmenter leur effet. Par exemple, « +1 balle niveau 2 » ajoute une troisième balle.\n\nLors de votre première partie, seules quelques améliorations sont disponibles ; vous débloquez les autres en jouant et en marquant des points. Un mécanisme similaire s'applique au déblocage des niveaux. À la fin d'une partie, les éléments que vous venez de débloquer seront affichés et vous pourrez consulter leur contenu complet dans le menu / Déblocages.\n\nDe nombreuses améliorations influencent votre combo.\n\n# Combo\n\nVotre « combo » correspond au nombre de pièces générées lorsqu'une brique se brise. L'affichage est sur votre palet. Par exemple, x4 signifie que chaque brique rapporte 4 pièces. Le jeu se réinitialise si vous ratez votre tentative.\n\n# Configuration requise\n\nBreakout 71 peut fonctionner hors ligne (ajoutez-le à l'écran d'accueil) et fonctionne bien même sur les appareils bas de gamme.\nL'application est très simple et occupe peu d'espace de stockage (environ 0,1 Mo).\nSi l'application est instable, activez le « mode rapide » dans les paramètres pour afficher une vue simplifiée et plus rapide. Il existe également un mode facile pour les enfants (balle plus lente).\n\n# Boucle\n\nUne fois toutes les améliorations débloquées, vous aurez la possibilité de jouer une partie plus longue.\nDans ce mode, vous pouvez boucler le jeu jusqu'à 7 fois après votre première tentative.\n\nChaque boucle est plus courte et vous ne pouvez pas utiliser les niveaux d'avantages utilisés dans les niveaux précédents, à l'exception d'un avantage que vous pouvez améliorer continuellement. Si vous épuisez complètement un avantage, il ne sera plus proposé dans les boucles suivantes. L'avantage que vous améliorez gagne instantanément +1 niveau et +2 niveaux max.\nChaque boucle est plus courte d'un niveau. La balle démarre légèrement plus vite.\nLa partie se termine lorsque vous perdez le ballon ou terminez la 7e boucle.\n\n# Visée\n\nSeule la position du palet frappé détermine la trajectoire du ballon. Si le ballon touche le palet en plein centre, il rebondira verticalement, tandis que si vous frappez davantage d'un côté, l'angle sera plus grand.\nLa vitesse du palet et l'angle d'arrivée n'ont aucun impact sur la direction du ballon après le rebond.\n\nUn palet plus petit facilitera peut-être la visée près des coins, mais rendra aussi beaucoup plus difficile la capture de pièces.\nLes options « Vent » et « Palet contrôle le ballon » peuvent vous aider à viser même après un rebond dans la mauvaise direction.\n« Balle plus lente » vous donne un peu plus de temps pour viser, ce qui est particulièrement utile dans les niveaux avancés où la balle va plus vite. La balle accélère également à mesure que vous progressez dans chaque niveau.",
|
||||
"main_menu.help_content": "# Objectif\n\nLe but est d'attraper un maximum de pièces au cours des 7 niveaux.\nLes pièces apparaissent lorsque vous cassez des briques.\nElles volent, rebondissent et roulent, et vous devez les attraper avec votre palet pour augmenter votre score.\nVotre score est affiché en haut à droite de l'écran.\nVous devez supprimer toutes les briques pour passer au niveau suivant.\nSi vous laissez tomber la balle, la partie est terminée, sauf si vous aviez l'amélioration « Vie supplémentaire ».\n\n# Améliorations\n\nAprès avoir terminé un niveau, vous pourrez choisir des améliorations parmi une petite sélection qui vous sera présentée.\nL'amélioration choisie sera valable jusqu'à la fin de la partie. Vous aurez plus de choix d'améliorations, et même la possibilité d'en choisir plusieurs à la fin du niveau si vous jouez bien : attrapez toutes les pièces, terminez le niveau rapidement et ne ratez jamais votre cible.\nVous obtenez également une amélioration aléatoire gratuite au début de chaque partie. Vous pouvez voir vos améliorations (et quelques détails supplémentaires) en cliquant sur votre score en haut à droite de l'écran.\n\nLes améliorations s'appliquent à l'ensemble de la partie et peuvent être synergiques. Par exemple, si vous combinez « sapeur » et « perforant », la première brique que vous touchez après un rebond de palet se transformera immédiatement en brique explosive et explosera avec la même balle, vous donnant ainsi une balle explosive.\n\nCertaines améliorations facilitent la visée, comme les « balles de contrôle de palet ». Certaines améliorations peuvent être sélectionnées plusieurs fois pour augmenter leur effet. Par exemple, « +1 balle niveau 2 » ajoute une troisième balle.\n\nLors de votre première partie, seules quelques améliorations sont disponibles ; vous débloquez les autres en jouant et en marquant des points. Un mécanisme similaire s'applique au déblocage des niveaux. À la fin d'une partie, les éléments que vous venez de débloquer seront affichés et vous pourrez consulter leur contenu complet dans le menu / Déblocages.\n\nDe nombreuses améliorations influencent votre combo.\n\n# Combo\n\nVotre « combo » correspond au nombre de pièces générées lorsqu'une brique se brise. L'affichage est sur votre palet. Par exemple, x4 signifie que chaque brique rapporte 4 pièces. Le jeu se réinitialise si vous ratez votre tentative.\n\n# Configuration requise\n\nBreakout 71 peut fonctionner hors ligne (ajoutez-le à l'écran d'accueil) et fonctionne bien même sur les appareils bas de gamme.\nL'application est très simple et occupe peu d'espace de stockage (environ 0,1 Mo).\nSi l'application est instable, activez le « mode rapide » dans les paramètres pour afficher une vue simplifiée et plus rapide. Il existe également un mode facile pour les enfants (balle plus lente).\n\n# Boucle\n\nUne fois toutes les améliorations débloquées, vous aurez la possibilité de jouer une partie plus longue.\nDans ce mode, vous pouvez boucler le jeu jusqu'à 7 fois après votre première tentative.\n\nChaque boucle est plus courte et vous ne pouvez pas utiliser les niveaux d'avantages utilisés dans les niveaux précédents, à l'exception d'un avantage que vous pouvez améliorer continuellement. Si vous épuisez complètement un avantage, il ne sera plus proposé dans les boucles suivantes. L'avantage que vous améliorez gagne instantanément +1 niveau et +2 niveaux max.\n\nChaque boucle est plus courte d'un niveau. La balle démarre légèrement plus vite. La partie se termine lorsque vous perdez le ballon ou terminez la 7e boucle.\n\n# Visée\n\nSeule la position du palet frappé détermine la trajectoire du ballon. Si le ballon touche le palet en plein centre, il rebondira verticalement, tandis que si vous frappez davantage d'un côté, l'angle sera plus grand.\nLa vitesse du palet et l'angle d'arrivée n'ont aucun impact sur la direction du ballon après le rebond.\n\nUn palet plus petit facilitera peut-être la visée près des coins, mais rendra aussi beaucoup plus difficile la capture de pièces.\nLes options « Vent » et « Télékinesis » peuvent vous aider à viser même après un rebond dans la mauvaise direction.\n« Balle plus lente » vous donne un peu plus de temps pour viser, ce qui est particulièrement utile dans les niveaux avancés où la balle va plus vite. La balle accélère également à mesure que vous progressez dans chaque niveau.",
|
||||
"main_menu.help_help": "Découvrez le jeu en détail",
|
||||
"main_menu.help_title": "Aide et crédits",
|
||||
"main_menu.help_upgrades": "<h2>Améliorations</h2>",
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
<div id="popup">
|
||||
<button id="close-modale"></button>
|
||||
</div>
|
||||
<div id="tooltip" style="display: none"> </div>
|
||||
<div id="tooltip" style="display: none"></div>
|
||||
<script type="module">
|
||||
import "./game.ts";
|
||||
</script>
|
||||
|
|
|
@ -1,39 +1,49 @@
|
|||
import {isOptionOn} from "./options";
|
||||
import { isOptionOn } from "./options";
|
||||
|
||||
export function setupTooltips() {
|
||||
const tooltip = document.getElementById('tooltip') as HTMLDivElement
|
||||
if (isOptionOn('mobile-mode')) {
|
||||
tooltip.style.display = 'none';
|
||||
return
|
||||
}
|
||||
const tooltip = document.getElementById("tooltip") as HTMLDivElement;
|
||||
if (isOptionOn("mobile-mode")) {
|
||||
tooltip.style.display = "none";
|
||||
return;
|
||||
}
|
||||
|
||||
function updateTooltipPosition(e:MouseEvent){
|
||||
tooltip.style.transform=`translate(${e.clientX}px,${e.clientY + 20}px) `+(e.clientX > window.innerWidth / 2 ? ' translate(-100%,0)':'')
|
||||
}
|
||||
|
||||
document.body.addEventListener('mouseenter', (e:MouseEvent) => {
|
||||
let parent: HTMLElement | null = e.target as HTMLElement
|
||||
while (parent && !parent.hasAttribute('data-tooltip')) {
|
||||
parent = parent.parentElement
|
||||
}
|
||||
if (parent?.hasAttribute('data-tooltip')) {
|
||||
tooltip.innerHTML = parent?.getAttribute('data-tooltip')
|
||||
tooltip.style.display = '';
|
||||
updateTooltipPosition(e)
|
||||
}else{
|
||||
|
||||
tooltip.style.display = 'none';
|
||||
}
|
||||
}, true)
|
||||
document.body.addEventListener('mousemove', e => {
|
||||
if (!tooltip.style.display) {
|
||||
updateTooltipPosition(e)
|
||||
}
|
||||
}, true)
|
||||
document.body.addEventListener('mouseleave', e => {
|
||||
// tooltip.style.display = 'none';
|
||||
}, true)
|
||||
function updateTooltipPosition(e: MouseEvent) {
|
||||
tooltip.style.transform =
|
||||
`translate(${e.clientX}px,${e.clientY + 20}px) ` +
|
||||
(e.clientX > window.innerWidth / 2 ? " translate(-100%,0)" : "");
|
||||
}
|
||||
|
||||
document.body.addEventListener(
|
||||
"mouseenter",
|
||||
(e: MouseEvent) => {
|
||||
let parent: HTMLElement | null = e.target as HTMLElement;
|
||||
while (parent && !parent.hasAttribute("data-tooltip")) {
|
||||
parent = parent.parentElement;
|
||||
}
|
||||
if (parent?.hasAttribute("data-tooltip")) {
|
||||
tooltip.innerHTML = parent?.getAttribute("data-tooltip");
|
||||
tooltip.style.display = "";
|
||||
updateTooltipPosition(e);
|
||||
} else {
|
||||
tooltip.style.display = "none";
|
||||
}
|
||||
},
|
||||
true,
|
||||
);
|
||||
document.body.addEventListener(
|
||||
"mousemove",
|
||||
(e) => {
|
||||
if (!tooltip.style.display) {
|
||||
updateTooltipPosition(e);
|
||||
}
|
||||
},
|
||||
true,
|
||||
);
|
||||
document.body.addEventListener(
|
||||
"mouseleave",
|
||||
(e) => {
|
||||
// tooltip.style.display = 'none';
|
||||
},
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue