倉金家ホームページ
趣味の部屋/ホームページ余話
ホームページに載せた写真などの画像を位置や大きさを指定して表示し、しかもその場でスクロール、あるいは拡大、縮小などができるといいなと思ったことがあります。 今回javascriptでそんなコードを書いてみました。さらにSVG画像も試してみました。 |
|
|
このホームページでは写真は通常下のように小さいのを掲載します。
|
そして写真をマウスでクリックすると拡大画像を表示、それをもう一度クリックすると元に戻るようにしています(...自動的にそうなるようにプログラムしてあるんだ)。 ただこの方法は基本的には画面の大きなブラウザ向けで、しかもわざわざページを切り替えて表示すると何だか話がいったんとぎれるような感も否めません。 時には縮小しないで元サイズのままページに載せたい場合もあります。地図、説明書きなどがいい例で、縮小してしまうと内容がよく見えませんし、わざわざ拡大する為にページを切り替えるというのも煩わしく感じます。 また話の流れを大事にしたいときなどもページ上の画像だけで用が済めばと思います。
|
そんなときはページ上に適度の大きさの画像を載せますが、ときになんだか中途半端になり、小さくなったり画面から外れたりでかんじんなところがよく見れなかったりします。 そのためにわざわざ写真をトリミングしたりサイズを変えたりしますがやっぱりめんどうです。 そこで縮尺や位置を指定して表示できるようにし、さらにズームやスクロール機能をつけてみました。 左下のボタンで拡大・縮小、スクロールなどができます。ボタンは見る邪魔をしないよう控えめに設置しました。 さらにマウスで、 (1) マウスでボタンをおしたままのドラッグ方式のスクロール (2) ワンクリックごとのキャッチ&ドロップ方式のスクロール (3) さらにダブルクリックでズーム切替や中央へのスクロールなど という、な、なんと3種類のスクロールができる豪華版です。 (遊びで3種類のスクロールを同時に実現などとこってしまったが(1)だけでよかったみたい。知らないとかえって混乱したりする。でもスクリプトの動作の選択は変更できる。) 画像はこんなふうに表示されます。 これは先ほどの 写真:金閣寺。 同じ画像だが位置と大きさをうまく指定すればこれだけでほとんどいける。 その他、 日本地図…ただの白地図なんだ。 京都の地図…地図はやっぱりスクロールできて周りも見れるといいね。 写真:夏祭り…かんじんなところはスクロールして見てね。 ...といった具合。
|
現行ブラウザでは、Trident/7.0、Firefox/38、Chrome/44、OPR(Opera)/31で動作確認してあります。 最初HTML5感覚で書いたら少し古いMSIEでは動作せず多少後退した記述になっていますが、いちおうMSIE8(WindowsXP)でもちゃんと動作します。このころMSIEが一番HTML5対応が遅れているような気がしたのでそれ以降のブラウザではほとんどだいじょうぶでしょう。(それ以外のブラウザはないので確認してませんけど。...たまたま捨てずにあったXPが役に立った。しばらくこのままとっておこう。)
コードは今回phpは使わずjavascriptだけで書いてありますのでそのままホームページに設置できます。ご参考に。
|
|
←画像拡大縮小スクロールプログラム showimg.html ソースコード。(別窓に表示します。) ただし実際使うのでしたら最後の方に載せたHTML+javascript分離版をお薦めします。(2015-9-8追記) |
|
上のようにページ内に表示するためのHTMLコードは以下のようです。 絶対必要なのは 赤の?src=画像のファイル名だけであとの &以下はオプションですが、どんなオプションがあったか自分でも忘れるのでコピーペーストして変えればいいようにディフォルトでも使いそうなのを皆書いてあります。 (例) <iframe name="FrameName" src="showimg.html?src=image1.jpg&x=0.5&y=0.5&zoom=1&title=&info=&scrolling=no&anchor=&button=left" width="480" height="360" style="border:4px white solid;"></iframe>
オプションの意味は、 x= 大きな画像を表示するときなるべく中心にもってくる左右位置。左端0.0,右端1.0。 y= 大きな画像を表示するときなるべく中心にもってくる上下位置。上端0.0,下端1.0。 zoom= 縮小比率、原寸表示1,画面に合わせて縮小表示0,その他半分に縮小なら0.5など。 title= 画像のタイトル。左上に表示。 info= 説明、案内など。右上に表示。 scrolling= スクロールバーを表示するか否か。yesで表示、noで非表示。 anchor= 拡大縮小時などの基準位置の目印。+や◯などの記号文字。 button= 表示操作ボタンの配置。leftかright、+をつけると初期表示。 など。 |
|
また上記の表示画面内の内容を切り替えるリンクは、 <a href="showimg.html?src=image2.jpg&...." target="FrameName">画像その2</a> などとします。すなわちtargetに上記のインラインフレーム名を指定します。 指定しなければ同じページ、NewWindowなどとすれば新しいウィンドウ(タブ)に表示されます。 |
|
上記プログラムはphpも使って画像にマーカーを入れたりして地図などを表示するのに使っています。 単に場所の案内地図なら最近は地図サイトの位置リンクサービスなどを使えばいいのでさほど必要性はありませんが、手書きの案内や 特殊な画像にマーカーを入れる等の用途には便利に使えます。 |
|
追記:SVG画像を試してみた(2015年8月30日)
|
|
先週東京方面に行く用事があり鉄道の路線図を見ようとしたら、 東京の鉄道路線図SVGを作りました&パブリックドメインで配布します(http://note.openvista.jp/2014/svg-rail-map) というページを見つけて、SVG画像だとどうなるのか試してみた。 ファイルをダウンロード、CSSファイルが別になっていたが画像のソースとした場合は読み込まないらしいので本体に移動。 |
|
←読み込ませる東京の鉄道路線図のSVGファイル(695kB)。 ソースをテキスト表示させるために拡張子に".txt"を付加してあります。だからクリックするとテキストソースを表示します。とても長いです。...よくこんなのつくったもんです。 |
|
実際表示させてみるとブラウザによっては少し問題があってコードを修正した。 以下がその表示。 まず私のIE11(Trident/7.0)ではなぜかうまく表示されない。図形はともかく字がよく見えない。決して老眼のせいではない。元のサイトのをブラウザで直に開いてもちゃんと表示されないのでこのスクロールプログラムのせいではなさそう。 「IE11 svg」で検索してみるとIEでのSVG表示はいろいろ問題があるようで、svgファイルを修正してどのブラウザでもうまく表示できるようにする技量もないが、とりあえずcss部分を修正したらすこし見やすくなったのでその画像に切り替えて見てもらうことにしよう。 IE8では全然表示されない。svgファイルをアドレスに直に指定するとダウンロードウィンドウが出るのでIE8で取り扱うファイルではないということらしい。その他のIEはもってないのでわからない。 他のブラウザ(Firefox38, Chrome44, Opera31:現時点での最新版)では特に問題はない。 ただしスクロールはいいとして画像の拡大縮小には少し時間がかかる。jpg写真のような連続的なズームは難しい。 たぶんブラウザ内でSVGを都度<img>タグ用の画像に変換して書き出すためだろうと思う。 MSIE11でうまく文字が表示されていない方はこちらで→MSIE11向け画像に切替。
|
上記表示のHTMLは、 <iframe src="showimg.html?src=idata/files/180/16/tokyo_ja.svg&x=0.507&y=0.476&zoom=0.5&zoommax=0.8&zoommin=0.2&title=東京鉄道路線図&info=ご注意:画像は見本であり実用に供するためではありません。&dclick=centerscroll&btnzoom=stepjump&button=+left&scrolling=yes&anchor=" width="98%" height="500" style="border:2px gray solid;background:#EFE;"></iframe>
…大きさは適当に見やすいように決めました。中心はもちろん皇居ということになっております。 現時点ではこの路線図は実際と合っていても今後変わった場合更新はされないので、実用に供するためのものではない旨の断りをいれておきました。 |
|
ちなみに上記の東京鉄道路線図SVG画像をインラインではなく1ページにフルに表示してみたのがこちら。画像が大きく内容が濃いので見応えがある。 ただしこちらの表示プログラムはあとの方に書いたhtml+javascript分離版に変更しています。 → 東京鉄道路線図 …1ページ表示。Firefox,Chrome,Operaのどれかでなるべく大きな画面で見てね。ボタンなどもう少し格好をつければこれだけでページとして充分通用するな。 |
|
(追記)cssの部分を一部無効にしたらIE11でも何とか見れるようになった。やっぱcssが合ってなかったようだ。さらに同じブラウザで見ても描画は速くなった。cssを当てるのにけっこう時間をくうんだ。 → (IE11向)東京鉄道路線図 …1ページ表示。IE11向け。元画像のcssが少し修正されている。
|
SVGの場合(内容にもよると思うが)通常のjpgやpngなどの画像に比べサイズ変更の書換えに時間がかかるようだ。 pngなどの画像に変換して表示すればいいような気もしたので私の持っている画像ソフトでやってみたがどうやらcssの部分は反映されないようで(cssが効くのはブラウザとそれなりの画像ソフトのみ?)、文字の部分がうまく表示されずあきらめました。仮にできてもファイルサイズはかえってすごく大きくなるみたいだし。 でも今後PCやブラウザのスピードもどんどん上がるし、仕様も統一されてくるし、ブラウザ共通にSVG画像をつくるテクニックも上がってくるだろうし、何より変更がすぐに反映されることなどいろいろ考えると、SVGをそのまま表示するメリットの方がじきに大きくなってくると思う。 …などと言ってうまくできなかったのをごまかす。 ブラウザの中でpng画像などに変換してそれを表示に使えればさらにいいのかもしれませんが、残念ながら私にはそのスキルはなかったのでした。 ...というわけで、自分でSVG画像を作れるわけではないけれど、試しにやってみましたという話。 このような労作を無償公開してくださった note.openvista.jp の@hashccさんに感謝!感謝!
|
追記:参考に(2015年9月8日)
同じようなことをやろうとしている人がいましたら少しでも参考になるようにと、今回検討したことなど記しておきます。
画像の表示タグは<img>タグのほかに<object>や<embed>を使う方法もありますが、今回のSVG画像の場合サイズを変えると見え方がちがいます(本来SVGはそうではないと思うんだけど)。画像を書き出してからそのサイズを変えて表示するか最初からそのサイズで書き出すかの差だろうと思っていますが、今回は一番自然に見えた<img>タグを使いました。 |
|
1.画像サイズの取得の方法
当初元画像の画像サイズはImageオブジェクトから取得していました。すなわち(細かいとこは省略して)、 画像サイズ取得方法その1: img = new Image(); img.src = (画像のURL); document.write('<img id="IMG" src="'+img.src+'" onload="init_set();" />'); .... function init_set() { .... // 元画像の幅と高さ(単位px)。 sourceimage_width = img.width; sourceimage_height = img.height; .... } しかし通常の画像(jpg写真など)では特に問題はなかったけど、svg画像では画像サイズの取得で少し問題が出ました。 あるブラウザでは画像が表示されず、調べてみると 画像サイズが取得できていなかったのです。 で、検討した結果、 画像サイズ取得方法その2: document.write('<img id="IMG" src="" />'); if(セキュリティーチェックOK) { document.getElementById("IMG").onload = function(){ setTimeout("init_set();",100); } document.getElementById("IMG").src = (画像のURL); } .... function init_set() { .... // 元画像の幅と高さ(単位px)。 sourceimage_width = document.getElementById("IMG").width; sourceimage_height = document.getElementById("IMG").height; .... }
.... この方法でsvg画像のサイズも試したすべてのブラウザ(MSIE11(Trident/7.0), Firefox38, Chrome44, Opera31)で取得できるようになりました。もちろんjpg写真なども従来どおり問題ありません。 .width, .height ではなく .naturalWidth, .naturalHeight でとるのが本当だとは思うのですが、SVG画像だとまたもや一部のブラウザではとれません。<img>タグにまずはサイズを指定せずこの方法でとるというのが今のところもっとも無難そうです。 onload の部分に setTimeout を使っている理由とセキュリティーについては以下に述べます。 |
|
2.画像サイズ取得のタイミング
上記の画像サイズの取得方法その2で、最初onloadの部分を、 document.getElementById("IMG").onload = init_set; としていました。 ところがときおりsvg画像が表示されず、そのときはなぜか画像サイズが取得できていません。 毎回ではなく時折で、この画像の表示一発目に多いようです。 キャッシュの有無などともからむ何かタイミング的な問題があると思われました。 そこで、setTimeoutを入れて画像サイズ取得のタイミングを少し遅らせてみました。 document.getElementById("IMG").onload = function(){ setTimeout("init_set();",100); } 結果、予想どおりばっちりOK。以後この現象は出なくなりました。 画像をロードしてから実際にタグに画像のサイズがセットされるのにほんの少し時間がかかる場合があるようです。100ms(0.1秒)に特に根拠はありません。ちゃんと表示されて待ち時間の増加としても実質問題がない範囲でということで。 SVG画像だからなのか、あるいはその内容によるのかなど、詳しくは調べていません。 その他細かいのは省略。 |
|
3.セキュリティー
このようなプログラムを書く時はいつもだったらphpを使って表示条件などはほとんど固定的に指定してしまうのですが、今回はjavascriptだけでしかもその場ですぐ表示条件を変えられるようクエリーでの指定を受け付けるようにしました。
最初全然考えなかったのですが、これだと画像にへんな画像や宣伝など勝手なものを指定して掲示板などに投稿すればそれを表示させられるということに気がつきました。そんなことするやつもたぶんいないだろうけど。
で、念のため表示チェックを追加。 1.画像についてはページと同一ドメイン(正確にいうならホスト)の画像のみ表示。 2.titleとinfoについてはページと同一のreferrerを確認して表示。 その他のパラメータ、画像の大きさ、位置、...などについてはまあいいでしょう。
ちょっと運用が面倒にはなるけれど、以下のいずれかの方法をとってクエリーの受入はなるべくやめるのが正解かもしれません。 1.別にパラメータリストを作ってそれを読み込むようにし、クエリーでパラメータキーのみ指定。 2.都度ファイル名を変えてファイルを作成しパラメータを書換え。必要なら共通部分は別にして読み込み。 できればそうした方がいいと思うので、無精でない方はぜひこちらで。
|
|
2の方法でやるとして設定部とスクリプト部を分けてみました(HTML+javescript分離版)。 img.htmlを表示したい名前でコピーし(img_phpto1.htmlなどと)、表示設定の部分を変えればOK。 クエリーは一切受け付けません。セキュリティーチェックも取り除いたのでhttp://指定で他のドメインの画像も表示は可能です。 ファイルサイズなんて気にしないという方は前のクエリー版からクエリー受入部分を取り除いた都度名前を変えたファイルで表示するのもいいかと思います。
|
|
おまけ:画像に付箋をつける (2018年5月8日 追記)
その後インライン画像に付箋などつけられないかという話があったので少し検討してみました。 やりたいのは、インライン表示した画像に付箋を付けたり剥がしたりしたいとのことでした。 画像に付けるというところがミソのようで、画像の位置に追従させなくてはなりません。
|
結果から言うと、何とかそれらしいことはできました。 ページの任意の位置にはもちろん、画像をブロック表示して、および画像をインライン表示して、それぞれ付箋をつける方法が書いてあります。 ←左のアイコンをクリックすればその方法と実際のデモが見れます。
|
←こちらはそのhtmlとjavascriptのソースです。 一見付箋らしいのをtextareaでつくり、移動、サイズ変更、保存、読み出しなどをjavascriptで制御しています。
|
お話をいただいた方に送った説明用ファイルほぼそのままですが...。 上記の画像のズームやスクロールとあわせて画像表示の参考にでもなればということで。
|
|
|