三、放大镜进阶版

JavaScriptJqueryExampleHtml2canvas

# 需求分析

最近要做的这个放大镜的功能需求是这样的,截取屏幕可视区域的图片然后进行放大。

为了可以看到动态的效果,所以我在上面加了随机的添加图标的功能,这样就可以看到实时的改变。

# 功能分析

  • 设置按钮,点击按钮的时候显示遮挡层和大图框
  • 设置添加图标按钮,点击在屏幕的随机位置生成一个图标
  • 在文本框中输入文字
  • 截取可视区域的屏幕并生成图片
  • 将可视区域的图片进行放大放入到大图框中
  • 鼠标移动的时候大图框中的也同样移动

# 效果图

tb.png

# 截屏插件 html2canvas

html2canvas 官网 (opens new window)

这个插件是让你整体截屏或者部分截屏的功能,截屏直接在浏览器上使用。这个插件是基于dom操作,但是不是百分百准确的,因为它并不是生成一个图片,而是基于页面上的信息截图。(说白了就是截下来一部分的信息然后直接绘制到另一个地方,并不是保存成了图片文件)

# 注意事项

这个插件有一定的限制

  • 第一个就是文档不是很全,过于简单
  • 第二个是其工作原理不是真正生成一个截图,而是遍历所有的dom元素构建页面,所以很多css属性无法使用
  • 第三个是要求图像同源且没有代理,这个脚本不渲染flash\applet\iframe等内容

# 可用参数

这些参考API和中文的简书,写的很清楚

html2canvas中文简书 (opens new window)

# demo

  • 先引入js文件
<script type="text/javascript" src="html2canvas.js"></script>
1
  • 写html结构
<body id="bd">
    <div id="view" style="background:url('./test.png') no-repeat;background-size: contain; width: 700px; height: 500px;">
        <input type="button" value="截图" onclick="takeScreenshot()">
    </div>
</body>
1
2
3
4
5
  • 写js代码
<script type="text/javascript">
  function takeScreenshot() {
      html2canvas(document.getElementById('bd'), {
          onrendered: function(canvas) {
              document.body.appendChild(canvas);
          }
      });
  }
</script>

1
2
3
4
5
6
7
8
9
10

下面还是回归正题,开始写放大镜的结构:

# 放大镜的html结构

<style>
  *{
      margin:0;
      padding:0;
  }
  body{
      background-image: url('./hua.jpg');
      background-repeat: no-repeat;
      position: absolute;
      width: 100%;
      height: 100%;
  }
  #dv{
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background-color: rgba(0,0,0,0.5);
      display: none;
  }

  #btn{
      position:absolute;
      top: 20px;
      left: 20px;
  }

  #mask{
      width: 175px;
      height:175px;
      position: absolute;
      top: 0;
      left: 0;
      background-color: rgba(255,150,0,.5);
      cursor: move;
  }

  #look{
      width: 200px;
      height:200px;
      position: absolute;
      top: 30px;
      right: 30px;
      border: 1px solid #f40;
      cursor: move;
      overflow: hidden;
  }
  #box{
      width: 100%;
      height:100%;
  }
</style>

<body id="bd">
    hello world!!
    <input type="button" value="放大镜" id="btn"/>
    <div id="dv"><!--遮罩层-->
        <div id='box'></div><!--相当于小图-->
        <div id="mask"></div><!--跟着鼠标的层-->
        <div id="look"><!--显示的区域-->
            <div id="move"></div><!--移动的地方-->
        </div>
    </div>
</body>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

# 使用jquery进行代码实现

# 第一步 获取元素

//获取id
var btn = $('#btn');
var dv = $('#dv');
var box = $('#box');
var mask = $('#mask');
var look = $('#look');
var move = $('#move');
//定义图片的最大移动距离和跟着鼠标层的最大移动距离的变量
var imgMaxMove;
var maskMaxMove;
1
2
3
4
5
6
7
8
9
10

# 第二步 注册按钮点击事件

  • 点击按钮的时候显示遮罩层,同时也显示出来随着鼠标移动的框框,显示出来图片显示的位置。
  • 显示遮罩层的时候截图
  • 点击遮罩层的时候遮罩层消失
//给按钮注册点击事件
btn.on('click',function(){
    //截屏功能
    takeScreenshot();
    //遮罩层显示
    dv.css('display','block');
});

//点击屏幕的时候就消除
dv.on('click',function(){
    $(this).css('display','none');
})
1
2
3
4
5
6
7
8
9
10
11
12

# 第三步 截屏功能

function takeScreenshot() {
   //根据body进行截屏
   html2canvas(bd, {
      allowTaint: true, //允许跨域
      taintTest: false,  //渲染图片不用测试图片
      //渲染图片
      onrendered: function(canvas) {
           //将canvas标签转化为img标签
           canvas.id = 'cv';
           var dataUrl = canvas.toDataURL();
           var newImg = document.createElement("img");
           newImg.src = dataUrl;
           //设置图片的长和宽
           newImg.width = 4 * bd.width();
           newImg.height = 4* bd.height();
           //把图片的长宽赋值给外面的盒子
           move.width(newImg.width);
           move.height(newImg.height);
           //把图片加到盒子上
           move.append(newImg);
        },
    });
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 第四步 注册鼠标移动事件

  • 不考虑兼容的问题,使用clientX
  • 确定不要让跟着鼠标的小块出了屏幕,给它设定范围
  • 比例这个东西啊,因为之前截屏的时候,长度就进行了扩大,所以比例也不好掌握,后面自己慢慢的调。。。总会差不多的。(给自己留的bug
//给鼠标注册移动事件
dv.on('mousemove',function(e){
   var left = e.clientX - mask.width() / 2;//横坐标
    var top = e.clientY - mask.height() / 2;//纵坐标
    //设置遮挡层的left和top
    var x = left;
    var y = top;

    x=x<0?0:x;//如果横坐标小于0就设置为0
    y=y<0?0:y;//如果纵坐标小于0就设置为0
    x=x>box.width()-mask.width()?box.width()-mask.width():x;
    y=y>box.height()-mask.height()?box.height()-mask.height():y;

    //确定跟着鼠标动的小块的定位值
    mask.offset({"left":x,"top":y});

    //大图的最大的移动距离
    imgMaxMove=newImg.width-look.width();
    //遮挡层的最大的移动距离
    maskMaxMove=box.width()-mask.width();

    //大图的横向移动的距离
    var imgMoveLeft=x*maskMaxMove/imgMaxMove*9;
    //大图的纵向移动的距离
    var imgMoveTop=y*maskMaxMove/imgMaxMove*9;
    // 给大图设定移动位置
    move.css("marginLeft",-imgMoveLeft);
    move.css("marginTop",-imgMoveTop);
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# 第五步 给屏幕上动态的添加元素

  • 点击添加图标的时候,在屏幕上随机的添加一个图标
  • 可以在文本框中输入文字信息
 $('#jb').on('click',function(){
    var img = document.createElement('img');
    img.src = 'images/jb.jpg';
    img.width = 100;
    img.height = 100;
    var leftRandom = Math.random()*1366; //随机生成横坐标
    var topRandom = Math.random()*768; //随机生成纵坐标
    img.style.position = 'absolute';
    img.style.left = leftRandom + 'px';
    img.style.top = topRandom + 'px';
    $('#show').append(img);
})
1
2
3
4
5
6
7
8
9
10
11
12
更新时间: 2021-09-15 12:03