jQuery mobile/JavaScript image pinch zoom for android and iPad - html

I have been searching for an uncomplicated solution to how an image (png) can be zoomed in and out without affecting the rest of the website, but found none.
Have any of you used such a tool or know a way to do this using jQuery or javascript? I am very new to jQuery, so don't know what events I should look at. This functionality should work on both android tablets and iPad.
Looked at JQuery Mobile Pinch Zoom Image Only and the links provided but apparently those are for the ones using PhoneGap.
Thanks for any help.

I did not find a solution either so I implemented it myself (using vanilla JS and canvas but portable to css3) : https://github.com/rombdn/img-touch-canvas
Example : http://www.rombdn.com/img-touch-canvas/demo (better with a touch device but works on desktop with +/- and mouse drag)
<html>
<body>
<div style="width: your_image_width; height: your_image_height">
<canvas id="mycanvas" style="width: 100%; height: 100%"></canvas>
</div>
<script src="img-touch-canvas.js"></script>
<script>
var gesturableImg = new ImgTouchCanvas({
canvas: document.getElementById('mycanvas'),
path: "your image url"
});
</script>
</body>
</html>

I would place the image in a "viewport" layer that is used to maintain the flow of your page. The "viewport" element would have it's overflow CSS property set to hidden to achieve this goal.
You can then use JavaScript to detect multiple touches and then scale the image as necessary. I have yet to use this frameworks but it seems very cool and could help make this easier on you: https://github.com/HotStudio/touchy
You can also detect multiple touches without a framework by watching the event.touches array inside an event handler for touchmove. For each touch occurring simultaneously there will be another index in the event.touches array.
Using Touchy seems pretty easy (untested):
var handleTouchyPinch = function (e, $target, data) {
$target.css({'webkitTransform':'scale(' + data.scale + ',' + data.scale + ')'});
};
$('#my_div').bind('touchy-pinch', handleTouchyPinch);

Related

CSS conflict when using iFrame [duplicate]

