Resizing images by maintaining aspect ratio - loop - actionscript-3

I need some help creating a more performant code to resize images and maintain their aspect ratio. So I made an instance in Flash "Image_Placeholder" that is being used to load in images from an external XML file.
These images should fit in the placeholder of let's say 120px by 120px.
So far the code I'm using is the following:
function ResizeImage2(){
image.width=120;
image.scaleY=image.scaleX;
image2.width=120;
image2.scaleY=image2.scaleX;
if(image.height>120 && image2.height>120){
image.height=120;
image.scaleX=image.scaleY;
image2.height=120;
image2.scaleX=image2.scaleY;
}
else if(image.height>120 && image2.height<120){
image.height=120;
image.scaleX=image.scaleY;
}
else if(image.height<120 && image2.height>120){
image2.height=120;
image2.scaleX=image2.scaleY;
}
}
ResizeImage2();
How do I create a loop that does this function for each image? Instead of creating more else statements as more images get loaded in.

I found the solution:
function ResizeImage(obj:Object){
var imgname =obj;
imgname.width=120;
imgname.scaleY=imgname.scaleX;
if(imgname.height>120){
imgname.height=120;
imgname.scaleX=imgname.scaleY;
}
}
ResizeImage(image);
ResizeImage(image2);

Related

Is it possible to hide an html element if dynamic content requires more space?

I would like to hide an html Element (in my case a headline) only when the dynamic content of the site expands so far vertically that a scrollbar would appear. I am aware how to hide an element but I don't know how to trigger the event. I am searching for something like the #media rule in css, only that it shouldn't be triggered on the viewport resolution, but the size of the content (vertically).
Does anyone know a solution to this?
Thanks in advance!
Thanks to Nicks comment I figured out a solution.
If anyone is looking for the same thing, here is a working Javascript solution (no JQuery needed):
var callback = function(){
// Handler when the DOM is fully loaded
// Check if the body height is bigger than the clients viewport
if (document.body.scrollHeight > document.body.clientHeight) {
// Assign a class with display:none (in my case 'hide')
document.getElementById("headline").className = 'hide';
}
};
// This part ensures that the script will be loaded once the site is loaded
if (
document.readyState === "complete" ||
(document.readyState !== "loading" && !document.documentElement.doScroll)
) {
callback();
} else {
document.addEventListener("DOMContentLoaded", callback);
}
With help by https://www.sitepoint.com/jquery-document-ready-plain-javascript/

Touch location misinterpreted on iPad when rescaling an iframe showing a kineticjs canvas

I am building a widget using KineticJS (which is fantastic). It allows the user to drag images around in a canvas.
I can view and use the widget inside an iframe: this works perfectly on all the browsers and devices I have tried.
I can even scale that iframe so the page is responsive. Following another stackoverflow post, I have added the css:
#media screen and (max-width : 768px) {
iframe {
-moz-transform-origin: 0 0;
-o-transform-origin: 0 0;
-webkit-transform-origin: 0 0;
-moz-transform: scale(0.85);
-o-transform: scale(0.85);
-webkit-transform: scale(0.85);
}
}
This works well on my Mac.
But on an iPad, although the iframe appears properly scaled, when you try to drag elements around, it seems to think they are in their unscaled positions.
Is there a way I can get this to work on the iPad too? Or do I need to rethink my design (in which case, what design should I use)?
thanks!
Thanks to #irie11's suggestion, I have now implemented this. In the interests of posterity, here is my full approach.
I added some javascript to rescale the canvas when the window changes size:
function scaleCanvasToContainer() {
var container_width = $("#my-containers-parent-id").width();
var scale = 1.0;
if (container_width<target_width) {
scale = container_width/target_width;
}
$("#my-container-id").css("max-height",scale*target_height+"px");
stage.setScale(scale,scale);
stage.setWidth(scale*target_width);
stage.setHeight(scale*target_height);
stage.draw();
drawLines();
}
window.onresize = function(event) {
scaleCanvasToContainer();
}
...
scaleCanvasToContainer();
Note the above also resizes the canvas (i.e. changes its width and height), and for good measure sets the maximum height through css too.
I discovered that when you use context.moveTo() these coordinates are not scaled, so I had to manually scale them, e.g.
function drawLines() {
var canvas = layer.getCanvas();
var context = canvas.getContext();
var scaleX = stage.getScaleX();
var scaleY = stage.getScaleY();
context.beginPath();
context.moveTo(targetX*scaleX,targetY*scaleY);
...
}
I changed the css on my canvas a little to include:
background-size: contain;
background-repeat: no-repeat;
So far, we have scaled the content to the size of the containing iframe. However, we also need to make that iframe have the right size.
So I added some javascript to the calling page:
<script>
function scaleIFrame() {
var target_width = 850;
var container_width = $("#iframe-parent").width();
var width = target_width;
if (container_width<target_width) {
width = container_width;
}
$("#iframe-parent iframe").css("width",width+"px");
}
window.onresize = function(event) {
scaleIFrame();
}
scaleIFrame();
</script>
This leaves me with just one problem: setting the height of the iframe. In theory I should be able to access the height of the contents of the iframe using something like this (see this link):
var iframe = $("iframe");
var iframe_internal = iframe.contents().find("#my-content");
iframe.css("height",iframe_internal.style.height+"px");
This requires the two sites involved to be at the same domain; if they are on the same top-level domain you can still do it if you include a document.domain tag in both the iframe content and the calling page (see this SO post). You may also want to give your localhost the domain name you are using, so that you can test it (see this SO post) - I just added a new line to my /etc/hosts file: '127.0.0.1 local.example.com'.
I followed this last process (my two sites have the same top-level domain), but when I print out the iframe_internal variable it is an object with zero length, so something is going wrong here.
Still, I am very happy to have got this far. It works on the iPad and all browsers I have tested.

