diff --git a/src/resources/hoedown.js b/src/resources/hoedown.js
index 42e4922d..3089a5a6 100644
--- a/src/resources/hoedown.js
+++ b/src/resources/hoedown.js
@@ -20,6 +20,7 @@ var updateHtml = function(html) {
contentDiv.innerHTML = html;
insertImageCaption();
+ setupImageView();
var codes = document.getElementsByTagName('code');
mermaidIdx = 0;
diff --git a/src/resources/markdown-it.js b/src/resources/markdown-it.js
index 0ea8e3d0..4948cd13 100644
--- a/src/resources/markdown-it.js
+++ b/src/resources/markdown-it.js
@@ -138,6 +138,7 @@ var updateText = function(text) {
contentDiv.innerHTML = html;
handleToc(needToc);
insertImageCaption();
+ setupImageView();
handleMetaData();
renderMermaid('lang-mermaid');
renderFlowchart(['lang-flowchart', 'lang-flow']);
diff --git a/src/resources/markdown_template.html b/src/resources/markdown_template.html
index 62731b28..1535d34b 100644
--- a/src/resources/markdown_template.html
+++ b/src/resources/markdown_template.html
@@ -21,17 +21,24 @@
}
+
+
+
+
×
+
![]()
+
+
diff --git a/src/resources/markdown_template.js b/src/resources/markdown_template.js
index 83942d69..c241c509 100644
--- a/src/resources/markdown_template.js
+++ b/src/resources/markdown_template.js
@@ -854,7 +854,7 @@ var insertImageCaption = function() {
captionDiv.textContent = img.alt;
img.insertAdjacentElement('afterend', captionDiv);
}
-}
+};
var asyncJobsCount = 0;
@@ -1005,7 +1005,8 @@ window.onmousedown = function(e) {
// Left button and Ctrl key.
if (e.buttons == 1
&& isCtrl
- && window.getSelection().type != 'Range') {
+ && window.getSelection().type != 'Range'
+ && !isViewingImage()) {
vds_oriMouseClientX = e.clientX;
vds_oriMouseClientY = e.clientY;
vds_readyToScroll = true;
diff --git a/src/resources/marked.js b/src/resources/marked.js
index bc1ffbd2..37d409bd 100644
--- a/src/resources/marked.js
+++ b/src/resources/marked.js
@@ -58,6 +58,7 @@ var updateText = function(text) {
contentDiv.innerHTML = html;
handleToc(needToc);
insertImageCaption();
+ setupImageView();
renderMermaid('lang-mermaid');
renderFlowchart(['lang-flowchart', 'lang-flow']);
renderPlantUML('lang-puml');
diff --git a/src/resources/showdown.js b/src/resources/showdown.js
index 74a957f0..e40cabba 100644
--- a/src/resources/showdown.js
+++ b/src/resources/showdown.js
@@ -97,6 +97,7 @@ var updateText = function(text) {
contentDiv.innerHTML = html;
handleToc(needToc);
insertImageCaption();
+ setupImageView();
highlightCodeBlocks(document,
VEnableMermaid,
VEnableFlowchart,
diff --git a/src/resources/view_image.css b/src/resources/view_image.css
new file mode 100644
index 00000000..f84952a3
--- /dev/null
+++ b/src/resources/view_image.css
@@ -0,0 +1,63 @@
+.view-image {
+ cursor: pointer;
+ transition: 0.3s;
+}
+
+.modal-box {
+ display: none;
+ position: fixed;
+ z-index: 1000;
+ padding-top: 50px;
+ left: 0;
+ top: 0;
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
+ background-color: rgb(68, 68, 68);
+ background-color: rgba(68, 68, 68, 0.9);
+}
+
+.modal-content {
+ margin: auto;
+ display: block;
+ width: auto;
+ height: auto;
+ cursor: move;
+}
+
+/* Add Animation */
+.modal-content {
+ -webkit-animation-name: zoom;
+ -webkit-animation-duration: 0.6s;
+ animation-name: zoom;
+ animation-duration: 0.6s;
+}
+
+@-webkit-keyframes zoom {
+ from {-webkit-transform:scale(0)}
+ to {-webkit-transform:scale(1)}
+}
+
+@keyframes zoom {
+ from {transform:scale(0)}
+ to {transform:scale(1)}
+}
+
+/* The Close Button */
+span.modal-close {
+ position: absolute;
+ z-index: 1000;
+ top: 15px;
+ right: 35px;
+ color: #DADADA;
+ font-size: 40px;
+ font-weight: bold;
+ transition: 0.3s;
+}
+
+span.modal-close:hover,
+span.modal-close:focus {
+ color: #EEEEEE;
+ text-decoration: none;
+ cursor: pointer;
+}
diff --git a/src/resources/view_image.js b/src/resources/view_image.js
new file mode 100644
index 00000000..6f0260d7
--- /dev/null
+++ b/src/resources/view_image.js
@@ -0,0 +1,149 @@
+var imageViewDiv = document.getElementById('image-view-div');
+
+var viewImage = function(obj, image) {
+ image = !image ? obj.src : image;
+
+ imageViewDiv.style.display = 'block';
+
+ var boxImage = document.getElementById('image-view');
+ boxImage.src = image;
+ // Restore image-view.
+ boxImage.style.width = '';
+ boxImage.style.position = '';
+ boxImage.style.zIndex = '';
+};
+
+var viewBoxImageMouseDown = false;
+var viewBoxImageOffsetToMouse = [0, 0];
+
+var closeImageViewBox = function() {
+ imageViewDiv.style.display = "none";
+};
+
+var initImageViewBox = function() {
+ // Left and top in pixel.
+ var moveImage = function(img, left, top) {
+ if (img.style.position != 'absolute') {
+ img.style.position = 'absolute';
+ img.style.zIndex = parseInt(document.getElementById('image-view-close').style.zIndex) - 1;
+ }
+
+ img.style.left = left + 'px';
+ img.style.top = top + 'px';
+ };
+
+ // View box.
+ imageViewDiv.onclick = function(e) {
+ e = e || window.event;
+ var boxImage = document.getElementById('image-view');
+ if (e.target.id != boxImage.id) {
+ // Click outside the image to close the box.
+ closeImageViewBox();
+ }
+
+ e.preventDefault();
+ };
+
+ imageViewDiv.onwheel = function(e) {
+ e = e || window.event;
+ var ctrl = !!e.ctrlKey;
+ if (ctrl) {
+ return;
+ }
+
+ var target = e.target;
+ if (!target || target.id != 'image-view') {
+ return;
+ }
+
+ var rect = target.getBoundingClientRect();
+ var centerX = e.clientX - rect.left;
+ var centerY = e.clientY - rect.top;
+
+ var oriWidth = target.getAttribute('oriWidth');
+ var oriHeight = target.getAttribute('oriWidth');
+ if (!oriWidth) {
+ oriWidth = rect.width;
+ oriHeight = rect.height;
+
+ target.setAttribute('oriWidth', oriWidth);
+ target.setAttribute('oriHeight', oriHeight);
+ }
+
+ var step = Math.floor(oriWidth / 4);
+
+ var value = e.wheelDelta || -e.detail;
+ // delta >= 0 is up, which will trigger zoom in.
+ var delta = Math.max(-1, Math.min(1, value));
+
+ var newWidth = rect.width + (delta < 0 ? -step : step);
+ if (newWidth < 200) {
+ e.preventDefault();
+ return;
+ }
+
+ var factor = newWidth / rect.width;
+
+ target.style.width = newWidth + 'px';
+
+ // Adjust the image around the center point.
+ moveImage(target, e.clientX - centerX * factor, e.clientY - centerY * factor);
+
+ e.preventDefault();
+ };
+
+ // Content image.
+ var boxImage = document.getElementById('image-view');
+ boxImage.onmousedown = function(e) {
+ e = e || window.event;
+ var target = this || e.target;
+ viewBoxImageMouseDown = true;
+ viewBoxImageOffsetToMouse = [
+ target.offsetLeft - e.clientX,
+ target.offsetTop - e.clientY
+ ];
+ e.preventDefault();
+ };
+
+ boxImage.onmouseup = function(e) {
+ e = e || window.event;
+ viewBoxImageMouseDown = false;
+ e.preventDefault();
+ };
+
+ boxImage.onmousemove = function(e) {
+ e = e || window.event;
+ var target = this || e.target;
+ if (viewBoxImageMouseDown) {
+ moveImage(target, e.clientX + viewBoxImageOffsetToMouse[0], e.clientY + viewBoxImageOffsetToMouse[1]);
+ }
+
+ e.preventDefault();
+ };
+
+ // Close button.
+ document.getElementById('image-view-close').onclick = closeImageViewBox;
+};
+
+initImageViewBox();
+
+var setupImageView = function() {
+ closeImageViewBox();
+
+ var imgs = document.getElementsByTagName('img');
+ for (var i = 0; i < imgs.length; ++i) {
+ var img = imgs[i];
+ if (img.id == 'image-view') {
+ continue;
+ }
+
+ img.classList.add('view-image');
+ img.onclick = function() {
+ viewImage(this, this.src);
+ };
+ }
+};
+
+var isViewingImage = function() {
+ return imageViewDiv.style.display == 'block';
+};
diff --git a/src/vnote.qrc b/src/vnote.qrc
index 35a8dacf..00bf6367 100644
--- a/src/vnote.qrc
+++ b/src/vnote.qrc
@@ -261,5 +261,7 @@
resources/icons/tags.svg
resources/icons/tag_explorer.svg
resources/icons/tag.svg
+ resources/view_image.js
+ resources/view_image.css