I am trying to build a webpage where users can zoom in to a photo and look at the image in greater detail. The idea is that I will have a "zoom in" button, that, when clicked, will show a higher resolution version of the image. Use case: historical/archival image gallery
I recently came upon this article written by Cloudinary on how to create JavaScript functions for zooming in and out of photos. However, the article did not actually provide an example of using the Cloudinary service.
Article: Cool Tricks for Resizing Images in JavaScript (cloudinary.com)
https://cloudinary.com/blog/cool_tricks_for_resizing_images_in_javascript
Does anyone have advice/tips on how to make this work with Cloudinary stored images? I want to ensure I'm serving the highest quality/resolution version of the original image when zoomed in.
I have a codesandbox demo: https://codesandbox.io/s/cloudinary-zoom-image-542b1?file=/src/App.vue
The best practice is to upload the images to Cloudinary in the best quality/resolution. Assuming that the images would be scaled down when displayed on your site, once the zoom button is clicked, you can use Cloudinary transformations to request the images in larger dimensions, and possibly even their original dimensions.
For instance, in the following example, the image is originally scaled down to a width of 400px (c_scale,w_400). Once the "Zoom In" button is clicked, I'm changing the transformation URL in a way that crops a size of 400px width of the original image (height is implicitly set to retain the image aspect ratio) - c_crop,w_400. This way the zoomed-in image is in it's original resolution/quality:
function zoomin() {
var myImg = document.getElementById("my-image");
var src = myImg.src;
var splitted = src.split("c_scale,w_400/");
splitted[0] += "c_crop,w_400";
myImg.src = splitted.join("/");
// results in https://res.cloudinary.com/demo/image/upload/q_auto/c_crop,w_400/sample.jpg
}
function zoomout() {
var myImg = document.getElementById("my-image");
myImg.src = "https://res.cloudinary.com/demo/image/upload/q_auto/c_scale,w_400/sample.jpg";
}
body {
display: flex;
flex-direction: column;
align-items: center;
}
<button type="button" onclick="zoomin()">Zoom In</button>
<button type="button" onclick="zoomout()">Zoom Out</button>
<img src="https://res.cloudinary.com/demo/image/upload/q_auto/c_scale,w_400/sample.jpg" id="my-image" width="400px" alt="Flowers and Bee">
That's just a simple example. There are many ways you could implement a zoom-in effect in general, and by using Cloudinary transformations in particular.
Related
I am trying to do a confirmation screen on my react native app and I need the user to trace an ellipse in order to confirm their action - kinda like what hotel tonight does with their logo. Is there a library I can use to have the user trace over an svg?
Here is an example of what the user would be doing:
I found someone else trying to do this, I don't think that is the most creative approach, there was a way to do this in flash many years ago.
I know that SVG is being used for line art animation there are many tutorials out there:
https://medium.com/#sterling.meghan/svg-line-animation-for-beginners-51857c88357f
Also, there is a library for SVG called react-native-svg, the thing is SVG objects can be dragged in javascript
http://www.petercollingridge.co.uk/tutorials/svg/interactive/dragging/
So my idea to solve this would be this:
You have two layers one on top of each other.
The top one fills the entire screen and has a cut, that is the shape to be traced (the line art)
To get to the SVG object that is behind you can only do it through this cut. You can show a small circle on the starting point that is part of a big SVG colored shape that is under the cut, this shape is the second layer.
The user would start tracing but what he really is doing is dragging that SVG big object from one point to the next, he needs to follow the path like tracing because only if he does this he can drag the object through the hole. (He can only reach the object in the second layer through the hole)
The SVG object being drag has a different color from the top layer so when the user drags it gives the appearance of the path filling up.
I hope this helps you or at least gives you some ideas. Also, you could animate another SVG when the user completes the trace, with CSS line art animation. I would probably try this when I have the time.
I came across a similar situation in which I ended up using react-native-sketch-canvas
I made the user draw on the canvas & compared the output path with a predefined path. It was not a perfect solution but was good enough for my requirements.
For recognition you can use rn-gesture-recognizer built off of the rn-draw package :
https://www.npmjs.com/package/rn-gesture-recognizer
(https://www.npmjs.com/package/rn-draw)
And then you can for example create your perfect css shape over your svg :
https://codedaily.io/tutorials/22/The-Shapes-of-React-Native
Also, you can do other things like that :
https://codedaily.io/tutorials/55/Create-a-Draggable-Opacity-Changing-Circle-with-Reanimated-in-React-Native
Generally when we talk about working on SVG's the first library that comes to my mind is the D3 Js , in d3 you can follow the path of any shape in the svg and we can create interpolation , One such example is stated below , See through if this can help you in any ways.
<!DOCTYPE HTML>
<html lang="en">
<head>
</head>
<body>
<div id="loader_container"></div>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script>
function loader(config) {
return function() {
var radius = Math.min(config.width, config.height) / 2;
var tau = 2 * Math.PI;
var arc = d3.svg.arc()
.innerRadius(radius*0.5)
.outerRadius(radius*0.9)
.startAngle(0);
var svg = d3.select(config.container).append("svg")
.attr("id", config.id)
.attr("width", config.width)
.attr("height", config.height)
.append("g")
.attr("transform", "translate(" + config.width / 2 + "," + config.height / 2 + ")")
var background = svg.append("path")
.datum({endAngle: 0.33*tau})
.style("fill", "#4D4D4D")
.attr("d", arc)
.call(spin, 1500)
function spin(selection, duration) {
selection.transition()
.ease("linear")
.duration(duration)
.attrTween("transform", function() {
return d3.interpolateString("rotate(0)", "rotate(360)");
});
setTimeout(function() { spin(selection, duration); }, duration);
}
function transitionFunction(path) {
path.transition()
.duration(7500)
.attrTween("stroke-dasharray", tweenDash)
.each("end", function() { d3.select(this).call(transition); });
}
};
}
var myLoader = loader({width: 960, height: 500, container: "#loader_container", id: "loader"});
myLoader();
</script>
</body>
</html>
Source :
http://bl.ocks.org/MattWoelk/6132258
You can tweak the interpolation with any types , String , date anything. For Interpolation the below link can help
https://bl.ocks.org/mbostock/3173784
http://jsfiddle.net/SHF2M/
https://codepen.io/frcodecamp/pen/wxXypx
Build the outer svg shape as two ellipses connected by line on either sides , then we can use the ellipse path to interpolate using rotate positions , The rotate position should depend on the progress in confirmation screen.
I'm trying to dynamically set the max-height of Bootstraps modal-body elements for all modal dialog boxes. I've written the following, which seems to work when the dialog is opened. I'm depending on the enforceFocus method to exist and to be called once the dialog is rendered. I realize there may be moment before the CSS property is set where the dialog will not be rendered exactly right, but I'm okay with that. Is there anything wrong with this solution? I know I have yet to account for resizing the screen with a modal open, but that seems the easier problem to solve.
(function ($) {
$.fn.modal.Constructor.DEFAULTS.backdrop = 'static';
$.fn.modal.Constructor.DEFAULTS.keyword = false;
var oldEnforceFocus = $.fn.modal.Constructor.prototype.enforceFocus;
$.fn.modal.Constructor.prototype.enforceFocus = function () {
oldEnforceFocus.call(this);
var $element = this.$element;
var maxHeight =
$("body").height() // full page
- $element.find(".modal-header").outerHeight(true) // modal header
- $element.find(".modal-footer").outerHeight(true) // modal footer
- ($element.find(".modal-dialog").outerHeight(true) - $element.find(".modal-dialog").height()) // dialog margins
- 5; // fudge factor
$element.find(".modal-body").css("max-height", maxHeight);
}
})(jQuery);
Thanks!
edit: To give credit where credit is due, this is based on
Correct way to extend Bootstrap Modal - lock, unlock.
If you don't want to use javascript, you can use CSS media queries and get close-ish to the height you need by using min-height. For example, define a media query on min-height: 540px, and set the max-height of the modal to something like max-height: 500px. Then define a media query at say min-height: 680px and set the modal to max-height: 640px. It's not fluid, and it requires several media queries to inch up to the largest size you want to plan for, but it will get you there.
#Josh solution is good with CSS and media queries but writing so many media queries where small devices has different screen heights e.g Iphone and SamSung G and N series, required alot of media queries to even calculate close-ish modal height on different screen sizes.
so setting height of modal (modal-body) dynamically according to media screen size and on small devices where there will be 2 types of media screen landscape and portrait, following few lines of code will put you very close-ish to your goal
Rendering modal HTML according to screen size with-in sec and later if screen size changes adjust it's height according to screen size
$(document).ready(function () {
setInterval(Dimension, 100);
function Dimension() {
var doc = $(document).height(); // document height
var head = $(".modal-header").height(); // modal header height
var footer = $(".modal-footer").height(); // modal footer height
var modheight = doc - head - footer - 65; // 65 is extra margins and it will not effect the height of modal any way if not changed.
$('.modal-body').css('height', modheight);
}
});
Note
Few Changes required in Modal CSS
CSS
.modal-dialog {
margin: 0px auto !important;
}
.modal-body {
overflow-y: scroll; // In-case the content in modal-body overflow so it will have scrolling.
}
Fiddle
You can check the modal height adjust itself by increasing and decreasing the fiddle result window's height and width.
I'm using the supersized jquery plugin in order to display a fullscreen background slideshow.
Look at this website (it's not my own but I'm using the same structure):
http://mysampleconcept.com/situs4/
As you can see (for example if you give the header some opacity) the images begin at the top of the body.
But I want them to begin below the header (so that the header doesn't cover the top of the image).
If you give the supersized LIs for example top: 100px; the whole image moves down so that the bottom of the image disappears below my footer.
So that's not the solution I want.
So all in all which I need is the image to stretch to the biggest size it can, while still being inside the window not stretching over the top 100px nor bottom.
How can I do this?
Sorry, my English is not the best...
I found this solution but I don't know how to implement it: https://stackoverflow.com/a/12889088/1981981
You can use the solution offered in the question you refered to as a starting point. Just place it right below the $.supersized() inside your document ready function.
Since you want a top offset, we have to modify the top value aswell. I modified the snipped to suit your needs:
var portfolioSize = function() {
var headerOffset = 100;
$('#supersized').css({
height: $(window).height() - headerOffset,
top: headerOffset + 'px'
});
};
portfolioSize();
$(window).resize(function() { portfolioSize(); });
I changed the $(window).load Event to a direct call, since we place the code inside the document ready function.
Don't forget to modify the CSS for positioning as mentioned in the other answer (https://stackoverflow.com/a/12889088/860205).
I have an image area in my application with width:530px and height:510px. I want to place images in that area but the images comes in different different sizes. how to crop or scale the image without losing aspect ratio to fill that area. Is there any native methods available in winjs?
You have a few options for that.
One is to use the ViewBox control that WinJS provides you. The ViewBox can only have a single child (so you would have your tag as its only child perhaps or a div that contains your img) and it will scale that child (using CSS transforms) up to fit into its container (without changing the aspect ratio). It's pretty slick.
Another option is to set the image as the CSS background-image property of a container (such as a div) and set the background-size property to contain. This will stretch the image up to the size of the container.
A final option that you have to resort to if your case is a bit special is not such a bad option after all. In the updateLayout method of your page, you can refer to the element and explicitly set its CSS properties to fit. At that point you'll know all about the layout and can easily do the math to figure out what size image should be. Here's some code from one of my projects where I do this. Notice that I'm comparing the aspect ratio of the screen and the image to determine whether I should size to the width or the height. Unlike your situation (I'm guessing), my code makes sure the image fills the screen and excess is clipped. I'm guessing you want your img to be contained.
function setImagePosition() {
var img = q(".viewCamera #viewport img");
if (outerWidth/outerHeight > img.naturalWidth/img.naturalHeight) {
img.style.width = format("{0}px", outerWidth);
img.style.height = "";
img.style.top = format("{0}px", (outerHeight - img.clientHeight) / 2);
img.style.left = "0px";
} else {
img.style.width = "";
img.style.height = format("{0}px", outerHeight);
img.style.top = "0px";
img.style.left = format("{0}px", (outerWidth - img.clientWidth) / 2);
}
}
Hope that helps!
Are you referring to scaling HTML images? If so, you can set either one, width or height. Whichever you set, the other will scale and keep image aspect ratio.
I have a gadget that is a glossary with a number of different pages. users can upload new words to the data source and those words will be pulled into the glossary through an AJAX call.
I want to resize the gadget window everytime the window is re-sized OR a new letter is selected and the page height changes (ie the gadget html block height).
Google developers has posted this on their website. However, this clearly is not working for me. The scrolling is not registering on the iframe and the height is not adjusting when the window is resized.
Here are my ModulePrefs
title="Climate Policy and Science Glossary"
description="Paragraph format"
height="300"
scrolling="true">
<Require feature="dynamic-height"/>
<Require feature="opensocial-0.8" />
Here is the gadget's script telling it to adjust:
window.onresize = adjust;
function adjust() {
var wndwH = gadgets.window.getViewportDimensions().height,
wgtH = $('#_glossary').closest('html').height,
h = Math.min(wndwH, wgtH);
gadgets.window.adjustHeight(h);
}
gadgets.util.registerOnLoadHandler(adjust);
What's going on? Am I doing something wrong or is there anyone else out there having trouble with Google's dynamic height??
The adjust function really only needs:
function adjust() {
gadgets.window.adjustHeight();
}
That should fit everything automatically.