写了个简单的 JavaScript,可以指定 HTML 页面上的一个元素作为 container,从里面的任意元素向里面某个图片的一个区域画箭头。名字就叫 autoarrow.js 吧,放在 github 上,点过去可以看到简介、截图,里面也有一个简单的例子。依赖 jQuery, 不过我不太熟悉怎么做成 jQuery 插件的形式,就这么凑合着吧。
Showcase
以下几篇文章可以作为演示 (如果你看不到可能是缓存问题,强制刷新一下)
大致原理
创建一个 canvas,位置、大小完全和 container 一致,但是 z-index 是负数,这样它就在 container 显示层的下面,设置 container 背景透明,所以能够看到 canvas 上的东西。如果 canvas 在 container 上面,则会影响 container 里的文字选择等操作。
因为图片一般是不透明的,所以把区域内的图片都设置 z-index 为更小的负数,但暂未考虑其它不透明元素。
计算出箭头起点区域和终点区域的坐标,用一种很简单的算法计算起点、终点到底从哪个方向画出来。这样在接口参数中,起点只需指定起点的元素,比如 $('#anchor-1')
这样的,终点只需指定图片和目标区域(一般是图片上的一个物体)。无需考虑排版变化之后需要重新“布线”的问题。
执行时机
使用这个脚本的时间问题。最初我选择在 jQuery 的 ready 事件中执行:
$(function() { ... });
随后发现在 Chrome 里,图片还没有加载就开始画线了,而如果这图片的大小是事先未知的,就不能事先指定其尺寸,图片加载完成会造成重新排版,就全乱了。
正好 jQuery 还提供了一个 .load 事件,这个可以在所有图像加载结束之后执行,正适合这个场合:
$(window).load(function() { ... });
如何方便地取得图片区域坐标
这只是一个小工具,如果想在动态程序中应用它,所需的额外工作还不少。比如怎么选定图片的一个区域,得到它的坐标并且保存起来,好在显示页面的时候使用?这方面的插件有很多,imgAreaSelect 就是很好用的一个。
如何让编辑器辅助该功能
如果想在可视化编辑器里加这么个功能还真有点麻烦。我这个 blog 后台一直在使用 textarea 里写 Markdown 的形式,所以就不用可视化了。我写了一个 Python Markdown 的 extension, 使用这样的语法 {链接文字-->1}
,意思是把“链接文字”这段字作为起点,指向数据库里保存的 id 为1的区域(这个记录保存了图片地址,区域坐标,通过这些信息可以定位)。插件会把这段标记翻译为:
<span class="pointer" id="pointer-to-1">链接文字</span>
在页面加载完成后的事件处理中,就可以通过 pointer 这个 CSS class 找到所有的链接起点,每个起点又可以通过其 id 分析出指向的区域,就可以应用 autoarrow.js 了。
应用场景
说明书或者产品介绍之类的东西吧
尚存在问题
- 线条不够美观
- 没有找到一种办法可以让线条醒目,同时在文字区域又不太影响阅读
- 没有考虑 container 里有许多复杂的不透明元素的问题
- 只在 Firefox 6 和 Chrome 13 里测试过
Leave a Reply