Is it possible to change styles of a div that resides inside an iframe on the page using CSS only?
You need JavaScript. It is the same as doing it in the parent page, except you must prefix your JavaScript command with the name of the iframe.
Remember, the same origin policy applies, so you can only do this to an iframe element which is coming from your own server.
I use the Prototype framework to make it easier:
frame1.$('mydiv').style.border = '1px solid #000000'
or
frame1.$('mydiv').addClassName('withborder')
In short no.
You can not apply CSS to HTML that is loaded in an iframe, unless you have control over the page loaded in the iframe due to cross-domain resource restrictions.
Yes. Take a look at this other thread for details:
How to apply CSS to iframe?
const cssLink = document.createElement("link");
cssLink.href = "style.css";
cssLink.rel = "stylesheet";
cssLink.type = "text/css";
frames['frame1'].contentWindow.document.body.appendChild(cssLink);
// ^frame1 is the #id of the iframe: <iframe id="frame1">
You can retrieve the contents of an iframe first and then use jQuery selectors against them as usual.
$("#iframe-id").contents().find("img").attr("style","width:100%;height:100%")
$("#iframe-id").contents().find("img").addClass("fancy-zoom")
$("#iframe-id").contents().find("img").onclick(function(){ zoomit($(this)); });
Good Luck!
The quick answer is: No, sorry.
It's not possible using just CSS. You basically need to have control over the iframe content in order to style it. There are methods using javascript or your web language of choice (which I've read a little about, but am not to familiar with myself) to insert some needed styles dynamically, but you would need direct control over the iframe content, which it sounds like you do not have.
Use Jquery and wait till the source is loaded,
This is how I have achieved(Used angular interval, you can use javascript setInterval method):
var addCssToIframe = function() {
if ($('#myIframe').contents().find("head") != undefined) {
$('#myIframe')
.contents()
.find("head")
.append(
'<link rel="stylesheet" href="app/css/iframe.css" type="text/css" />');
$interval.cancel(addCssInterval);
}
};
var addCssInterval = $interval(addCssToIframe, 500, 0, false);
Combining the different solutions, this is what worked for me.
$(document).ready(function () {
$('iframe').on('load', function() {
$("iframe").contents().find("#back-link").css("display", "none");
});
});
Apparently it can be done via jQuery:
$('iframe').load( function() {
$('iframe').contents().find("head")
.append($("<style type='text/css'> .my-class{display:none;} </style>"));
});
https://stackoverflow.com/a/13959836/1625795
probably not the way you are thinking. the iframe would have to <link> in the css file too. AND you can't do it even with javascript if it's on a different domain.
Not possible from client side . A javascript error will be raised "Error: Permission denied to access property "document"" since the Iframe is not part of your domaine.
The only solution is to fetch the page from the server side code and change the needed CSS.
A sort of hack-ish way of doing things is like Eugene said. I ended up following his code and linking to my custom Css for the page. The problem for me was that, With a twitter timeline you have to do some sidestepping of twitter to override their code a smidgen. Now we have a rolling timeline with our css to it, I.E. Larger font, proper line height and making the scrollbar hidden for heights larger than their limits.
var c = document.createElement('link');
setTimeout(frames[0].document.body.appendChild(c),500); // Mileage varies by connection. Bump 500 a bit higher if necessary
Just add this and all works well:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
If the iframe comes from another server, you will have CORS ERRORS like:
Uncaught DOMException: Blocked a frame with origin "https://your-site.com" from accessing a cross-origin frame.
Only in the case you have control of both pages, you can use https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage to safely send messages like this:
On you main site(one that loads the iframe):
const iframe = document.querySelector('#frame-id');
iframe.contentWindow.postMessage(/*any variable or object here*/, 'https://iframe-site.example.com');
on the iframe site:
// Called sometime after postMessage is called
window.addEventListener("message", (event) => {
// Do we trust the sender of this message?
if (event.origin !== "http://your-main-site.com")
return;
...
...
});
Yes, it's possible although cumbersome. You would need to print/echo the HTML of the page into the body of your page then apply a CSS rule change function. Using the same examples given above, you would essentially be using a parsing method of finding the divs in the page, and then applying the CSS to it and then reprinting/echoing it out to the end user. I don't need this so I don't want to code that function into every item in the CSS of another webpage just to aphtply.
References:
Printing content of IFRAME
Accessing and printing HTML source code using PHP or JavaScript
http://www.w3schools.com/js/js_htmldom_html.asp
http://www.w3schools.com/js/js_htmldom_css.asp

Custom Pinterest button for custom URL (Text-Link, Image, or Both)

I tried to find the solution but can't. I need a custom image for Pinterest (Pin It) button and pin some custom image by url but not a current page.
I created a custom link:
Pin It
in style I set the background image but I see only default Pin It button and not my custom button
There are some solutions where you can set custom button image for Pin It button but I can't change the media={ImageURL} in those solutions.
The popular solution is
<a href='javascript:void((function()%7Bvar%20e=document.createElement(&apos;script&apos;);e.setAttribute(&apos;type&apos;,&apos;text/javascript&apos;);e.setAttribute(&apos;charset&apos;,&apos;UTF-8&apos;);e.setAttribute(&apos;src&apos;,&apos;http://assets.pinterest.com/js/pinmarklet.js?r=&apos;+Math.random()*99999999);document.body.appendChild(e)%7D)());'><img src='http://www.brandaiddesignco.com/blog/PinIt.png'/></a>
But it doesn't help me. Does any one know the solution?
Indeed the popular solution by Jeremy Mansfield at www.brandaiddesignco.com has a great method to customize the Pinterest button any way you want!
I've made three examples, in the form of jsFiddle's, so you can see how it's done using that method.
Reference: jsFiddle Text-Link method
Reference: jsFiddle Custom Logo method
Reference: jsFiddle Custom Logo and Image method
For more Pinterest Info, see my other SO Answer.
Adding an encoded whitespace before the last fragment of the URL will prevent Pinterest's JS from "hijacking" the link:
//pinterest.com/pin/create/%20button?url=
Update:
It seems that my previous solution doesn't work anymore. Here is another one:
//pinterest.com/pin/create%2Fbutton/?url=
At the risk of over simplifying things, use your 'http://pinterest.com/pin/create/button/?url=' path that you've already got, set up your variables, and append them as you do, and just don't include any pinterest javascript. Without that js, it won't find the link and replace it out with their own pinterest button. Just customize your link with an image inside it (or set a background image or whatever) and screw the pinterest js. Set the target to open in a new window.
Custom Link/Button looks like this:
<a href="http://stackoverflow.com/questions/11312923/custom-pinterest-button-for-custom-url-text-link-image-or-both" data-image="http%3A%2F%2Fcdn.sstatic.net%2Fstackexchange%2Fimg%2Flogos%2Fso%2Fso-logo.png" data-desc="Custom Pinterest button for custom URL (Text-Link, Image, or Both)" class="btnPinIt">
Custom Pin it image or text here!
</a>
Note: I don't think the data attributes need to be encoded (like I did for data-image) but it doesn't seem to hurt it.
JQuery:
$('.btnPinIt').click(function() {
var url = $(this).attr('href');
var media = $(this).attr('data-image');
var desc = $(this).attr('data-desc');
window.open("//www.pinterest.com/pin/create/button/"+
"?url="+url+
"&media="+media+
"&description="+desc,"_blank");
return false;
});
Here is what worked for me :
<img src="../img/custompinint.png" />
The attribute data-pin-custom is what I picked up from Pinterest documentation.
Hope this helps.
After a bit of trial and error, below is what worked for me. This response is a combination of #rharvey's response thread and another stack overflow post. This solution opens up a pop up to share content via pinterest.
Note: In order to prevent 2 windows from popping up you need to set a target. Below is the full solution:
<a href="http://stackoverflow.com/questions/11312923/custom-pinterest-button-for-custom-url-text-link-image-or-both" data-image="http%3A%2F%2Fcdn.sstatic.net%2Fstackexchange%2Fimg%2Flogos%2Fso%2Fso-logo.png" data-desc="Custom Pinterest button for custom URL (Text-Link, Image, or Both)" class="btnPinIt" target= "pinIt">
Custom Pin it image or text here!
</a>
<script>
$('.btnPinIt').click(function() {
var url = $(this).attr('href');
var media = $(this).attr('data-image');
var desc = $(this).attr('data-desc');
window.open("//www.pinterest.com/pin/create/button/"+
"?url="+url+
"&media="+media+
"&description="+desc,"pinIt","toolbar=no, scrollbars=no, resizable=no, top=0, right=0, width=750, height=320");
return false;
});
</script>
Works for me perfectly.
Your script
<script>
function pinIt()
{
var e = document.createElement('script');
e.setAttribute('type','text/javascript');
e.setAttribute('charset','UTF-8');
e.setAttribute('src','https://assets.pinterest.com/js/pinmarklet.js?r='+Math.random()*99999999);
document.body.appendChild(e);
}
</script>
Call it with
Pin

I'd like my page titles to automatically scale to fill the available space (horizontally)

I'm creating a blog (via tumblr) and I'd like my page titles to automatically scale to fill the available space horizontally, and perhaps to push the content down a little at the same time.
(by scale, I mean the changing the font size, and perhaps word spacing)
The page titles will all be four words long, so there will probably be between 16 and 40 characters.
I know very little about html, and I'd be extremely grateful to anyone who could help me out. Cheers!
Notice : It's not a pure html/css solution .. I don't think it possible to do it with only html and css so It uses javascript intensively. Also I'm using jquery to do it but it could be easily reproduced with any of the javascript libraries out there. (I'm using a javascript library mainly for two reasons : 1st is the cross-browser compatibility that those libraries brings, as well as the well-tought shortcuts/utility functions and the 2nd reason is the high quantity of plugins that those libraries have to handle most of the situations or to bring free eye-candy to websites)
Hi I didn't find any 'out-of-the-box' solution for this, but it's something I always liked in iphone development and that I missed back in web dev so I decided to give it a try
Here is my solution, it's not perfect but it kinda works :p . I tough it would be not too difficult but I took me some time, anyway I think I might use it some day ... or some knowledge I acquired in the process ...
It has inspirations from this question where they depict a solution based on a loop where they increase/decrease the text size until it fits. But I was not satisfied with a loop for each text to resize and I was sure it could be calculated directly instead of trial-error'ed !
It has also inspirations from here for the window resize handling.
Now stop the chatting, here is the code :
<script type="text/javascript">
var timer_is_on=0;
jQuery.event.add(window, "load", loadFrame);
jQuery.event.add(window, "resize", resizeFrame);
function loadFrame() {
$(".sc_container").each(function(){
var $sc = $(this).children(".sc")
$sc[0].orig_width=$sc.width();
//console.log("saving width : "+$sc[0].orig_width+" for "+$sc[0])
});
resizeFrame()
}
function resizeFrame()
{
$(".sc_container").each(function(){
var $sc = $(this).children(".sc")
var wc = $(this).width();
var scale = 0
if (wc > $sc[0].orig_width) {
scale = wc / $sc[0].orig_width;
} else {
scale = - $sc[0].orig_width / wc;
}
//console.log("applying scale : "+scale+" for "+$sc[0])
$sc.css("font-size",scale+"em")
});
}
</script>
</head>
<body>
<div id="container">
<div class="sc_container">
<div class='sc'>SOME SUPER TITLE !</div>
</div>
<div class="sc_container">
<div class='sc'>ANOTHER ONE !</div>
</div>
<div class="sc_container">
<div class='sc'>AND A THIRD LOOOOOOOOOOOOOONG ONE :) !</div>
</div>
<div> And some normal content</div>
</div>
And here is a test page
It's not really robust .. it doesn't work well when the window is less than 400 px wide, and I only tested it on safari,firefox,chrome on mac.
A little tricky part is that I wanted it to work with multiple texts and so the $(".sc_container").each loop that runs on all the objects with css class ".sc_container".
A last trick is that I use the power of the css 'em' unit : for example '3em' mean 3 times the original text size, so here I can use this to scale from the original text size to the desired text size .. that's why I save the original text width on the DOM objects themselves : $sc[0].orig_width=$sc.width(); and reused it for computations later on resize, otherwise it was messed up after multiple resizes.
What do you guys think about it ?

loading for HTML5