Prevent images from being downloaded to page on mobile site

How can I make it so that within the mobile version of my site the images are not downloaded to from the web server as these are large files that are not needed and not being used and therefore severely impacting the use of the mobile version of the site. Having looking at previous threads of such nature I saw that hiding the parent of the image using code such as below can benefit.
.parent {display:block;}
.background {background-image:url(myimage.png);}
#media only screen and (max-width:480px) {
.parent {display:none;}
}
The problem being I don't want to use background image CSS for SEO issues associated with them as I like to use Schema tagging etc ..so how can I prevent an IMG tag from being downloaded, as display:none; only hides the image rather than stopping it being downloaded.
Note: This is not for copyright protection issues e.g. preventing right click etc etc but for speed and ultimately size of the downloaded content to mobile.
This solution uses CSS to prevent background-images from loading and jQuery to prevent images from loading. I'm not familiar with any CSS solution that will prevent images from loading.
JS Fiddle: http://jsfiddle.net/CoryDanielson/rLKuE/6/
If you know the images height and width (or even ratio) ahead of time you could set the background-image for a bunch of fixed size DIVs. This might be applicable for icons and layout-type images. Look at the HTML/CSS below for an example of that.
Background Images
/* hidden by default */
aside {
display: none;
}
/* Pictures load for 'big screen' users.. pcs/tablets? */
#media screen and (min-width: 750px) {
aside {
display: block;
}
.catpicDiv {
height: 100px;
width: 100px;
display: inline-block;
border: 1px solid red;
background-image: url('http://img2.timeinc.net/health/images/slides/poodle-1-400x400.jpg');
background-size: cover;
}
}
and HTML
<aside>
<div class="catpicDiv"></div>
<div class="catpicDiv"></div>
<div class="catpicDiv"></div>
</aside>
Image Elements are a different story...
I don't know of any purely CSS solution to prevent them from loading the images. So I'd solve it like this:
Define IMG tags as follows
<img src="" data-src="url-to-image.jpg" />
Then, somewhere in the head of the document you need similar javascript
1) Function to load all of the images
function loadAllTheImages() {
$("img").each(function(){
$(this).attr('src', $(this).attr('data-src'));
});
}
2) Code to determine if the user is on mobile or a PC (slow vs fast connection) and then load the images.
This code isn't bulletproof, there are much more accurate and reasonable tests than this.
$(window).load(function(){
if ( $(window).width() > 750 ) {
loadAllTheImages(); // !
} else {
$("body").append("<a id='mobileCheck' href='javascript: void(0);'>I GOTS 4G, LEMME HAVE EM!</a>");
}
});
3) As well as maybe some code to activate a button to load the images anyways? Why not, I guess... ?
$(document).ready(function(){
$('body').prepend("<h1>" + $(window).width().toString() + "</h1>");
$('body').on('click', '#mobileCheck', function(){
loadAllTheImages(); // !
$("#mobileCheck").remove();
});
});
Similar solution as here and what I hypothesized in the comments:
Delay image loading with jQuery
There is no native solution in CSS that would prevent images from loading even if you hide them or set display to none.
You have to use some JS to achieve that result. If you are familiar with JS that should not be an issue at all. There are several plugins ready to go to do what you want. You can also write your own JS because its not that difficult.
Here is my code that loads images based on the screen size:
DEMO AT CODE PEN
It works without any libraries like JQ but if you use one of those it will automatically switch to it (Tweak it to your specific needs).
JS
// use jQuery or pure JS
if (typeof jQuery !== 'undefined') {
// jQuery way
// alert("jquery");
$(function() {
$(window).on('load resize', function() {
var products = $("[data-product-image]");
products.each(function(key, value) {
var bg = null;
if (window.outerWidth < 500) return;
if (window.outerWidth < 1000) bg = $(value).data("product-image-s");
if (window.outerWidth >= 1000) bg = $(value).data("product-image");
console.log($(window).outerWidth);
$(value).css({
'background-image': 'url(' + bg + ')',
'background-position': 'center',
'background-size': 'cover',
});
});
});
});
} else {
// Pure JS way
// alert("JS");
(function() {
window.addEventListener('load', wlImageLoader);
window.addEventListener('resize', wlImageLoader);
function wlImageLoader() {
console.log('event! Trig trig');
var all = document.getElementsByTagName("div");
var products = [];
for (i = 0; i < all.length; i++) {
if (all[i].hasAttribute('data-product-image')) {
products.push(all[i]);
}
}
Array.prototype.forEach.call(products, function(value) {
var bg = null;
var curent = window.getComputedStyle(value).getPropertyValue('background-image');
console.log(curent);
if (window.outerWidth < 500 || curent != 'none') return;
if (window.outerWidth < 1000 && curent == 'none') bg = value.getAttribute('data-product-image-s');
if (window.outerWidth >= 1000 && curent == 'none') bg = value.getAttribute('data-product-image');
// if (window.outerWidth >= 2000 && curent == null) bg = value.getAttribute('data-product-image-l');
if(bg == null || curent != 'none') return;
value.style.backgroundImage = "url(" + bg + ")";
value.style.backgroundPosition = "center";
value.style.backgroundSize = "cover";
curent = window.getComputedStyle(value).getPropertyValue('background-image');
console.log(curent);
});
}
})();
}
HTML
<div data-product-image="img/something_normal.jpg" data-product-image-s="img/something_small.jpg" id="p3" class="product">
However if you are a time loading freak you probably prefer to write your code natively in JS as you often don't use most of the jQuery library. For fast internet connection this is not a problem but if you target mobile devices on country side that might make a difference.
I would suggest combining perhaps the #import and #media commands to only #import the stylesheet which contains images if the #media tag meets you criteria (say, over a certain resolution).
So by default you wouldn't import the stylesheet which applies the BG image, you'd only end up doing it if you had determined the site was 'non-mobile'..if that makes sense!
The W3c site has some decent examples of combining the rules:
http://www.w3.org/TR/css3-mediaqueries/#media0

