将图像悬停并在画布元素中显示光标周围区域的缩放版本

Hover an image and show a zoomed version of an area around the cursor in a canvas element?

本文关键字:光标 显示 周围 区域 版本 缩放 元素 悬停 图像 布元素      更新时间:2023-09-26

我在一个较旧的项目中使用Magnify.js (http://mark-rolich.github.io/Magnifier.js/),并希望远离它,因为它非常复杂。

我试图通过重构和阅读一些关于这个主题的文章来构建我自己的图像缩放功能,但老实说,代码不会去任何地方,因此我删除了它,因为它当时的无能。

无论如何,对于手头的问题,这是我希望发生的事情:

  1. 我将图像悬停在一个特定的css类
  2. 画布元素只有当带有该类的图像悬停在屏幕上时才会出现
  3. 在canvas元素
  4. 中显示了光标周围区域(100px x 100px)的放大版本
  5. 当光标在图像周围移动时,画布会实时更新,以显示如上所述的新悬停区域的缩放部分
  6. 鼠标悬停时,画布项再次隐藏

听起来很简单,但我对这个问题的看法远非如此。

所以,我的问题,简而言之:有没有其他简单的框架,除了放大。js(如上所述),你知道,我可以检查,或者如果它是足够简单的做,我只是过于复杂,你会怎么去的问题?

使用框架是一个好主意,因为它解决了跨浏览器的问题,是一个功能更全面的解决方案,而不是你可以从头开始编写的代码。

无论如何,如果你的需求非常有限,你可以自己做。顺便说一句,你没有用jQuery标记问题,但我会假设你正在使用它。

我认为你不需要使用画布。而不是:

  1. 将图像放置两次,第二次放置在隐藏的容器中。
  2. 缩小第一个,这样你就可以使用缩略图。
  3. 第二个保持原来的大小,但要确保容器有overflow: hidden
  4. 创建mousemove事件。它需要使容器可见
  5. e.pageX / e.pageY$( element ).offset()检测鼠标在图片中的位置
  6. 计算缩略图的面积与原始图片的大小之比
  7. 每次移动光标时,按计算出的比例修改原尺寸图片(容器内图片)的边距。
  8. 创建隐藏容器的mouseout事件

这里有一个片段:

var zoom_container_size = $( '.zoom_container').height();
var zoom_area_size = 100;
var zoom_radius = zoom_area_size / 2;
$( '.thumbnail' ).mousemove(function(e) {
    // Show original picture    
    var $original = $( '#' + this.id + '_original');
    var $container = $original.parent();
    $container.removeClass( 'hidden' );
    // Thumbnail
    var offset = $( this ).offset();
    var tX = e.pageX - offset.left;
    var tY = e.pageY - offset.top;
    // We stay inside the limits of the zoomable area
    tX = Math.max( zoom_radius, Math.min( $( this ).width() - zoom_radius, tX ) );
    tY = Math.max( zoom_radius, Math.min( $( this ).height() - zoom_radius, tY ) );
    // Ratios
    var ratioX = ( $original.width() - zoom_container_size) / ( $( this ).width() - zoom_area_size );
    var ratioY = ( $original.height() - zoom_container_size) / ( $( this ).height() - zoom_area_size );
    // Margin to be set in the original    
    var moX = -Math.floor( ( tX - zoom_radius ) * ratioX );
    var moY = -Math.floor( ( tY - zoom_radius ) * ratioY );
    // Apply zoom efect
    $original.css( 'marginLeft', moX );
    $original.css( 'marginTop', moY );
    // Log values
    $('#ratios').html( 'Ratio X: <b>' + ratioX + '</b><br>Ratio Y: <b>' +  ratioY + '</b>' );
    $('#coordinates_thumbnail').html( 'tX: <b>' + tX + '</b><br>tY: <b>' +  tY + '</b>' );
    $('#coordinates_original' ).html( 'Margin left: <b>' + Math.round(moX) + '</b><br>Margin top: <b>' +  moY + '</b>' );
});
$( '.thumbnail' ).mouseout(function(e) {
    var $original = $( '#' + this.id + '_original');
    var $container = $original.parent();
    $container.addClass( 'hidden' );
});
.main_container div {
    display: inline-block;
}
.thumbnail {
    height: 200px;
}
div.zoom_container {
    width: 200px;
    height: 200px;
    overflow: hidden;
}
.zoom_container.hidden {
    display: none;    
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
A beautiful pic from <a href="https://commons.wikimedia.org/wiki/File:Talv_V%C3%A4ike-Taevaskojas.jpg">Külli Kolina</a>.
<div id="zoom_area"></div>
<div class="main_container">
    <img id="forest" class="thumbnail" src="https://upload.wikimedia.org/wikipedia/commons/thumb/f/fd/Talv_V%C3%A4ike-Taevaskojas.jpg/640px-Talv_V%C3%A4ike-Taevaskojas.jpg">
    <div class="zoom_container hidden">
        <img id="forest_original" class="original" src="https://upload.wikimedia.org/wikipedia/commons/thumb/f/fd/Talv_V%C3%A4ike-Taevaskojas.jpg/640px-Talv_V%C3%A4ike-Taevaskojas.jpg">
    </div>
</div>
<hr><span id="ratios">Ratios</span>
<hr><span id="coordinates_thumbnail">Coordinates</span>
<hr><span id="coordinates_original">Negative margin</span>

在这段代码中有很多可以优化的东西(主要是与从事件处理程序中获得一些工作有关)以获得更平滑的效果,但是现在您已经有了开始工作的基础。如果你真的关心性能,你可以阅读另一个答案(主题不同,但大多数想法适用于相同的方式)。

希望有帮助!