electron学习笔记如何通过electron实现图片查看器

寸阳分阴须爱惜,休负春色与时光。这篇文章主要讲述electron学习笔记如何通过electron实现图片查看器相关的知识,希望能为你提供帮助。
前言
对于图片查看器,在实践中做了两种方案的对比。
第一种是借助 canvas 的方案,如果使用 canvas 会生成一张静态图片, 并且操作 canvas 旋转时,旋转后的坐标比较难计算,对于计算图片的放大缩小有一定的难度。
第二种是 “img+css+js” 的组合方案,可以支持 gif 的动态图片。
相比之下,img 只需要操作 css,其旋转后的坐标也比较容易计算,并且旋转使用了transform 来提高渲染的性能。


下面来介绍一下  “img+css+js”  组合方案的实现方式。


实现效果

electron学习笔记如何通过electron实现图片查看器

文章图片
v-show="link & & !imageLoad"
:
:
@load="onload"
class="imageSrc"
:style="position"
id="imgSrc"
/>
< img src="https://www.songbingjia.com/img/loading.gif" class="img-loading" v-show="imageLoad" />
< div class="pre" @click.stop="optHandle(pre)" :title="preTip" :style="show">
< i class="iconfont icon icon-prev"> < /i>
< /div>
< div class="next" @click.stop="optHandle(next)" :title="nextTip" :style="show">
< i class="iconfont icon icon-next"> < /i>
< /div>
< /div>
< div class="image-opt">
...
< /div>
< /main>


核心功能
放大缩小的难点在于,需要随鼠标放大、缩小、旋转后的坐标变换。
1、先记录鼠标的位置?
// 滚轮放大缩小
imageView.onmousewheel = imageView.onwheel = (event: any) =>
// 记录当前鼠标的位置
const imageView: any = document.getElementById("image-view");
const box = imageView.getBoundingClientRect();
const tempPos =
x: event.x - box.left,
y: event.y - box.top,
;
const x = position.left.substring(0, position.left.indexOf("px"));
const y = position.top.substring(0, position.left.indexOf("px"));
startPointX.value = https://www.songbingjia.com/android/Number(((pos.x - Number(x)) / imgScale.value).toFixed(2));
startPointY.value = https://www.songbingjia.com/android/Number(((pos.y - Number(y)) / imgScale.value).toFixed(2));
pos.x = tempPos.x;
pos.y = tempPos.y;
if (event.wheelDelta > 0)
increase();
else
decrease();

;