Image load with site load

Hello I make simple site but I have a little trouble with loading images. As you can see with new category there is new image. There is a problem, beacause only then img is loading, and I want to load all images when my site is loading.
sample code how I operate with those img.
imgUrls.push("img/01.jpg");
imgUrls.push("img/02.jpg");
var k3:Boolean=false;
btn1.addEventListener(MouseEvet.CLICK, clickFunc);
function clickFunc(e:MouseEvent):void
if (k3==false)
{
img1.myUILoader.source = imgUrls[0];
k3=true;
}else
{
img2.myUILoader.source = imgUrls[0];
k3=false;
}
btn2.addEventListener(MouseEvet.CLICK, clickFunc2);
function clickFunc2(e:MouseEvent):void
if (k3==false)
{
img1.myUILoader.source = imgUrls[1];
k3=true;
}else
{
img2.myUILoader.source = imgUrls[1];
k3=false;
}
So my question is: How can I load all img with site.?
Your code currently is telling the program to load the images when either btn1 or btn2 is clicked. You need to tell the program to load the images right away, before user input, then have btn1 and btn2 display them.

Google Images heterogeneous Thumb Positioning

Google Image Search returns Images of different sizes. even their Thumbs are of different size. But still they are arranged in such a way that keeps a clean margin. even resizing the browser keeps the left and right alignment proper. What I've noticed is they group a Page of Image into an ul and each image is in an li. not all rows contain same amount of images. But still how they manage to keep images of different sizes properly aligned ?
EDIT
Though I've accepted an answer Its not exact match. It may be a near match. However I still want to know What is the exact procedure they are doing. I cannot chalk out the pattern.
It seems that they wrap a page in a <ol> and put images in <li> But when I resize the images are redistributed among pages. But how many images the page <ol> should contain now is to be decided. What procedure can be used to accomplish that ? and also images are resized based on a standard height I think. and that standard height is changed on resize. How how much ? how that is decided ?
It's not exactly the same thing, but you might get some useful ideas about how to optimize image "packing" by looking at the approach taken by the jQuery Masonry plug-in.
They know how big each thumbnail is, since it's stored in their image database. They just make each <li> float left, and make them a fixed size based on whatever the largest image is within that section of images.
I've written a little plugin just to do that HERE you can watch it in action:
(function($){
//to arrange elements like google image
//start of the plugin
var tm=TweenMax;
var positionFunc= function(options, elem){
var setting=$.extend({
height:150,
container:$('body'),
margin:5,
borderWidth:1,
borderColor:'#000',
borderStyle:'solid',
boxShadow:'0 0 0 #000',
borderRadius:0,
type:'img'
},options);
tm.set($(elem),{
'max-height':setting.height
});
$(elem).wrap('<div class="easyPositionWrap"></div>');
var winsize=setting.container.width();
var thisrow=0;
var elementsused=0;
var row=0;
tm.set($('.easyPositionWrap'),{
border:setting.borderWidth+'px '+setting.borderStyle+' '+setting.borderColor,
borderRadius:setting.borderRadius,
boxShadow:setting.boxShadow,
margin:setting.margin,
height:setting.height,
position:'relative',
display:'block',
overflow:'hidden',
float:'left'
});
$('.easyPositionWrap').each(function(index, element) {
if(thisrow<winsize){
thisrow+=$(this).width()+(setting.margin*2)+(setting.borderWidth*2);
}
else{
var currentwidth=thisrow-$(this).prevUntil('.easyPositionWrap:eq('+(elementsused-1)+')').width()-(setting.margin*2)+(setting.borderWidth*2);
var nextimagewidth=$(this).prev('.easyPositionWrap').width()+(setting.margin*2)+(setting.borderWidth*2);
var elems=$(this).prevAll('.easyPositionWrap').length-elementsused;
var widthtobetaken=(nextimagewidth-(winsize-currentwidth))/(elems);
if(widthtobetaken!=0){
if(elementsused==0){
$(this).prevUntil('.easyPositionWrap:eq(0)').each(function(index, element) {
$(this).width($(this).width()-widthtobetaken);
$(this).find(setting.type+':first-child').css('margin-left','-'+(widthtobetaken/2)+'px');
});
$('.easyPositionWrap:eq(0)').width($('.easyPositionWrap:eq(0)').width()-widthtobetaken);
$('.easyPositionWrap:eq(0) '+setting.type).css('margin-left','-'+(widthtobetaken/2)+'px');
}
else{
$(this).prevUntil('.easyPositionWrap:eq('+(elementsused-1)+')').each(function(index, element) {
$(this).width($(this).width()-widthtobetaken);
$(this).find(setting.type+':first-child').css('margin-left','-'+(widthtobetaken/2)+'px');
});
}
}
elementsused+=elems;
thisrow=$(this).width()+(setting.margin*2)+(setting.borderWidth*2);
}
});
$(window).resize(function(){
clearTimeout(window.thePositionTO);
window.thePositionTO=setTimeout(function(){
$(elem).each(function(index, element) {
$(this).unwrap('.easyPositionWrap');
$(this).data('easyPositioned',false);
});
$(elem).easyPosition(options);
},200);
});
}
$.fn.easyPosition= function(options){
if($(this).data('easyPositioned')) return;
positionFunc(options, this);
$(this).data('easyPositioned',true);
};
//end of the plugin
}(jQuery));
$(window).load(function(){
$('img').easyPosition();
});
libraries to include:
jQuery
GreenSock's TweenMax