[C++] 341 BBS閲覧アプリの製作 その27 リンク画像をポップアップ表示 JavaScript

[M1 Mac, MacOS Ventura 13.3.1, clang 14.0.3]

画像のURLをマウスオーバーするとぼかし画像がポップアップ表示され、クリックすると加工無しの画像がポップアップ表示されるようにしました。

ここが山場になるかと構えていましたが、思っていたよりもあっさりでした。それでもChatGPTを駆使しながら4時間程度掛かっています。

最も手こずったのはクリックして指定サイズでポップアップさせるところでしょうか。どうしても普通にリンクを踏む形になって大きいサイズでの埋め込み表示になってしまいました。結局、event.preventDefault()でデフォルトのリンク処理をスキップして解決しました。

たまにポップアップの後に影が残ったりしますが、後日対応することにします。

マウスオーバーでぼかし画像表示
クリックで元の画像表示

<html lang="ja">
<HEAD>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="styles.css" />
<script type="text/javascript" src="function.js"></script>
<STYLE TYPE="text/css">
    .popup-image {
        position: absolute;
        top: 0;
        left: 300px;
        width: 300px;
        height: auto;
        display: none;
        filter: blur(10px); // ぼかし加工
      }
    .popup-image2 {
        position: absolute;
        top: 0;
        left: 300px;
        width: 500px;
        height: auto;
        display: none;
    }
</STYLE>
</HEAD>
<BODY bgcolor="#ffffff">

<p id ='1'><font size="2" color="#008080">1 : テスト<br></font>
<font size="2" color="#000080">2023/07/22(土) 10:23:46.76 ID:xxx<br></font>
<font size="2" color="#000B00"> テスト <br> <a href="画像のURL" 
rel="noopener noreferrer" onmouseover="showImage(this,event);" onmouseout="hideImage();" 
onclick="showImage2(this,event);">画像のURL</a>
</font></p>

<script>
    // ぼかしあり画像表示
    function showImage(element,event) {
        var imageSrc = element.getAttribute("href");
        var imageElement = document.createElement("img");
        imageElement.src = imageSrc;
        imageElement.classList.add("popup-image");
        document.body.appendChild(imageElement);
        imageElement.style.display = "block";

        var rect = imageElement.getBoundingClientRect();
        var y1 = rect.top;
        console.log("Popup y1 = " + y1);

        var y2 = event.clientY;
        console.log("Popup y2 = " + y2);

        var y = -y1 + y2 -100;
        if (y < -y1){
            y = -y1;
        }
        console.log("Popup y = " + y);

        imageElement.style.top = y;
    }

    // ぼかしなし画像表示
    function showImage2(element,event) {
        event.preventDefault();

        var imageSrc = element.getAttribute("href");
        var imageElement = document.createElement("img");
        imageElement.src = imageSrc;
        imageElement.classList.add("popup-image2");
        document.body.appendChild(imageElement);
        imageElement.style.display = "block";

        var rect = imageElement.getBoundingClientRect();
        var y1 = rect.top;
        console.log("Popup y1 = " + y1);

        var y2 = event.clientY;
        console.log("Popup y2 = " + y2);

        var y = -y1 + y2 -100;
        if (y < -y1){
            y = -y1;
        }
        console.log("Popup y = " + y);

        imageElement.style.top = y;
    }
    
    // 画像消去
    function hideImage() {
        var popupImages = document.getElementsByClassName("popup-image");
        while (popupImages.length > 0) {
            var image = popupImages[0];
            image.parentNode.removeChild(image);
        }

        var popupImages2 = document.getElementsByClassName("popup-image2");
        while (popupImages2.length > 0) {
            var image2 = popupImages2[0];
            image2.parentNode.removeChild(image2);
        }
    }
</script>
  
</BODY></html>

[C++] 340 BBS閲覧アプリの製作 その26 モーダルダイアログ設定 / Fl_Button修正 セル灰色トラブル対策 FLTK

[M1 Mac, MacOS Ventura 13.3.1, clang 14.0.3]

スレッドタイトルを選択して右クリックするとdatファイルを削除できますが、一応モーダルダイアログで確認するようにしました。

また右クリック時にセルがランダムに灰色になってしまう問題については、元ソースコードのFl_Button::draw関数に原因があることが判明しましたのでこれを修正しました。

具体的にはFl_Buttonにvalue関数でsetした値が1の場合はselection_color()である灰色になっていました。これをcolor()に変更しています。

作業効率を上げるためなのでしょうが、変数名が単純すぎるのも第三者から見ると読みにくくて仕方ないです。ただでさえC++の表現は記号が多くて抽象的なので、気を付けたいところです。

#include "MyButton.h"

MyButton::MyButton(int x, int y, int width, int height, const char *L)
 : Fl_Button(x, y, width, height, L) 
{
}

void MyButton::draw() {
    if (type() == FL_HIDDEN_BUTTON) return;
    Fl_Color col = value() ? color() : color();
    //   Fl_Color col = value() ? selection_color() : color(); // この行を修正
    draw_box(value() ? (down_box()?down_box():fl_down(box())) : box(), col);
    draw_backdrop();
    if (labeltype() == FL_NORMAL_LABEL && value()) {
        Fl_Color c = labelcolor();
        labelcolor(fl_contrast(c, col));
        draw_label();
        labelcolor(c);
    } else {
        draw_label();
    }
    if (Fl::focus() == this) draw_focus();
}

int MyButton::handle(int event) {
    switch (event) {
        case FL_ENTER :{ // マウスオーバー
            color(fl_rgb_color(160,216,239));
            redraw();
            return 1;
        }
        case FL_LEAVE :{ // マウスが離れる
            color(FL_WHITE);
            redraw();
            return 1;
        }
        case FL_PUSH:{ // マウスボタンを押す
            color(fl_rgb_color(0,255,255));
            redraw();
            return 1;
        }
        case FL_RELEASE :{ // マウスボタンを放す
            do_callback(FL_REASON_RELEASED);
            color(fl_rgb_color(FL_WHITE));
            redraw();
            return 1;
        }
        case FL_MOUSEWHEEL :
        case FL_FOCUS :
        case FL_UNFOCUS :
        case FL_KEYBOARD :
        case FL_SHORTCUT :
        case FL_DRAG :{
            return Fl_Button::handle(event);
        }
        default:{
            return Fl_Button::handle(event);
        }
    }
}