首先添加zoom.js

(function (root, factory) {
if (typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if (typeof define === 'function' && define.amd)
define([], factory);
else if (typeof exports === 'object')
exports["Zoom"] = factory();
else
root["Zoom"] = factory();
})(this, function () {

/**
* 简洁的元素缩放功能。
* @param {[type]} el 要缩放的元素
* @param {[type]} option {windth:元素宽度(必须),height:元素高度(必须),minScale:最小缩放比例,maxScale:最大缩放比例,top:原始位置,left:原始位置}
*/
function Zoom(el, option) {
if (!option || !option.width || !option.height) {
throw "dom的尺寸参数错误";
}
option = Object.assign({
minScale: 1,
maxScale: 3,
top: 0,
left: 0
}, option);

this.el = el;

this.lastSapce = 0;
this.touchState = 0;
this.lastPoint = null
this.targetPoint = null;

//放大缩小的倍数 当前缩放倍数
this.minScale = option.minScale || 1;
this.maxScale = option.maxScale || 10;

//dom的尺寸参数
this.width = option.width;
this.height = option.height;
this.top = option.top;
this.left = option.left;
this.scale = 1;

//初始位置 以及 初始宽高
this.originTop = option.top;
this.originLeft = option.left;
this.originW = this.width;
this.originH = this.height;
//图片中心点
this.centerX = this.left + this.originW / 2;
this.centerY = this.top + this.originH / 2;

this.el.style.position = 'absolute';

this.init();
return this;
}

Zoom.prototype.getTouches = function (event) {
let touches = event.touches;
if (!touches) {
touches = event.originalEvent.touches;
}
return touches;
}

Zoom.prototype.getTouchsDistance = function (t1, t2) {

let dx = parseInt(t1.pageX - t2.pageX);
let dy = parseInt(t1.pageY - t2.pageY);

let d = Math.pow((dx * dx + dy * dy), 0.5);

return d.toFixed(5);
}

Zoom.prototype.restView = function () {
this.el.style.width = this.width + 'px';
this.el.style.height = this.height + 'px';
this.el.style.top = this.top + 'px';
this.el.style.left = this.left + 'px';
}

Zoom.prototype.init = function () {

this.el.addEventListener('touchmove', this.touchmoveHandler);
this.el.addEventListener('touchstart', this.touchmoveHandler);
this.el.addEventListener('touchend', this.touchEndHandler);
this.el.addEventListener('touchcancel', this.touchEndHandler);
this.el.addEventListener('touchstart', this.dbclickHandler);
this.el.zoom = this;

}
Zoom.prototype.dbclickHandler = function (event) {
event.stopPropagation();
event.preventDefault();
let el = event.currentTarget;
let zoom = el.zoom;
let time = new Date(event.timeStamp).getTime();
let touchs = zoom.getTouches(event);
if (touchs.length == 1) {
if (!el.lastClickTime) {
el.lastClickTime = time;
} else {
if (time - el.lastClickTime < 300) {
el.lastClickTime = 0;
if (zoom.scale != 1) {
zoom.setScale(1);
} else if (zoom.scale == 1) {
zoom.setScale(2);
}
} else {
el.lastClickTime = time;
}
}
}
zoom.touchStartTime = new Date().getTime();
return false;
},
Zoom.prototype.drage = function (touch) {
if (this.lastPoint == null) {
this.lastPoint = {
x: touch.pageX,
y: touch.pageY,
}
} else {
let dx = parseInt(touch.pageX - this.lastPoint.x);
let dy = parseInt(touch.pageY - this.lastPoint.y);

this.lastPoint.x = touch.pageX;
this.lastPoint.y = touch.pageY;

this.left += dx;
this.top += dy;

this.setTransform(false);
}
}

Zoom.prototype.zoom = function (touchs) {

this.lastPoint = null;
let t1 = touchs[0];
let t2 = touchs[1];

let x1 = t1.pageX;
let x2 = t2.pageX;
let y1 = t1.pageY;
let y2 = t2.pageY;

let d = this.getTouchsDistance(t1, t2);

if (this.touchState == 0) {
this.lastSapce = d;
this.touchState = 1;

this.pointX = (x2 + (x1 - x2) / 2 - this.left) / this.scale;
this.pointY = (y2 + (y1 - y2) / 2 - this.top) / this.scale;

} else if (this.touchState == 1) {

let scaleChange = ((d / this.lastSapce) - 1) * 2;

let scale = this.scale + scaleChange / 2;

this.setScale(scale, this.pointX, this.pointY);

this.lastSapce = d;
}
}

Zoom.prototype.touchmoveHandler = function (event) {

event.stopPropagation();
event.preventDefault();
let el = event.currentTarget;
let zoom = el.zoom;
let touchs = zoom.getTouches(event);
if (touchs.length == 1) {
zoom.drage(touchs[0]);//拖动处理
} else if (touchs.length >= 2) {
zoom.lastPoint = null;//终止拖动事件
zoom.zoom(touchs);//缩放处理

}

return false;
}

Zoom.prototype.touchEndHandler = function (event) {
let zoom = event.currentTarget.zoom;

zoom.touchState = 0;
zoom.lastPoint = null;
zoom.lastSapce = 0;

let minSpace = 20;
let parentWidth = zoom.el.parentElement.offsetWidth;
let parentHight = zoom.el.parentElement.offsetHeight;
let scale = zoom.scale;

if (scale < zoom.minScale) {
scale = zoom.minScale;
}
if (scale > zoom.maxScale) {
scale = zoom.maxScale;
}

if (scale != zoom.scale) {
zoom.preSetScale(scale, zoom.lastPointX, zoom.lastPointY);
}

if ((zoom.left + zoom.width) < minSpace) {
zoom.left = - zoom.width + minSpace;
}
if (zoom.left >= (parentWidth - minSpace)) {
zoom.left = parentWidth - minSpace;
}

if ((zoom.top + zoom.height) < minSpace) {
zoom.top = - zoom.height + minSpace;
}
if (zoom.top >= (parentHight - minSpace)) {
zoom.top = parentHight - minSpace;
}

zoom.setTransform(true);

return;
}
Zoom.prototype.setTransform = function (needAnimation, originX, originY) {
let distanceX = this.left - this.originLeft;
let distanceY = this.top - this.originTop;
let scale = this.scale;
originX = originX == undefined ? (this.originTop + 'px') : originX;
originY = originY == undefined ? (this.originLeft + 'px') : originY;
this.el.style.transformOrigin = 'left top';
this.el.style.transform = 'matrix(' + scale + ',0,0,' + scale + ',' + distanceX + ',' + distanceY + ')';
if (needAnimation == true) {
this.el.style.transition = 'all .3s ease-in-out 0s'
} else {
this.el.style.transition = ''
}
}

Zoom.prototype.destroy = function () {

this.el.removeEventListener('touchmove', this.touchmoveHandler);
this.el.removeEventListener('touchstart', this.touchmoveHandler);
this.el.removeEventListener('touchend', this.touchEndHandler);
this.el.removeEventListener('touchcancel', this.touchEndHandler);

this.el.zoom = null;
}
//初始化放大倍数
Zoom.prototype.setScale = function (scale, pointX, pointY) {
this.preSetScale(scale, pointX, pointY);
this.setTransform(false);
}

Zoom.prototype.preSetScale = function (scale, pointX, pointY) {

if (scale < 0.1) {
scale = 0.1;
}

if (pointX == undefined) {
this.left = this.centerX - this.originW / 2 - this.originW / 2 * (scale - 1);
this.top = this.centerY - this.originH / 2 - this.originH / 2 * (scale - 1);

this.width = scale * this.originW;
this.height = scale * this.originH;

this.scale = scale;
} else {
this.width = scale * this.originW;
this.height = scale * this.originH;

this.left = this.left - pointX * (scale - this.scale);
this.top = this.top - pointY * (scale - this.scale);

this.lastPointX = pointX;
this.lastPointY = pointY;

this.scale = scale;
}

}

return Zoom;
});

下面是参考模板

<style>

#paper {
width: 100%;
height: 3100px;
overflow: hidden;
position: relative; /*重点*/
}

