Browse Source

更新图片组件

pull/19/head
zyronon 3 years ago
parent
commit
f9c2323584
  1. 7
      src/pages/test/Test.vue
  2. 151
      src/pages/test/TestImg.vue
  3. 241
      src/pages/test/pinch.html

7
src/pages/test/Test.vue

@ -1,7 +1,8 @@ @@ -1,7 +1,8 @@
<template>
<!-- <TestSlide></TestSlide>-->
<!-- <SlideUser></SlideUser>-->
<SlideImgs></SlideImgs>
<!-- <SlideImgs></SlideImgs>-->
<TestImg/>
</template>
<script>
@ -9,13 +10,15 @@ @@ -9,13 +10,15 @@
import TestSlide from "./TestSlide";
import SlideUser from "../../components/slide/SlideUser";
import SlideImgs from "../../components/slide/SlideImgs";
import TestImg from "./TestImg";
export default {
name: "Test",
components: {
TestSlide,
SlideUser,
SlideImgs
SlideImgs,
TestImg
},
}
</script>

151
src/pages/test/TestImg.vue

@ -0,0 +1,151 @@ @@ -0,0 +1,151 @@
<template>
<div id="TestImg">
<img ref="img" src="../../assets/img/poster/0.jpg" alt=""
@touchstart="start"
@touchmove="move"
@touchend="end"
>
</div>
</template>
<script>
import globalMethods from "../../utils/global-methods";
export default {
name: "TestImg",
data() {
return {
result: {
width: 393,
height: 699
},
x: 0,
y: 0,
scale: 1,
maxScale: 3,
minScale: 0.5,
point1: {x: 0, y: 0},
point2: {x: 0, y: 0},
diff: {x: 0, y: 0},
lastPointermove: {x: 0, y: 0},
lastPoint1: {x: 0, y: 0},
lastPoint2: {x: 0, y: 0},
lastCenter: {x: 0, y: 0},
touches: [],
}
},
created() {
},
mounted() {
},
methods: {
getCenter(a, b) {
const x = (a.x + b.x) / 2;
const y = (a.y + b.y) / 2;
return {x, y}
},
getDistance(start, stop) {
return Math.hypot(stop.x - start.x, stop.y - start.y);
},
handlePointers(e, type) {
for (let i = 0; i < this.touches.length; i++) {
if (this.touches[i].pointerId === e.pointerId) {
if (type === 'update') {
this.touches[i] = e;
} else if (type === 'delete') {
this.touches.splice(i, 1);
}
}
}
},
start(e) {
// console.log('start')
if (e.touches && e.touches.length === 1) {
} else {
this.isTwo = true
this.$refs.img.style['transition-duration'] = '0ms';
let events = e.touches[0];
let events2 = e.touches[1];
this.lastPoint1 = this.point1 = {x: events.pageX, y: events.pageY};
this.lastPoint2 = this.point2 = {x: events2.pageX, y: events2.pageY};
this.lastCenter = this.getCenter(this.lastPoint1, this.lastPoint2)
// console.log('lastPoint1', this.lastPoint1)
}
},
move(e) {
if (e.touches && e.touches.length === 1) {
} else {
this.isTwo = true
let current1 = {x: e.touches[0].pageX, y: e.touches[0].pageY}
let current2 = {x: e.touches[1].pageX, y: e.touches[1].pageY}
//
let ratio = this.getDistance(current1, current2) / this.getDistance(this.lastPoint1, this.lastPoint2);
this.scale = this.scale * ratio
//
// let center = this.getCenter(current1, current2)
// console.log('center', center)
// transform-origin: 50% 50%
// transform-origin: 30% 40%origin.x = (ratio - 1) * result.width * 0.3
// origin.y = (ratio - 1) * result.height * 0.4
// 使transformtransform-origin
// origin(ratio - 1) * result.width * 0 = 0
// const origin = {
// x: (ratio - 1) * this.result.width * 0.5,
// y: (ratio - 1) * this.result.height * 0.5
// };
// ()
// this.x -= (ratio - 1) * (center.x - this.x) - origin.x - (center.x - this.lastCenter.x);
// this.y -= (ratio - 1) * (center.y - this.y) - origin.y - (center.y - this.lastCenter.y);
// console.log('this.x', this.x)
// console.log('this.y', this.y)
//
this.$refs.img.style.transform =
// `translate3d(${this.x}px,${this.y}px,0) scale(${this.scale})`;
`scale(${this.scale})`;
// this.lastCenter = {x: center.x, y: center.y};
this.lastPoint1 = {x: current1.x, y: current1.y};
this.lastPoint2 = {x: current2.x, y: current2.y};
}
},
end(e) {
// console.log('end', e)
//
this.scale = 1
this.x = this.y = 0
this.$refs.img.style.transform =
`translate3d(0px,0px,0) scale(1)`;
// this.point1 = {x: e.touches[0].pageX, y: e.touches[0].pageY}
}
}
}
</script>
<style scoped lang="less">
</style>
<style scoped lang="less">
#TestImg {
height: 100%;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
}
img {
width: 100%;
}
</style>

