CSS/Javascriptでテキストにマウスカーソルが乗っているかの判定

投稿者: Anonymous

HTMLにおいてCSSまたはJavaScriptを利用しテキスト(テキストを含む要素ではなく、テキスト、文字それ自体)にマウスカーソルが乗っているかを判定し効果をつける方法はありますか。
CSSなら

<style>
#box:hover { /* css */ }
</style>

<div id="box">てきすと</div>

というのではなくて、たとえば疑似コードを書くなら

<style>
#box:textShape:hover { /* css */ }
</style>

みたいなことです。
SVGのを利用した方法については確認済みですので、タイトルの通りCSSあるいはJavaScriptで可能かどうかを教えていただきたく、また可能であれば参考になるページなどを示していただければ幸いです。
よろしくおねがいします。

解決

mjy様の回答はとても参考になりました。canvasを使える環境であれば、示していただいた手法が解決法の一つとなるでしょう。また、このことを参考に自分でも調査をしてみると、https://stackoverflow.com/questions/1936021/javascript-eyedropper-tell-color-of-pixel-under-mouse-cursor というQAを発見し、こちらにもやはりcanvasを利用した回答、そして

It’s not possible with JavaScript as it goes against cross-domain security.

というようにjsではここまでが限界のようです。また、

通常のHTML要素で描画されている字形に対して、判定を行ないたい

のです。おっしゃるとおりです。

さて私は以前html2canvasというライブラリを使用したことがありまして、これはDOMを読んで独自にレンダリングしcanvas要素にスクリーンショットのようなものを生成してくれるライブラリです。画像の読み込みやiframe,flashなどへのサポートは技術的な制約もあり不完全ですが、テキスト目的という今回の趣旨については十分でしょう。
判定処理の発想はそのままですが、このスクリーンショットの画像を利用したサンプルを作ってみました。

_x000D_

_x000D_

var target = document.querySelector('#box');_x000D_
var ssCtx;_x000D_
_x000D_
html2canvas(target, {_x000D_
  onrendered: function(canvas) {_x000D_
    ssCtx = canvas.getContext('2d');_x000D_
  }_x000D_
});_x000D_
_x000D_
target.addEventListener('mousemove', function (e) {_x000D_
  if (ssCtx) {_x000D_
    var pixel = ssCtx.getImageData(e.offsetX, e.offsetY, 1, 1);_x000D_
    target.className = pixel.data[3] ? 'text_shape_hover' : '';_x000D_
  }_x000D_
});

_x000D_

#box {_x000D_
  font-size: 200px;_x000D_
  font-weight: bold;_x000D_
  transition: color 0.3s;_x000D_
}_x000D_
#box.text_shape_hover {_x000D_
  color: red;_x000D_
}

_x000D_

<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>_x000D_
_x000D_
<div id="box">てきすと</div>

_x000D_

_x000D_

_x000D_

結果は良好です。細部について(背景色/scroll/動作負荷/各環境のサポート)については未検証ですが、少なくともテキスト要素について利用するならば、canvasをサポートしてさえいればうまく動作するよう実装できるはずです。

結局canvasで力技かよ、と自分でも思いますが、以上で一応の自己解決として回答を載せておきたいと思います。

回答者: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *