mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
WebView: click an image to view/zoom it
This commit is contained in:
parent
15151742c9
commit
4df0d03baa
@ -20,6 +20,7 @@ var updateHtml = function(html) {
|
||||
contentDiv.innerHTML = html;
|
||||
|
||||
insertImageCaption();
|
||||
setupImageView();
|
||||
|
||||
var codes = document.getElementsByTagName('code');
|
||||
mermaidIdx = 0;
|
||||
|
@ -138,6 +138,7 @@ var updateText = function(text) {
|
||||
contentDiv.innerHTML = html;
|
||||
handleToc(needToc);
|
||||
insertImageCaption();
|
||||
setupImageView();
|
||||
handleMetaData();
|
||||
renderMermaid('lang-mermaid');
|
||||
renderFlowchart(['lang-flowchart', 'lang-flow']);
|
||||
|
@ -21,17 +21,24 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="qrc:/resources/view_image.css">
|
||||
<link rel="stylesheet" type="text/css" href="CSS_PLACE_HOLDER">
|
||||
<link rel="stylesheet" type="text/css" href="HIGHLIGHTJS_CSS_PLACE_HOLDER">
|
||||
<script src="qrc:/resources/qwebchannel.js"></script>
|
||||
<script src="qrc:/utils/highlightjs/highlight.pack.js"></script>
|
||||
<!-- EXTRA_PLACE_HOLDER -->
|
||||
<script src="JS_PLACE_HOLDER" defer></script>
|
||||
<script src="qrc:/resources/view_image.js" defer></script>
|
||||
<script src="qrc:/resources/markdown_template.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="content-div"></div>
|
||||
|
||||
<div id="image-view-div" class="modal-box">
|
||||
<span id="image-view-close" class="modal-close">×</span>
|
||||
<img id="image-view" class="modal-content">
|
||||
</div>
|
||||
|
||||
<div id="preview-div" style="display:none;"></div>
|
||||
|
||||
<div id="inplace-preview-div" style="display:none;"></div>
|
||||
|
@ -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;
|
||||
|
@ -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');
|
||||
|
@ -97,6 +97,7 @@ var updateText = function(text) {
|
||||
contentDiv.innerHTML = html;
|
||||
handleToc(needToc);
|
||||
insertImageCaption();
|
||||
setupImageView();
|
||||
highlightCodeBlocks(document,
|
||||
VEnableMermaid,
|
||||
VEnableFlowchart,
|
||||
|
63
src/resources/view_image.css
Normal file
63
src/resources/view_image.css
Normal file
@ -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;
|
||||
}
|
149
src/resources/view_image.js
Normal file
149
src/resources/view_image.js
Normal file
@ -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';
|
||||
};
|
@ -261,5 +261,7 @@
|
||||
<file>resources/icons/tags.svg</file>
|
||||
<file>resources/icons/tag_explorer.svg</file>
|
||||
<file>resources/icons/tag.svg</file>
|
||||
<file>resources/view_image.js</file>
|
||||
<file>resources/view_image.css</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
Loading…
x
Reference in New Issue
Block a user