vnote/src/resources/view_image.js
Le Tan b10078efa3 WebView: double-click to view diagrams
Mermaid is not supported since its use of external stylesheet.
2018-06-30 22:17:33 +08:00

202 lines
5.4 KiB
JavaScript

var imageViewDiv = document.getElementById('image-view-div');
var viewImage = function(imgSrc, background = 'transparent') {
viewBoxImageMouseDown = false;
imageViewDiv.style.display = 'block';
var boxImage = document.getElementById('image-view');
boxImage.src = imgSrc;
boxImage.style.backgroundColor = background;
// Restore image-view.
boxImage.style.width = '';
boxImage.style.position = '';
boxImage.style.zIndex = '';
};
var viewIMG = function(imgNode) {
viewImage(imgNode.src);
};
var viewSVG = function(svgNode, background = 'transparent') {
var svg = svgNode.outerHTML.replace(/#/g, '%23').replace(/[\r\n]/g, '');
var src = 'data:image/svg+xml;utf8,' + svg;
viewImage(src, background);
};
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) {
if (imgs[i].id == 'image-view') {
continue;
}
setupIMGToView(imgs[i]);
}
};
var isViewingImage = function() {
return imageViewDiv.style.display == 'block';
};
var onSVGDoubleClick = function(forceBackground, e) {
e = e || window.event;
var name = e.target.nodeName.toLowerCase();
if (name != 'text' && name != 'tspan') {
if (forceBackground) {
// Use <svg>'s parent's background color.
var svgNode = e.target;
while (svgNode && svgNode.nodeName.toLowerCase() != 'svg') {
svgNode = svgNode.parentNode;
}
if (svgNode) {
var style = window.getComputedStyle(svgNode.parentNode, null);
viewSVG(this, style.backgroundColor);
}
} else {
viewSVG(this);
}
e.preventDefault();
}
};
var setupSVGToView = function(node, forceBackground = false) {
if (!node || node.nodeName.toLowerCase() != 'svg') {
return;
}
node.classList.add('view-svg');
node.ondblclick = onSVGDoubleClick.bind(node, forceBackground);
};
var setupIMGToView = function(node) {
if (!node || node.nodeName.toLowerCase() != 'img') {
return;
}
node.classList.add('view-image');
node.ondblclick = function() {
viewIMG(this);
};
};