#detailBody {
position: absolute; /*重点*/
width: 100%;
height: 100%;
left: 0px;
top: 0px;
}

</style>

<script type="text/javascript">

$(function () {

var zoomEl = document.getElementById('detailBody');
var zoom = new Zoom(zoomEl, { 'top': 0, 'left': 0, 'width': $("#detailBody").width(), 'height': $("#detailBody").height() });
zoom.setScale(1);

});

</script>

<div id="paper" style="margin-top: 30px;">
<div class="layui-card-body" style="padding: 10px;" id="detailBody">

</div>
</div>

转载于:https://www.cnblogs.com/niuniu0108/p/11468195.html

h5移动端局部放大效果相关推荐

  1. html手机页面弹幕效果,H5移动端弹幕动画实现

    需求 已知20条内容要有弹幕效果,分成三层,速度随机. 先来看看效果: 小小弹幕效果.gif 所以这里不考虑填写生成的.只是一个展现的效果. 如果要看填写生成的,请不要浪费Time 思路把单个内容编辑 ...

  2. php清除h5格式,移动端H5页面端怎样除去input输入框的默认样式

    这次给大家带来移动端H5页面端怎样除去input输入框的默认样式,移动端H5页面端除去input输入框的默认样式的注意事项有哪些,下面就是实战案例,一起来看一下. 前两天在开发在微信访问的HTML5页 ...

  3. html5首页图标怎么除掉,移动端H5页面端如何除去input输入框的默认样式

    移动端H5页面端如何除去input输入框的默认样式 发布时间:2020-09-29 16:41:58 来源:亿速云 阅读:124 作者:小新 这篇文章主要介绍了移动端H5页面端如何除去input输入框 ...

  4. H5 移动端二维码扫描

    H5 移动端二维码扫描-附加扫描样式 依赖包jsQR 思路:通过浏览器获取视频流播放在video当中,然后设置定时器截取视频流绘制在canvas中,使用canvas获取到图片信息,再使用jsQR解析二 ...

  5. H5移动端知识点总结

    H5移动端知识点总结 阅读目录 移动开发基本知识点 calc基本用法 box-sizing的理解及使用 理解display:box的布局 理解flex布局 Flex布局兼容知识点总结 回到顶部 移动开 ...

  6. H5移动端div固定到底部实现底部导航条的几种方式

    H5移动端div固定到底部实现底部导航条的几种方式 需求: 需要把导航固定在底部?只能滑动内容,导航菜单固定不动的.效果如下: 这篇文章主要讲解三种实现方案,包括:fixed,absolute,以及c ...

  7. h5/wap端调试、移动端调试 / vconsole、eruda、spy-debugger

    关于h5调试 一.vconsole,类似小程序的调试工具,可以在手机上看见打印,真机调试h5时,我们只能看alert,但有些内容无法alert,但vconsole能做到,就像谷歌的f12一样 用法,页 ...

  8. 移动端css hover效果,css移动端:acitve效果的实现

    做移动前端也有一些日子了,一直有个问题没有解决,就是与pc端那样的一个:hover的效果,:hover是鼠标指针浮动在其上的元素的一个选择器,但因为在移动端是没有鼠标的,代替的是触摸屏,用户也不是有& ...

  9. 雪狐html5,【干货】如何实现H5移动端无缝滚动动画

    原标题:[干货]如何实现H5移动端无缝滚动动画 需求分析 哈哈,上动态图真的是一下就明了了. 就是滚动么滚动,那么制作这个有什么方法呢?我们来总结一下: html骨架 其实很简单,最外面的 是做固定的 ...