2、放大?
/**
* @description: 放大
* @param *
* @return *
*/
const increase = () =>
const image = imageArr[index.value];
if (imgScale.value =https://www.songbingjia.com/android/= 15)
return;

let rR = imgScale.value + 0.1;
if (rR > 15)
rR = 15;

const width = image.width * rR;
const height = image.height * rR;
const [wrapW, wrapH] = getRect();
let x = (1 - rR) * startPointX.value + (pos.x - startPointX.value);
let y = (1 - rR) * startPointY.value + (pos.y - startPointY.value);
if (rotateIndex.value % 2 == 0)
//console.log(height, wrapW, wrapH, width, x, y);
if (width < = wrapW)
x = (wrapW - width) / 2;
else if (width > = wrapW & & x > 0)
x = 0;
else if (width + x < wrapW)
x = wrapW - width;

if (height < = wrapH)
y = (wrapH - height) / 2;
else if (height > = wrapH & & y > 0)
y = 0;
else if (height + y < wrapH)
y = wrapH - height;

else
const abs = Math.abs(width / 2 - height / 2);
let X = 0;
let Y = 0;
if (imgWidth.value < imgHeight.value)
X = x - abs;
Y = y + abs;
else
X = x + abs;
Y = y - abs;

if (height < = wrapW)
x = (wrapW - width) / 2;
else if (height > = wrapW & & X > 0)
if (imgWidth.value < imgHeight.value)
x = +abs;
else
x = -abs;

else if (height + X < = wrapW)
const mx = wrapW - height;
if (imgWidth.value < imgHeight.value)
x = mx + abs;
else
x = mx - abs;


if (width < = wrapH)
y = (wrapH - height) / 2;
else if (width > = wrapH & & Y > 0)
if (imgWidth.value < imgHeight.value)
y = -abs;
else
y = abs;

else if (width + Y < = wrapH)
const my = wrapH - width;
if (imgWidth.value < imgHeight.value)
y = my - abs;
else
y = my + abs;



imgScale.value = https://www.songbingjia.com/android/rR;
position.left = x + "px";
position.top = y + "px";
imgWidth.value = https://www.songbingjia.com/android/width;
imgHeight.value = https://www.songbingjia.com/android/height;
;



3、缩小?
/**
* @description: 缩小
* @param *
* @return *
*/
const decrease = () =>
const image = imageArr[index.value];
if (imgScale.value =https://www.songbingjia.com/android/= 0.01)
return;

let rR = imgScale.value - 0.1;
if (rR < 0.01)
rR = 0.01;

const width = image.width * rR;
const height = image.height * rR;
const [wrapW, wrapH] = getRect();
// 判断鼠标是否在图片上
let x = (1 - rR) * startPointX.value + (pos.x - startPointX.value);
let y = (1 - rR) * startPointY.value + (pos.y - startPointY.value);
if (rotateIndex.value % 2 == 0)
//console.log(height, wrapW, wrapH, width, x, y);
if (width < = wrapW)
x = (wrapW - width) / 2;
else if (width > = wrapW & & x > 0)
x = 0;
else if (width + x < wrapW)
x = wrapW - width;

if (height < = wrapH)
y = (wrapH - height) / 2;
else if (height > = wrapH & & y > 0)
y = 0;
else if (height + y < wrapH)
y = wrapH - height;

else
const abs = Math.abs(width / 2 - height / 2);
let X = 0;
let Y = 0;
if (imgWidth.value < imgHeight.value)
X = x - abs;
Y = y + abs;
else
X = x + abs;
Y = y - abs;

if (height < = wrapW)
x = (wrapW - width) / 2;
else if (height > = wrapW & & X > 0)
if (imgWidth.value < imgHeight.value)
x = +abs;
else
x = -abs;

else if (height + X < = wrapW)
const mx = wrapW - height;
if (imgWidth.value < imgHeight.value)
x = mx + abs;
else
x = mx - abs;


if (width < = wrapH)
y = (wrapH - height) / 2;
else if (width > = wrapH & & Y > 0)
if (imgWidth.value < imgHeight.value)
y = -abs;
else
y = abs;

else if (width + Y < = wrapH)
const my = wrapH - width;
if (imgWidth.value < imgHeight.value)
y = my - abs;
else
y = my + abs;



imgScale.value = https://www.songbingjia.com/android/rR;
position.left = x + "px";
position.top = y + "px";
imgWidth.value = https://www.songbingjia.com/android/width;
imgHeight.value = https://www.songbingjia.com/android/height;
;



4、移动
const imageV: any = document.getElementById("imgSrc");
imageV.onmousedown = (e: any) =>
e.preventDefault();
e.target.setAttribute("draggable", true);
e.target.style.cursor = "pointer";
const startX = e.clientX;
const startY = e.clientY;
const left = position.left;
const leftX = Number(left.substring(0, left.indexOf("px")));
const top = position.top;
const topX = Number(top.substring(0, top.indexOf("px")));
imageV.onmouseup = () =>
e.target.setAttribute("draggable", false);
e.target.style.cursor = "default";
imageV.onmouseup = null;
imageV.mouseleave = null;
imageV.onmousemove = null;
;
imageV.onmouseleave = () =>
e.target.setAttribute("draggable", false);
e.target.style.cursor = "default";
imageV.onmouseup = null;
imageV.mouseleave = null;
imageV.onmousemove = null;
;
imageV.onmousemove = (event: any) =>
const [w, h] = getRect();
const moveX = event.clientX;
const moveY = event.clientY;
let moveLeft = leftX + (moveX - startX);
let moveTop = topX + (moveY - startY);
const abs = Math.abs(imgWidth.value / 2 - imgHeight.value / 2);
let leftT = 0;
let topT = 0;
if (rotateIndex.value % 2 !== 0)
if (imgHeight.value < = w & & imgWidth.value < = h)
return;

if (imgWidth.value < imgHeight.value)
leftT = leftX - abs + (moveX - startX);
topT = topX + abs + (moveY - startY);
else
leftT = leftX + abs + (moveX - startX);
topT = topX - abs + (moveY - startY);

if (leftT > 0)
if (imgHeight.value < = w)
moveLeft = leftX;
else
moveLeft = abs;

else
if (imgHeight.value < = w)
moveLeft = leftX;
else if (leftT + imgHeight.value < w)
const ml = w - imgHeight.value;
if (imgWidth.value < imgHeight.value)
moveLeft = ml + abs;
else
moveLeft = ml - abs;



if (topT > 0)
if (imgWidth.value < = h)
moveTop = topX;
else
moveTop = abs;

else
if (imgWidth.value < = h)
moveTop = topX;
else if (topT + imgWidth.value < h)
//console.log(h - imgWidth.value);
const mT = h - imgWidth.value;
if (imgWidth.value < imgHeight.value)
moveTop = mT - abs;
else
moveTop = mT + abs;



else
if (imgWidth.value < = w & & imgHeight.value < = h)
return;

if (moveLeft > 0)
if (imgWidth.value < = w)
moveLeft = leftX;
else
moveLeft = 0;

else
if (imgWidth.value < = w)
moveLeft = leftX;
else if (moveLeft + imgWidth.value < w)
moveLeft = w - imgWidth.value;


if (moveTop > 0)
if (imgHeight.value < = h)
moveTop = topX;
else
moveTop = 0;

else
if (imgHeight.value < = h)
moveTop = topX;
else if (moveTop + imgHeight.value < h)
moveTop = h - imgHeight.value;



position.left = moveLeft + "px";
position.top = moveTop + "px";
;
;



5、旋转
/**
* @description: 旋转
* @param *
* @return *
*/
const rotate = () =>
rotateIndex.value = https://www.songbingjia.com/android/(rotateIndex.value + 1) % 4;
const deg = rotateIndex.value * 90;
const [w, h] = getRect();
const oW = imageArr[index.value].width;
const oH = imageArr[index.value].height;
let nowW = oW;
let nowH = oH;
let scale = 1;
// console.log(deg);
switch (deg)
case 180:
case 0:
if (oH > h)
scale = h / oH;
nowH = h;
nowW = oW * scale;

if (nowW > w)
scale = w / oW;
nowW = w;
nowH = oH * scale;

imgHeight.value = https://www.songbingjia.com/android/nowH;
imgWidth.value = https://www.songbingjia.com/android/nowW;
imgScale.value = https://www.songbingjia.com/android/scale;
// 位置
position.top = h / 2 - nowH / 2 + "px";
position.left = w / 2 - nowW / 2 + "px";
position.transform = `rotate($-degdeg)`;
break;

case 90:
case 270:
if (oW > h)
scale = h / oW;
nowW = h;
nowH = oH * scale;

if (nowH > w)
scale = w / oH;
nowH = w;
nowW = oW * scale;

imgHeight.value = https://www.songbingjia.com/android/nowH;
imgWidth.value = https://www.songbingjia.com/android/nowW;
imgScale.value = https://www.songbingjia.com/android/scale;
// 位置
position.top = h / 2 - nowH / 2 + "px";
position.left = w / 2 - nowW / 2 + "px";
position.transform = `rotate($-degdeg)`;
break;


;



总结
总的来说,通过 electron 实现图片查看器还是比较方便快捷的,主要难点在于坐标计算上,同时还需要注意边界值的情况,大家有兴趣也可以动手尝试一下!


【electron学习笔记如何通过electron实现图片查看器】给大家分享更多 electron 实战中的点滴,如果大家对此感兴趣,欢迎各位关注、留言,大家的支持就是我的动力!

    推荐阅读