241
src/pages/test/pinch.html

@ -1,241 +0,0 @@ @@ -1,241 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<title>pinch</title>
<style>
* {
margin: 0;
padding: 0;
}
.container {
height: 100vh;
background: #000;
overflow: hidden;
}
img {
touch-action: none;
}
.log {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 99;
padding: 5px;
color: #FFF;
font-size: 12px;
line-height: 18px;
pointer-events: none;
}
</style>
</head>
<body>
<div class="container">
<img id="image" alt="">
</div>
<div class="log"></div>
<script>
// 获取dom
const image = document.getElementById('image');
const log = document.querySelector('.log');
// 全局变量
let result,
x,
y,
scale = 1,
maxScale,
minScale = 0.5;
// 图片加载完成后再操作,否则naturalWidth为0
image.addEventListener('load', function () {
result = getImgSize(image.naturalWidth, image.naturalHeight, window.innerWidth, window.innerHeight);
image.style.width = result.width + 'px';
image.style.height = result.height + 'px';
x = (window.innerWidth - result.width) * 0.5;
y = (window.innerHeight - result.height) * 0.5;
image.style.transform = 'translate3d(' + x + 'px, ' + y + 'px, 0) scale(1)';
maxScale = Math.max(Math.round(image.naturalWidth / result.width), 3);
log.innerHTML = `x = ${x.toFixed(0)}<br>y = ${y.toFixed(0)}<br>scale = ${scale.toFixed(5)}`;
});
image.src = 'http://jsdemo.codeman.top/images/liya.jpg';
/**
* 获取图片缩放尺寸
* @param {number} naturalWidth
* @param {number} naturalHeight
* @param {number} maxWidth
* @param {number} maxHeight
* @returns
*/
function getImgSize(naturalWidth, naturalHeight, maxWidth, maxHeight) {
const imgRatio = naturalWidth / naturalHeight;
const maxRatio = maxWidth / maxHeight;
let width, height;
// 如果图片实际宽高比例 >= 显示宽高比例
if (imgRatio >= maxRatio) {
if (naturalWidth > maxWidth) {
width = maxWidth;
height = maxWidth / naturalWidth * naturalHeight;
} else {
width = naturalWidth;
height = naturalHeight;
}
} else {
if (naturalHeight > maxHeight) {
width = maxHeight / naturalHeight * naturalWidth;
height = maxHeight;
} else {
width = naturalWidth;
height = naturalHeight;
}
}
return { width: width, height: height }
}
// 全局变量
let isPointerdown = false, // 按下标识
pointers = [], // 触摸点数组
point1 = { x: 0, y: 0 }, // 第一个点坐标
point2 = { x: 0, y: 0 }, // 第二个点坐标
diff = { x: 0, y: 0 }, // 相对于上一次pointermove移动差值
lastPointermove = { x: 0, y: 0 }, // 用于计算diff
lastPoint1 = { x: 0, y: 0 }, // 上一次第一个触摸点坐标
lastPoint2 = { x: 0, y: 0 }, // 上一次第二个触摸点坐标
lastCenter; // 上一次中心点坐标
// 绑定 pointerdown
image.addEventListener('pointerdown', function (e) {
pointers.push(e);
point1 = { x: pointers[0].clientX, y: pointers[0].clientY };
if (pointers.length === 1) {
isPointerdown = true;
image.setPointerCapture(e.pointerId);
lastPointermove = { x: pointers[0].clientX, y: pointers[0].clientY };
} else if (pointers.length === 2) {
point2 = { x: pointers[1].clientX, y: pointers[1].clientY };
lastPoint2 = { x: pointers[1].clientX, y: pointers[1].clientY };
lastCenter = getCenter(point1, point2);
}
lastPoint1 = { x: pointers[0].clientX, y: pointers[0].clientY };
});
// 绑定 pointermove
image.addEventListener('pointermove', function (e) {
if (isPointerdown) {
handlePointers(e, 'update');
const current1 = { x: pointers[0].clientX, y: pointers[0].clientY };
if (pointers.length === 1) {
diff.x = current1.x - lastPointermove.x;
diff.y = current1.y - lastPointermove.y;
lastPointermove = { x: current1.x, y: current1.y };
x += diff.x;
y += diff.y;
image.style.transform = 'translate3d(' + x + 'px, ' + y + 'px, 0) scale(' + scale + ')';
log.innerHTML = `x = ${x.toFixed(0)}<br>y = ${y.toFixed(0)}<br>scale = ${scale.toFixed(5)}`;
} else if (pointers.length === 2) {
const current2 = { x: pointers[1].clientX, y: pointers[1].clientY };
// 计算相对于上一次移动距离比例 ratio > 1放大,ratio < 1缩小
let ratio = getDistance(current1, current2) / getDistance(lastPoint1, lastPoint2);
// 缩放比例
const _scale = scale * ratio;
if (_scale > maxScale) {
scale = maxScale;
ratio = maxScale / scale;
} else if (_scale < minScale) {
scale = minScale;
ratio = minScale / scale;
} else {
scale = _scale;
}
// 计算当前双指中心点坐标
const center = getCenter(current1, current2);
// 计算图片中心偏移量,默认transform-origin: 50% 50%
// 如果transform-origin: 0% 0%,那origin.x = (ratio - 1) * result.width * 0
// origin.y = (ratio - 1) * result.height * 0
// 如果transform-origin: 30% 40%,那origin.x = (ratio - 1) * result.width * 0.3
// origin.y = (ratio - 1) * result.height * 0.4
const origin = { x: (ratio - 1) * result.width * 0.5, y: (ratio - 1) * result.height * 0.5 };
// 计算偏移量
x -= (ratio - 1) * (center.x - x) - origin.x - (center.x - lastCenter.x);
y -= (ratio - 1) * (center.y - y) - origin.y - (center.y - lastCenter.y);
image.style.transform = 'translate3d(' + x + 'px, ' + y + 'px, 0) scale(' + scale + ')';
lastCenter = { x: center.x, y: center.y };
lastPoint1 = { x: current1.x, y: current1.y };
lastPoint2 = { x: current2.x, y: current2.y };
log.innerHTML = `x = ${x.toFixed(0)}<br>y = ${y.toFixed(0)}<br>
scale = ${scale.toFixed(5)}<br>
centerX = ${center.x.toFixed(0)}<br>centerY = ${center.y.toFixed(0)}<br>`;
}
}
e.preventDefault();
});
// 绑定 pointerup
image.addEventListener('pointerup', function (e) {
if (isPointerdown) {
handlePointers(e, 'delete');
if (pointers.length === 0) {
isPointerdown = false;
} else if (pointers.length === 1) {
point1 = { x: pointers[0].clientX, y: pointers[0].clientY };
lastPointermove = { x: pointers[0].clientX, y: pointers[0].clientY };
}
}
});
// 绑定 pointercancel
image.addEventListener('pointercancel', function (e) {
if (isPointerdown) {
isPointerdown = false;
pointers.length = 0;
}
});
/**
* 更新或删除指针
* @param {PointerEvent} e
* @param {string} type
*/
function handlePointers(e, type) {
for (let i = 0; i < pointers.length; i++) {
if (pointers[i].pointerId === e.pointerId) {
if (type === 'update') {
pointers[i] = e;
} else if (type === 'delete') {
pointers.splice(i, 1);
}
}
}
}
/**
* 获取两点间距离
* @param {object} a 第一个点坐标
* @param {object} b 第二个点坐标
* @returns
*/
function getDistance(a, b) {
const x = a.x - b.x;
const y = a.y - b.y;
return Math.hypot(x, y); // Math.sqrt(x * x + y * y);
}
/**
* 获取中点坐标
* @param {object} a 第一个点坐标
* @param {object} b 第二个点坐标
* @returns
*/
function getCenter(a, b) {
const x = (a.x + b.x) / 2;
const y = (a.y + b.y) / 2;
return { x: x, y: y };
}
</script>
</body>
</html>
Loading…
Cancel
Save