最新文章

  1. 高温预警c语言,注意 | 高温预警来了!最高38°C!高温7连击!
  2. 简单的小程序实现ATM机操作
  3. Java纸牌拖拉机简单模拟
  4. java并发编程之美-阅读记录1
  5. 贪心(用了结构体排序)
  6. H5网页播放器播不了服务器上的mp4视频文件
  7. GitHub 最受欢迎的Top 20 JavaScript 项目
  8. CSS英文单词强制换行
  9. 随想录(嵌入式工程师的出路)
  10. 打牢Python基础,看看这10语法如何
  11. 【leveldb】整体架构
  12. quick-cocos2d-x 游戏开发——StateMachine 状态机
  13. 我的世界服务器物品箱子,我的世界:使用箱子储存物品居多,难不成他们很“鸡肋”?...
  14. C语言:鸡兔同笼(随机输入头数和脚数)
  15. 精彩泄漏截图 2006最值得期待的游戏
  16. 业务的转型能让大象重新跳舞吗?
  17. 游戏设计模式阅读笔记18——优化模式(对象池模式)
  18. 不见的何止重城,隐隐的又岂是江树。
  19. 重磅更新丨zCloud 数据库云管平台 v2.5
  20. 安全集群访问非安全集群问题记录

热门文章

  1. 30 行 Javascript 代码搞定智能家居系统
  2. 16.通过实现“函数一个返回值出口,返回两个返回值”。来了解指针与普通地址的区别...
  3. 关于Go语言,你可能会讨厌的五件事
  4. 【探索PowerShell 】【十二】筛选器 - Filters
  5. Exchange 2010 批量移动邮箱和增加移动请求并发数
  6. 【Objective-C】05-第一个OC的类
  7. html里,实现图片与文字对齐的最简洁方法
  8. 解决SQLServer事物日志过大的方法
  9. win7下PHP运行环境搭建(apache2+mysql+php)
  10. Linux救援模式实战