add: dblclick to preview images
This commit is contained in:
parent
5e0050b855
commit
a28ade9f2a
|
|
@ -0,0 +1,96 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Image Preview</title>
|
||||
</head>
|
||||
<body>
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
#image {
|
||||
position: relative;
|
||||
/* top: 50%;
|
||||
transform: translateY(-50%); */
|
||||
vertical-align: middle;
|
||||
}
|
||||
.container {
|
||||
height: calc(100% - 50px);
|
||||
overflow: auto;
|
||||
text-align: center;
|
||||
}
|
||||
.toolbar {
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
height: 50px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" href="chrome://__addonRef__/skin/workspace.css" />
|
||||
<script>
|
||||
window.addEventListener("DOMContentLoaded", (e) => {
|
||||
document.querySelector(".container").style["line-height"] = `${
|
||||
window.innerHeight - 50
|
||||
}px`;
|
||||
window.addEventListener("resize", (_e) => {
|
||||
document.querySelector(".container").style["line-height"] = `${
|
||||
window.innerHeight - 50
|
||||
}px`;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<div class="container">
|
||||
<img id="image" src="" alt="" />
|
||||
</div>
|
||||
<div class="toolbar">
|
||||
<div class="tooltip" id="left-container">
|
||||
<button id="left" class="tool-button">
|
||||
<svg
|
||||
t="1668665847719"
|
||||
class="icon"
|
||||
viewBox="0 0 1024 1024"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="6765"
|
||||
width="18"
|
||||
height="18"
|
||||
>
|
||||
<path
|
||||
d="M641.28 278.613333l-45.226667-45.226666-278.634666 278.762666 278.613333 278.485334 45.248-45.269334-233.365333-233.237333z"
|
||||
p-id="6766"
|
||||
></path>
|
||||
</svg>
|
||||
</button>
|
||||
<span class="tooltiptext">Previous</span>
|
||||
</div>
|
||||
<div class="tooltip" id="right-container">
|
||||
<button id="right" class="tool-button">
|
||||
<svg
|
||||
t="1668665870223"
|
||||
class="icon"
|
||||
viewBox="0 0 1024 1024"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="6907"
|
||||
width="18"
|
||||
height="18"
|
||||
>
|
||||
<path
|
||||
d="M593.450667 512.128L360.064 278.613333l45.290667-45.226666 278.613333 278.762666L405.333333 790.613333l-45.226666-45.269333z"
|
||||
p-id="6908"
|
||||
></path>
|
||||
</svg>
|
||||
</button>
|
||||
<span class="tooltiptext">Next</span>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -19,6 +19,7 @@ import NoteExportWindow from "./note/noteExportWindow";
|
|||
import NoteExport from "./note/noteExportController";
|
||||
import EditorViews from "./editor/editorViews";
|
||||
import EditorController from "./editor/editorController";
|
||||
import EditorImageViewer from "./editor/imageViewerWindow";
|
||||
import TemplateWindow from "./template/templateWindow";
|
||||
|
||||
class Knowledge4Zotero {
|
||||
|
|
@ -49,6 +50,7 @@ class Knowledge4Zotero {
|
|||
public NoteParse: NoteParse;
|
||||
public EditorViews: EditorViews;
|
||||
public EditorController: EditorController;
|
||||
public EditorImageViewer: EditorImageViewer;
|
||||
|
||||
constructor() {
|
||||
this.ZoteroEvents = new ZoteroEvents(this);
|
||||
|
|
@ -59,6 +61,7 @@ class Knowledge4Zotero {
|
|||
this.WorkspaceMenu = new WorkspaceMenu(this);
|
||||
this.EditorViews = new EditorViews(this);
|
||||
this.EditorController = new EditorController(this);
|
||||
this.EditorImageViewer = new EditorImageViewer(this);
|
||||
this.WizardWindow = new WizardWindow(this);
|
||||
this.SyncInfoWindow = new SyncInfoWindow(this);
|
||||
this.SyncListWindow = new SyncListWindow(this);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
* This file contains image viewer for note editor.
|
||||
*/
|
||||
|
||||
import Knowledge4Zotero from "../addon";
|
||||
import AddonBase from "../module";
|
||||
|
||||
class EditorImageViewer extends AddonBase {
|
||||
_window: Window;
|
||||
scaling: number;
|
||||
srcList: string[];
|
||||
idx: number;
|
||||
title: string;
|
||||
anchorPosition: {
|
||||
left: number;
|
||||
top: number;
|
||||
};
|
||||
constructor(parent: Knowledge4Zotero) {
|
||||
super(parent);
|
||||
this.scaling = 1;
|
||||
this.title = "Note";
|
||||
}
|
||||
|
||||
async onInit(srcs: string[], idx: number, title: string) {
|
||||
if (!this._window || this._window.closed) {
|
||||
this._window = window.open(
|
||||
"chrome://Knowledge4Zotero/content/imageViewer.html",
|
||||
"",
|
||||
"chrome,centerscreen,resizable,status,width=400,height=450"
|
||||
);
|
||||
let t = 0;
|
||||
console.log(this._window.document?.readyState);
|
||||
// Wait for window
|
||||
while (t < 500 && this._window.document.readyState !== "complete") {
|
||||
console.log(this._window.document?.readyState);
|
||||
await Zotero.Promise.delay(10);
|
||||
t += 1;
|
||||
}
|
||||
|
||||
this._window.document
|
||||
.querySelector("#left")
|
||||
.addEventListener("click", (e) => {
|
||||
this.setIndex("left");
|
||||
});
|
||||
this._window.document
|
||||
.querySelector("#right")
|
||||
.addEventListener("click", (e) => {
|
||||
this.setIndex("right");
|
||||
});
|
||||
const container = this._window.document.querySelector(
|
||||
".container"
|
||||
) as HTMLDivElement;
|
||||
const img = this._window.document.querySelector(
|
||||
"#image"
|
||||
) as HTMLImageElement;
|
||||
this._window.addEventListener("keydown", (e) => {
|
||||
// ctrl+w or esc
|
||||
if ((e.key === "w" && e.ctrlKey) || e.keyCode === 27) {
|
||||
this._window.close();
|
||||
}
|
||||
this.anchorPosition = {
|
||||
left: img.scrollWidth / 2 - container.scrollLeft / 2,
|
||||
top: img.scrollHeight / 2 - container.scrollLeft / 2,
|
||||
};
|
||||
if (e.keyCode === 37 || e.keyCode === 40) {
|
||||
this.setIndex("left");
|
||||
}
|
||||
if (e.keyCode === 38 || e.keyCode === 39) {
|
||||
this.setIndex("right");
|
||||
}
|
||||
if (e.key === "0") {
|
||||
this.setScale(1);
|
||||
} else if (e.keyCode === 107 || e.keyCode === 187 || e.key === "=") {
|
||||
this.setScale(this.scaling * 1.1);
|
||||
} else if (e.key === "-") {
|
||||
this.setScale(this.scaling / 1.1);
|
||||
}
|
||||
});
|
||||
this._window.addEventListener("wheel", async (e) => {
|
||||
this.anchorPosition = {
|
||||
left: e.pageX - container.offsetLeft,
|
||||
top: e.pageY - container.offsetTop,
|
||||
};
|
||||
function normalizeWheelEventDirection(evt) {
|
||||
let delta = Math.hypot(evt.deltaX, evt.deltaY);
|
||||
const angle = Math.atan2(evt.deltaY, evt.deltaX);
|
||||
if (-0.25 * Math.PI < angle && angle < 0.75 * Math.PI) {
|
||||
// All that is left-up oriented has to change the sign.
|
||||
delta = -delta;
|
||||
}
|
||||
return delta;
|
||||
}
|
||||
if (e.ctrlKey) {
|
||||
const delta = normalizeWheelEventDirection(e);
|
||||
this.setScale(
|
||||
this.scaling *
|
||||
Math.pow(delta > 0 ? 1.1 : 1 / 1.1, Math.round(Math.abs(delta)))
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.srcList = srcs;
|
||||
this.idx = idx;
|
||||
this.title = title || "Note";
|
||||
this.setImage();
|
||||
this.setScale(1);
|
||||
this._window.focus();
|
||||
}
|
||||
|
||||
private setImage() {
|
||||
(this._window.document.querySelector("#image") as HTMLImageElement).src =
|
||||
this.srcList[this.idx];
|
||||
this.setTitle();
|
||||
(
|
||||
this._window.document.querySelector("#left-container") as HTMLButtonElement
|
||||
).style.visibility = this.idx === 0 ? "hidden" : "visible";
|
||||
(
|
||||
this._window.document.querySelector("#right-container") as HTMLButtonElement
|
||||
).style.visibility =
|
||||
this.idx === this.srcList.length - 1 ? "hidden" : "visible";
|
||||
}
|
||||
|
||||
private setIndex(type: "left" | "right") {
|
||||
if (type === "left") {
|
||||
this.idx > 0 ? (this.idx -= 1) : undefined;
|
||||
}
|
||||
if (type === "right") {
|
||||
this.idx < this.srcList.length - 1 ? (this.idx += 1) : undefined;
|
||||
}
|
||||
this.setImage();
|
||||
}
|
||||
|
||||
private setScale(scaling: number) {
|
||||
const oldScale = this.scaling;
|
||||
this.scaling = scaling;
|
||||
if (this.scaling > 10) {
|
||||
this.scaling = 10;
|
||||
}
|
||||
if (this.scaling < 0.1) {
|
||||
this.scaling = 0.1;
|
||||
}
|
||||
const container = this._window.document.querySelector(
|
||||
".container"
|
||||
) as HTMLDivElement;
|
||||
(
|
||||
this._window.document.querySelector("#image") as HTMLImageElement
|
||||
).style.width = `calc(100% * ${this.scaling})`;
|
||||
if (this.scaling > 1) {
|
||||
container.scrollLeft +=
|
||||
this.anchorPosition.left * (this.scaling - oldScale);
|
||||
container.scrollTop +=
|
||||
this.anchorPosition.top * (this.scaling - oldScale);
|
||||
}
|
||||
}
|
||||
|
||||
private setTitle() {
|
||||
this._window.document.querySelector("title").innerText = `${this.idx + 1}/${
|
||||
this.srcList.length
|
||||
}:${this.title}`;
|
||||
}
|
||||
}
|
||||
|
||||
export default EditorImageViewer;
|
||||
|
|
@ -319,6 +319,7 @@ class ZoteroEvents extends AddonBase {
|
|||
Zotero.debug(`Knowledge4Zotero: note editor initialized.`);
|
||||
|
||||
if (!instance._knowledgeSelectionInitialized) {
|
||||
// Put event listeners here to access Zotero instance
|
||||
instance._iframeWindow.document.addEventListener(
|
||||
"selectionchange",
|
||||
async (e) => {
|
||||
|
|
@ -412,6 +413,18 @@ class ZoteroEvents extends AddonBase {
|
|||
}
|
||||
}
|
||||
);
|
||||
instance._iframeWindow.document.addEventListener("dblclick", (e) => {
|
||||
if ((e.target as HTMLElement).tagName === "IMG") {
|
||||
const imgs = instance._iframeWindow.document
|
||||
.querySelector(".primary-editor")
|
||||
?.querySelectorAll("img");
|
||||
this._Addon.EditorImageViewer.onInit(
|
||||
Array.prototype.map.call(imgs, (e: HTMLImageElement) => e.src),
|
||||
Array.prototype.indexOf.call(imgs, e.target),
|
||||
instance._item.getNoteTitle()
|
||||
);
|
||||
}
|
||||
});
|
||||
instance._knowledgeSelectionInitialized = true;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue