Pour écouter un click hors d'un élément, on utilise l'event delegation: on vérifie si la target de l'event correspond ou pas à l'objet qu'on veut.
document.addEventListener('click', e => {
if (!element.contains(e.target)) callback();
});
};
onClickOutside('#my-element', () => console.log('Hello'));
// Will log 'Hello' whenever the user clicks outside of #my-element
Tiens, je ne savais pas qu'addEventListener acceptait des paramètres en option, en particulier un { once : true} qui permet de n'exécuter la fonction attachée à l'évènement qu'une seule fois...
const listenOnce = (el, evt, fn) =>
el.addEventListener(evt, fn, { once: true });
listenOnce(
document.getElementById('my-btn'),
'click',
() => console.log('Hello!')
); // 'Hello!' will only be logged on the first click
Bon, c'est un fait, envoyer des fichiers sur toute machine de son réseau quel que soit son OS, c'est chiant... il y a bien KDE Connect et Warpinator... Mais c'est pas toujours foufou - et je suis un fervent adorateur de KDE Connect.
Déjà, c'est opensource et dispo sur Fdroid pour Android avec une version .deb/appimage... 👍
Localsend, qui se veut l'équivalent d'airdrop sur les machines à la pomme pour les poires (#payeTonTrollGratuit), semble une bonne alternative.
OnnxStream can run SDXL 1.0 in less than 300MB of RAM and therefore is able to run it comfortably on a RPI Zero 2, without adding more swap space and without writing anything to disk during inference. Generating a 10-steps image takes about 11 hours on my RPI Zero 2.
La génération d'une image 1024x1024 prend ... 11 heures.
Et là, c'est pour la laïcité à l'école ?! ha, non, dans le sport quand on est représentant de la fRance. pfff...
I have a dream: ces concitoyennes françaises vont concourir pour un autre pays et elles gagnent les médailles d'or au détriment de la fRance... façon Mitra Hejazipour, cette championne d'échecs iranienne exclue de la compet en Iran pour avoir refusé de porter le hidjab et venue s'inscrire en france.
Des femmes, des championnes, exclues simplement parce qu'on refuse de les laisser s'habiller comme elles le souhaitent. Au moins, l'iran ne se cache pas derrière une prétendue laïcité pour ça.
(oui, je suis colère)
Oblivion remaster : ils se sont rendu compte que le cadavre de Skyrim était froid, il font maintenant de la nécromancie avec celui d'Oblivion. C'est sale Bethesda, c'est très sale.
Pitin, ce que j'ai ri ! C'est tellement ça: de la nécromancie
Et tu sais quoi? ça m'a donné envie quand même ! comme quoi, je suis vraiment un con... sommateur
De côté pour plus tard... Une reset.css plus moderne... Je me contentais du box-sizing depuis son avènement.
Les explications associées sont intéressantes.
/* Box sizing rules */
*,
*::before,
*::after {
box-sizing: border-box;
}
/* Prevent font size inflation */
html {
-moz-text-size-adjust: none;
-webkit-text-size-adjust: none;
text-size-adjust: none;
}
/* Remove default margin in favour of better control in authored CSS */
body, h1, h2, h3, h4, p,
figure, blockquote, dl, dd {
margin: 0;
}
/* Remove list styles on ul, ol elements with a list role, which suggests default styling will be removed */
ul[role='list'],
ol[role='list'] {
list-style: none;
}
/* Set core body defaults */
body {
min-height: 100vh;
line-height: 1.5;
}
/* Set shorter line heights on headings and interactive elements */
h1, h2, h3, h4,
button, input, label {
line-height: 1.1;
}
/* Balance text wrapping on headings */
h1, h2,
h3, h4 {
text-wrap: balance;
}
/* A elements that don't have a class get default styles */
a:not([class]) {
text-decoration-skip-ink: auto;
color: currentColor;
}
/* Make images easier to work with */
img,
picture {
max-width: 100%;
display: block;
}
/* Inherit fonts for inputs and buttons */
input, button,
textarea, select {
font: inherit;
}
/* Make sure textareas without a rows attribute are not tiny */
textarea:not([rows]) {
min-height: 10em;
}
/* Anything that has been anchored to should have extra scroll margin */
:target {
scroll-margin-block: 5ex;
}
Aujourd'hui, je reviens de la cérémonie de crémation d'un de mes élèves de l'année dernière...
On a appris jeudi dernier qu'il s'était suicidé la veille au soir avec l'arme à feu de son grand-père.
Sous le choc, nous avons tous été extrêmement perturbés et profondément touchés par sa mort... je me souviens d'un môme attachant et discret, au sourire complice quand je faisais des blagues en espagnol, qui passait me voir en fin de journée avant de partir. Un gamin pas méchant pour deux sous, dépourvu de duplicité ou de mauvais sentiments, un garçon qui faisait des efforts en classe mais attendait l'interclasse pour échanger quelques mots avec moi.
Aujourd'hui, on a brûlé son corps en regardant des photos de lui défiler sur un écran et j'ai pleuré comme si c'était le mien... Les photos ressemblaient à celles que j'ai prises de mes mômes depuis 19 ans... et j'ai pas tenu.
Quand un enfant meurt, ce sont tous les parents du monde qui pleurent.
Comme prévu, on s'aperçoit qu'il y a peut-être de l'intox dans l'info qui prétend que des écolos ont empoisonné une rivière pour faire un genre de happening.
En même temps, c'est un peu gros quand même, hein: les Zécolos Gauchiss' idiots qui polluent toute une rivière pour lutter contre la pollution comme le plus con des américains qui pollue une rivière pour un gender reveal party.
un patch pour Starfield corrigera certaines des bethesdouilles les plus flagrantes du jeu. Seront ainsi rajoutés le support du DLSS, un réglage du FOV, un menu de calibration pour le HDR et des curseurs permettant de modifier le contraste et la luminosité de l'image.
Bon, je crois me rappeler que le DLSS est un genre d'upscaling mais j'en sais pas plus, donc je cherche un peu:
Comme son nom l’indique, le DLSS est une technologie d’upscaling reposant sur l’intelligence artificielle. Il existe en effet 4 techniques d’upscaling [...] Formulé plus simplement, le DLSS permet à un PC équipé d’une carte graphique et d’un processeur vieillissant d’afficher un jeu en 4K/60 FPS. Le DLSS est donc un cadeau tombé du ciel pour les joueurs ne pouvant pas se permettre de mettre régulièrement à jour leur setup pour profiter des derniers composants en date (https://www.phonandroid.com/dlss-tout-comprendre-sur-la-technologie-de-nvidia-qui-revolutionne-le-jeu-video.html)
Ha, bonne nouvelle alors ?! Regardons la liste des cartes compatibles sur la même page (j'ai pas cherché plus loin):
RTX 4060
RTX 4060 Ti
RTX 4070
RTX 4070 Ti
RTX 4080
RTX 4090
Donc des cartes allant de 350€ à 2000€...
Bon ben je vais continuer à jouer en mode potato, alors... Parce que même 350€, ça reste cher pour du matos qu'on associe déjà à des composants «vieillissants», en tout cas pour moi. Mon téléphone est explosé et ne fait plus de photos, mon tracteur de pelouse ne démarre plus sans starter extérieur, mes pneus commencent à être justes, on a les loyers de mes deux grands en ville etc etc. Comme tous les gens normaux, je peux pas me payer du matos tous les deux ans. Surtout qu'après, faut stocker... Quand on voit comment c'est dans mon bureau... (et je vous parle pas de chez Liandri )
Sans compter que s'il faut que je change mon compteur électrique et mon alim de PC pour installer une carte graphique qui coûte le PIB du Luxembourg en électricité... une carte qui ne rentrera probablement pas dans mon PC de toutes façons... et qui chauffera tellement que je devrai aussi changer les ventilos...
Bref, merci beaucoup Bethesda pour ce meeeeeerveilleux cadeau.
EDIT : petite annonce
Liandri en profite pour me dire via Signal qu'il vend sa config Gamer, donc je passe l'info
i7 9700k, 64go ram, rtx2080, bonne alim, boitier fractal design R6 silencieux et 4x SSD de 480go : 600€ .
Si ça vous intéresse, passez par moi ou contactez-le directement sur le mammouth
Deuxième épisode de mes notes perso sur la bibliothèque Image magic pour évoquer la classe ImagickDraw qui, comme son nom l'indique, permet de dessiner avec Imagick. ( 1er épisode )
On va se limiter à des usages basiques parce que la lecture du sommaire suffit à imaginer des possibilités certes alléchantes mais totalement hors de propos en ce qui me concerne (courbes de bézier etc)
Spoiler: c'est nettement moins intuitif et simple que pour le traitement d'image... l'écart entre Imagick et GD dans le domaine du tracé n'est plus si évident: ça mériterait de faire un classe pour simplifier tout ça... ( /me se jette sur son bujo pour griffonner spasmodiquement)
Préambule
Cette classe crée un objet servant d'instructions à appliquer ensuite à un objet Imagick.
On partira du principe que vous avez fait des instances des classes comme suit:
$im=new Imagick(); # l'image dans laquelle vous allez appliquer l'objet ImagickDraw
$draw=new ImagikDraw();
Ajouter un texte
Fixer les caractéristiques
$draw->setFont(fonte); : sélectionne la fonte à utiliser
$draw->setFontSize(taille); : définit la taille en pixels
$draw->setFillColor(couleur);: définit la couleur de fond (normalement, couleur est un objet ImagickPixel, voir 1er épisode mais on peut passer une chaîne au format de couleur CSS )
$draw->setTextAlignment(alignement); : une des constantes d'alignement imagick::ALIGN_LEFT imagick::ALIGN_CENTER Imagick::ALIGN_RIGHT
$draw->setGravity(Imagick::GRAVITY_CENTER); centre le texte dans sa boîte (horizontal et vertical)
$draw->setTextDecoration(decoration): une des constantes de décorationimagick::DECORATION_UNDERLINE imagick::DECORATION_OVERLINE imagick::DECORATION_LINETROUGH et bien d'autres (comme du... bruit ?!).
$draw->setTextAntialias(true);: ajouter de l'antialias
l'espacement :
entre les mots : $draw->setTextInterwordSpacing(taille)
entre les lignes : $draw->setTextInterlineSpacing(taille)
Tracer le texte
$draw->annotation(x,y,texte) : trace un texte dans la police sélectionnée
$im->annotateImage( $draw, 0, 0, 0, $fontName ); : ajoute le texte à l'image.
Obtenir des infos utiles
obtenir la liste des polices disponibles: $im->queryFonts($pattern = "*") 🆒 on peut filtrer avec une pattern à la façon de glob().
obtenir les infos fixées par setXXX : getXXX ... ainsi on a getFont(), getFontSize() etc...
obtenir les dimensions de la boîte de texte: $im->queryFontMetrics($draw, text); on récupère un tableau comme ci-dessous
Array
(
[characterWidth] => 9
[characterHeight] => 9
[ascender] => 9 # la taille au-dessus de la baseline
[descender] => -2 # la taille sous la baseline
[textWidth] => 71
[textHeight] => 10
[maxHorizontalAdvance] => 12
[boundingBox] => Array
(
[x1] => 0
[y1] => -2
[x2] => 6.890625
[y2] => 7
)
[originX] => 70
[originY] => 0
)
Dessiner des formes
Fixer les caractéristiques
opacité du trait : $draw->setStrokeOpacity(0-1);
couleur du trait : $draw->setStrokeColor(couleur);
épaisseur du trait : $draw->setStrokewidth(nb);
type de trait : $draw->setStrokeDashArray() Le motif semble être plein de possibilités car on peut le définir très spécifiquement et même utiliser une image comme motif (->setStrokePatternURL)
couleur de remplissage : $draw->setFillColor(couleur);
Allez, pour une fois, j'ai un peu de temps devant moi, je vais éplucher un peu la lib Image magick dont je parlais il n'y a guère...
La base
charger UNE image
Simple: pas besoin de plusieurs fonctions selon le format, il suffit de $images = new Imagick('image.jpg');
charger DES images (et là c'est fort)
Même pas nécessaire de passer par un foreach, on fournit le tableau des fichiers voire directement un glob: $images = new Imagick(glob('images/*.JPG'));
Sauver une image
$im->writeImage('image.jpg');
Faire une miniature
Si on laisse une dimension à 0, les proportions sont conservées (quand tu vois la merde que c'est avec GD !)
$image->thumbnailImage(100, 0);
Output une image
header('Content-type: image/jpeg');
$image = new Imagick('image.jpg');
# ici on effectue un traitement puis on sort le résultat
echo $image;
Récupération d'infos sur les images
taille $im->getImageWidth() $im->getImageHeight()
format $im->getImageFormat()
🆒 ⮕ pour fixer le format de l'image, c'est juste $im->setImageFormat('png'); ! 😍
Comme pour GD, il faut créer un objet couleur dans les traitements d'image, mais c'est plus simple qu'avec GD (et plus complet): il suffit de passer une couleur selon les normes CSS. Du coup, la transparence n'est pas gérée par une connerie de paramètre «alpha» mais simplement par ... rgba()... 💖
🆒 ⮕ Ça peut paraître compliqué, mais en fait, dans les fonctions où on est sensé utiliser ImagickPixel, je me suis aperçu qu'on pouvait tout simplement passer une string contenant la couleur css... elles se démerdent seules. 😍
Image Magick me semble particulièrement bien nommée tant les possibilités sont énormes et la simplicité d'utilisation étonnante: on sent une volonté de se simplifier la vie lors de l'utilisation... c'est juste beau.
Je voulais mettre une image de chaque effet dans les descriptions mais:
ça prenait une place de ouf
je préfère reprendre certaines de mes applis/api avec imagick
C'était souple et simple mais le résultat restait assez décevant parce que je ne parvenais pas à gérer correctement la transparence des PNG: GD ne prenait en compte qu'une seule couleur transparente et on se retrouve avec un GIF like en qualité potato...
Après avoir cherché, lutté, testé des trucs, modifié ma classe... le ratio temps demandé/résultat obtenu m'a poussé à me dire : «stop, il doit y avoir un moyen plus simple»
Ben vous savez quoi ? Il y a. Oui.
Ma classe était déjà vraiment pas mal car elle permettait de faire les choses simplement... Mais, juste pour tester, j'ai essayé ImageMagick.
Reprendre mon code pour utiliser cette lib m'a pris un gros quart d'heure et cinq fois moins de code.
Et ça a marché. Propre. Du premier coup.
Conclusion
🟢 rapide
🟢 simple d'utilisation (5 minutes pour piger les bases)
🟢 efficace
🟢 code ultra lisible et compact à la fin
🟢 se suffit à elle-même et gère seule les trucs chiants
Surtout Bethesda se prend les pieds dans son monde ouvert. L’échelle tant mise en avant se trouve saucissonnée en petites poches quasi étanches qui sapent le sentiment d’exploration si précieux dans leurs jeux. De toute façon, la plupart des planètes, au contenu généré aléatoirement, n’offre rien d’autre que des ressources à collecter et une infinité de jobards à tabasser dans des complexes militaro-industriels répétés à l’infini. Et si l’on peut personnaliser son vaisseau de pied en cap, on n’aura pas grand-chose à faire dedans. Pour sa première création originale en vingt-cinq ans, Bethesda livre une odyssée spatiale si chétive et étriquée qu’elle interroge sur la capacité du studio à se renouveler.
Au bout du compte, on a l'impression d'un jeu prétentieux :
Bethesda ne s'est pas donné les moyens de ses ambitions : les mondes générés produisent un peu le même effet que la N ieme ruine Ayléide, le N ieme dongeon, la N ieme grotte dans les elderscrolls...
Starfield ne donne jamais l'impression d'être vraiment dans un vaisseau comme celle qu'on a dans un Subnautica («welcome on board, captain»): on n'y fait rien, il ne s'y passe pas grand chose, on n'a même pas l'impression d'être dans un véhicule... Bof.
les chargements sont vraiment intempestifs: tu charges pour TOUT, et parfois, tu charges pour arriver devant une porte ou tu recharges pour la passer puis tu recharges encore ... et comme les chargements sont interminables... ça casse le rythme.
l'ajout de la couche de mondes à visiter accentue encore l'effet précédent: entre vaisseau ? CHARGE, déplacement dans un système ? CHARGE, atterrissage ? CHARGE, prends le tram ? CHARGE, entre dans un bâtiment ? CHARGE !
ce jeu ne propose finalement que peu d'interactions avec le monde: la plupart des trucs du décor (vaisseau compris) ne sont... ben que du décor. Ça me met de travers d'avoir des ralentissements et des chargements de ouf juste parce que le décor est détaillé...
Je pense que le jeu a été survendu, à tort annoncé comme révolutionnaire par certains: hélas, les mécaniques de Skyrim/Oblivion/Morrowind étaient suffisantes pour l'époque et on les aimait malgré leurs éventuelles imperfections.
Cette indulgence ne peut plus être autant de mise dix ans après Skyrim... Surtout après avoir autant attendu un jeu à cause duquel Bethesda n'a pas travaillé sur ES6... (et ÇA c'est grave !)