I am launching a mobile site and I want it to have a loading icon while loading all the content and images.
Details:
I have several pages. I want when I click on it will load the pages (to other html page), but I don't want to show the page without fully loaded and I want to show loading animation while it loading all the content. Once, the content is fully loaded. then the loading animation have to hide.
How to do that?
You can make a large <div> at the beginning of the page, then hide it using Javascript in the load event or using an illegal <style> block at the end of the <body>.
You need to give a more specific question to get more specific (useful answers).
In the meantime here are some (hopefully useful) resources:
http://www.devcurry.com/2009/05/display-progress-bar-while-loading.html
http://jquery-howto.blogspot.com/2009/04/display-loading-gif-image-while-loading.html
http://banagale.com/display-a-simple-loading-message-and-animated-loading-gif-using-javascript.htm
http://yensdesign.com/2008/11/how-to-create-a-stylish-loading-bar-as-gmail-in-javascript/
This one may come particularly if it applies to your situation:
Showing a div while page is loading, hiding when its done
Good luck!
Any number of ways, but you will need javascript.
You are ready when all image assets have been loaded. Define full screen div that covers the whole page. In this div, show e.g. loading spinner animated gif and what ever text you want.
<html>
<head> .. </head>
<body>
<div id="loader"> .. </div>
<div id="content" style="display:none"> .. </div>
<script> .. </script>
</body>
</html>
On your script preload all images. This ensures that they are in cache when they are needed.
<script>
var loadc = 0;
function _preload(path) {
var image = new Image;
image.src = path;
image.addEventListener('load', function() {
loadc++;
if (loadc == images.count) {
$("#loader").hide();
$("#hide").show();
}
// update here progress counter on loading div
};
}
var images = [ '/image/some.png', '/foo/bar.png' ]
$(document).ready(function() {
for (var i = 0 ; i < images.length; i++) _preload(images[i]);
});
</script>
You need to define in images array all assets that you want to be ready when content div is shown, this includes stuff referred from CSS and DOM and possible dynamic DOM. You can use this same method for other assets, like audio and json.

Is it possible to load an entire web page before rendering it?

I've got a web page that automatically reloads every few seconds and displays a different random image. When it reloads, however, there is a blank page for a second, then the image slowly loads. I'd like to continue to show the original page until the next page is loaded into the browser's memory and then display it all at once so that it looks like a seamless slideshow. Is there a way to do this?
is the only thing changing the image? if so it might be more efficient to use something like the cycle plugin for jQuery instead of reloading your whole page.
http://malsup.com/jquery/cycle/
Here is the JS needed if you used jQuery -
Say this was your HTML:
<div class="pics">
<img src="images/beach1.jpg" width="200" height="200" />
<img src="images/beach2.jpg" width="200" height="200" />
<img src="images/beach3.jpg" width="200" height="200" />
</div>
Here would be the needed jQuery:
$(function(){
$('div.pics').cycle();
});
no need to worry about different browsers- complete cross browser compatibility.
If you're just changing the image, then I'd suggest not reloading the page at all, and using some javascript to just change the image. This may be what the jquery cycle plugin does for you.
At any rate, here's a simple example
<img id="myImage" src="http://someserver/1.jpg" />
<script language="javascript">
var imageList = ["2.jpg", "3.jpg", "4.jpg"];
var listIndex = 0;
function changeImage(){
document.getElementById('myImage').src = imageList[listIndex++];
if(listIndex > imageList.length)
listIndex = 0; // cycle around again.
setTimeout(changeImage, 5000);
};
setTimeout(changeImage, 5000);
</script>
This changes the image source every 5 seconds. Unfortunately, the browser will download the image progressively, so you'll get a "flicker" (or maybe a white space) for a few seconds while the new image downloads.
To get around this, you can "preload" the image. This is done by creating a new temporary image which isn't displayed on the screen. Once that image loads, you set the real image to the same source as the "preload", so the browser will pull the image out of it's cache, and it will appear instantly. You'd do it like this:
<img id="myImage" src="http://someserver/1.jpg" />
<script language="javascript">
var imageList = ["2.jpg", "3.jpg", "4.jpg"];
var listIndex = 0;
var preloadImage = new Image();
// when the fake image finishes loading, change the real image
function changeImage(){
document.getElementById('myImage').src = preloadImage.src;
setTimeout(preChangeImage, 5000);
};
preloadImage.onload = changeImage;
function preChangeImage(){
// tell our fake image to change it's source
preloadImage.src = imageList[listIndex++];
if(listIndex > imageList.length)
listIndex = 0; // cycle around again.
};
setTimeout(preChangeImage, 5000);
</script>
That's quite complicated, but I'll leave it as an exercise to the reader to put all the pieces together (and hopefully say "AHA!") :-)
If you create two divs that overlap in the image area, you can load one with a new image via AJAX, hide the current div and display the one with the new image and you won't have a web page refresh to cause a the "bad transition". Then repeat the process.
If there's only a small number of images and they're always displayed in the same order, you can simply create an animated GIF.
Back in the dark old days (2002) I handled this kind of situation by having an invisible iframe. I'd load content into it and in the body.onload() method I would then put the content where it needed to go.
Pre-AJAX that was a pretty good solution.
I'm just mentioning this for completeness. I'm not recommending it but it's worth noting that Ajax is not a prerequisite.
That being said, in your case where you're simply cycling an image, use Ajax or something like the jQuery cycle plug-in to cycle through images dynamically without reloading the entire page.