This is my first question here so I apologize if it's not in the right formt. I don't know why but images work perfectly fine in my desktop computer but are out of place in my mobile devices. I used chrome's mobile simulator and it works fine there too. But not in the real mobile device.
Please help :(
There are many possibilities...
Without a look at your code, or knowing the OS for the device used it is impossible to provide a precise answer.
However, I experience similar issue with Foundation right out of the box... not sure why as well. In my application my up-loader re sizes each image and stores them in small, medium, and large folders. As a result, I need precise control on which image to load depending on device.
I came up with the system below which allows for the application of CSS to be applied according to device: This may or may not resolve you issue.
Mobile Detect
I went here to get Mobile Detect which I identifies the device used.
Code to call Mobile Detect
This calls the detect script and assigns device size to the variable: $thisImg
# mobile detect
require_once ($level.'core/ini/mobile-detect.php');
$detect = new Mobile_Detect; $deviceType = ($detect->isMobile() ? ($detect->isTablet() ? 'tablet' : 'phone') : 'computer');
if($layoutType == 'mobile'){$thisImg = 'small';}
elseif($layoutType == 'tablet'){$thisImg = 'medium';}
elseif($layoutType == 'classic'){$thisImg = 'large';}
Store Device Size
To store the device size I use a hidden input with an id of img_sizer
echo '<input type="hidden" id="img_sizer" value="'.$this_img.'">';
jQuery
By assigning a class to the image you can now control the CSS on all the images with that assigned class according to device and can manage various image classes through jQuery.
$('img.respond').each(function(){
var which_size = $('#img_sizer').val(); // my hidden input
if(which_size == 'small'){$(this).addClass( "text-center" );} // add center class for small
})
Determining Folder Path
In my application I use the following jQuery to assign the proper folder path to the image source. The code came from Stack here
$('img.respond').each(function(){
var which_size = $('#img_sizer').val(); // my hidden input
var msrc=$(this).attr('src');
msrc=msrc.split('/'); //images, services, image.jpg
var lastelem = msrc.pop(); //images, services // lastelem: image.jpg
msrc.push(which_size); //images, services, large // lastelem: image.jpg
msrc.push(lastelem); //images, services, large, image.jpg
msrc=msrc.join('/'); //"images/services/large/image.jpg"
$(this).attr('src', msrc);
if(which_size == 'small'){$(this).addClass( "text-center" );} // add center class for small
})
Related
I am using the pug templating engine to design the front-end of my website, and would want to make it responsive (desktop and mobile compatible), however, I have different background images for the desktop and mobile views respectively, and would like to know of a way to specify the different sources of background images for the same component within a mixin in JSON format. Here is the code where I am calling the jcfcards mixin:
block content
.flexboxcontainer
+jcfbanner
+jcfcards({"src": "/assets/images/Letter-J.png", "text":"Career Map"})
+jcfcards({"src": "/assets/images/Letter-C.png", "text":"Competencies"})
+jcfcards({"src": "/assets/images/Letter-F.png", "text":"Learning Roadmap"})
Here is the code for the jcfcards mixin:
mixin jcfcards(spec)
- spec = spec || {}
- spec.__class = spec.__class || ''
div(style=`background-image:url('${spec.src}')`).jcfcardtitle(class=spec.__class)&attributes(attributes)
if spec.text == "Career Map"
p.careerMap= spec.text
else
p= spec.text
.icon-long-right
If there is any other way I can tackle this problem, I would highly appreciate any inputs on that as well. :)
We have a component that contains a background image. Our front-end guy needs it to be loaded through CSS (i.e. background: url(/*path here*/)...). The following is a possible solution we came up with:
#string src = // Get image path from Sitecore().Field("Picture");
<div style="background: url(#src) left top no-repeat;"> ... </div>
However, there are two problems with this approach:
It makes it very difficult for the content editor to swap out the image. They will have to manually change it through edit item.
It feels like a hack/workaround.
So the question is as follows: Is there a way to edit the CSS of an element through Razor/Sitecore? Specifically, the background: field.
I had a similar case and I used :
<footer class="layout_footer" style="background-color: #Model.BackgroundColor">
on view rendering (cshtml file)
And on the model we have :
public string BackgroundColor
{
get
{
Sitecore.Data.Fields.ImageField imgField =((Sitecore.Data.Fields.ImageField)item.Fields["BackgroundImage"]);
return Sitecore.Resources.Media.MediaManager.GetMediaUrl(imgField.MediaItem);
}
}
For editing this field in page editor you can use Sitecore Field Editor from a command : http://blog.istern.dk/2012/05/21/running-sitecore-field-editor-from-a-command/
Check for edit mode, and display in edit mode a editable field. Also create a Custom Experience Button from the Field Editor Button Type. You can also display. See User friendly developing with the Sitecore Experience Editor
#string src = // Get image path from Sitecore().Field("Picture");
<div style="background: url(#src) left top no-repeat;">
#if (IsInEditingMode)
{
<h3>Backgroiund Picture: #Editable(m => m.Picture)</h3>
}
</div>
There is no Sitecore extension method which will do this out of the box (i.e. #Html.Sitecore().Field("fieldName") will not work here as it would render the entire image tag (also a load of other non-image markup in page editor mode) as you probably know.
The method that #sitecore climber mentions is useful for controller renderings (or view renderings with a custom RenderingModel). If you want to stick with simple view renderings (i.e. not create a RenderingModel) then you could create a Html extension method which can be re-used on any view rendering. This could be something like the following:
public string ImageFieldSrc(this SitecoreHelper sitecoreHelper, string fieldName, Item item = null)
{
if (item == null) {
item = sitecoreHelper.CurrentItem;
}
var imageField = new ImageField(item.Fields[fieldName]);
var mediaItem = imageField.MediaItem;
var mediaUrl = MediaManager.GetMediaUrl(mediaItem);
mediaUrl = HashingUtils.ProtectAssetUrl(mediaUrl); //if you want to use media request protection (adding the hash onto the end of the URL, use this line
return mediaUrl;
}
It's worth noting that if you are using Sitecore 7.5 or above there is a feature to protect media URLs with a hash to prevent malicious DoS type attacks described in this blog post by Adam Najmanowicz.
In summary; if you are using Sitecore 7.5+ and you use media hashing then you will need to call HashingUtils.ProtectAssetUrl on the media URL if it is to respect size parameters.
How do I make my highslide gallery take only specific images (e.g., contained in a specific div)?
I've got a gallery here: http://civicsector.org.ua/agitation/247-kampanya-chesn-vibori.html, but the problem is that the CMS I'm using outputs the content twice: once for a desktop screen, and once for a mobile screen.
While highslide is loading images from both divs (for desktop and for mobile), the images in the thumbstrip get duplicated.
How do I fix this?
Thanks.
Place your images into a slideShowGroup, per the Highslide JS API:
http://highslide.com/ref/hs.slideshowGroup
Then, the script will load only the images that are tagged as belonging to that group. The references to the images that your CMS creates won't be tagged as belonging to the group, so they won't get loaded into the slideshow twice.
MisterNeutron's answer was perfect for the common usage of highslide. However, in case anyone would use unobtrusive highslide (like myself), you just have to add a check in the hs.onSetClickEventHandler:
hs.onSetClickEvent = function ( sender, e ) {
if ($(e.element).closest('.hidden-desktop').length>0) {
return false;
}
// set the onclick for the element
e.element.onclick = function () {
return hs.expand(this, inPageOptions);
}
// return false to prevent the onclick being set once again
return false;
}
I have a ruby on rails web app, and in some views i have many heavy images( <img> ) to render .The <img> are generated in a Helper.
The problem is that the css is loaded first, then the js, then the heavy images , and then finally the css refereneced background images.
It takes quite a while for all of the heavy images to load, which therefore holds the whole site up.
I want to load first the css background images then load the other images, as they obviously hold visual structure of the page.
rails version: 2.3.8
EDIT:
Thank you guys, I apologize for not having shared the code earlier.
I have two models : Categories and Images, each Category has many images.
In the view i have a list of categories, which is generated by a helper :
categories.each do |cat|
html << "<a href='##{cat.id}' class='mapcat' >#{cat.libelle}</a>"
end
and when I click on the category the images are displayed
categories_images.each do |i|
html << "<div id='#{i.id}' class='#{css}'><img src='/images_moi/categories/#{cat.libelle}/#{i.path_file_name}' />"
end
I have css background image associated to the list of category
The problem is that the images (<img>) is displayed before the css background images of the list of categories.
We need to assume things because you haven't shared your code.
Coming to your query, for now you can preload images using jQuery:
function preload(arrayOfImages) {
$(arrayOfImages).each(function(){
$('<img/>')[0].src = this;
// Alternatively you could use:
// (new Image()).src = this;
});
}
// Usage:
preload([
'img/imageName.jpg',
'img/anotherOne.jpg',
'img/blahblahblah.jpg'
]);
This saves the loading time of loading images.
Use a base64 string.
Example:
background-image: url(data:image/png;base64,*CONVERTED IMAGE DATA HERE*);
without: **
online converter: http://webcodertools.com/imagetobase64converter
note: I only would suggest this if the image size is not too heavy.
Solution: Do not use the img tag.
Create a sprite containing all your images. Load the sprite in your application.html layout once.
Use data uris to transmit the data directly in the html. See http://css-tricks.com/data-uris/
My approach is to lazy load the images using jquery and data- tags. This approach also allows me to choose different images based on device width and spare tablet/mobile users.
<img src="" data-src="/img/graphic-desktop.jpg" data-smallsrc="/img/graphic-smaller.jpg" alt="Graphics" class="lazy" />
<!-- the following would be in your js file -->
$lazy = $('img.lazy');
$(window).load(function(){
// window load will wait for all page elements to load, including css backgrounds
$lazy.each(function(){
// run thru each img.lazy on the page. spare the jquery calls by making $this a variable
$this = $(this);
// if the window is greater then 800px wide, use data-src, otherwise, use the smaller graphic
($(window).width() >= 800) ? $this.attr('src', $this.attr('data-src')) : $this.attr('src', $this.attr('data-smallsrc'));
});
});
Due to screen density of iPhone, image assets are developed larger. So, when specifying the icons and images to Flex components takes this form.
<s:ViewNavigator id="tab1" label="Tab1 width="100%" height="100%" firstView="views.Tab1">
<s:icon>
<s:MultiDPIBitmapSource source160dpi="#Embed('assets/tabIcon.png')"/>
</s:icon>
</s:ViewNavigator>
Flex of course renders this correctly and adjusts the size to what it should be.
However, when I load images myself, they appear blown up as they would appear double in size.
This is how I use it when overriding the tab bar.
public class TabbedViewNavigatorTabBarSkin extends ButtonBarSkin
{
[Embed (source="/assets/tabBar.png" )]
private var TabBarPng:Class;
override protected function createChildren():void
{
var bgb:Bitmap = new TabBarPng() ;
addChild(bgb);
}
}
This is when the image appears blown up. What am I doing wrong?
Well I think what you're trying to get it to do can be achieved with the following code, this is basically going to negate the work done internally to scale the asset based on the screen size, while allowing it to scale other components based on the DPI, I'm not sure exactly how this will play out in practice.
import mx.core.mx_internal;
...
var bgb : Bitmap = new TabBarPng();
bgb.scaleX = 1 / systemManager.mx_internal::densityScale;
bgb.scaleY = 1 / systemManager.mx_internal::densityScale;
or another possibility I think is:
var mul : MultiDPIBitmapSource = new MultiDPIBitmapSource();
mul.source160dpi = new TabBarPng();
var bgb : BitmapImage = new BitmapImage();
bgb.source = mul;
var gr : Graphic = new Graphic();
gr.width = 100 / systemManager.mx_internal::densityScale; //not sure if you'd want densityScale being applied here or what? Same below just a matter of testing on more devices
gr.height = 100 / systemManager.mx_internal::densityScale;
gr.addElement(bgb)
addChild(gr);
[From MultiDPIBitmapSource API doc]
This class provides a list of bitmaps for various runtime densities. It is supplied as the source to BitmapImage or Image and as the icon of a Button. The components will use the Application.runtimeDPI to choose which image to display.
I think this documentation:
http://help.adobe.com/en_US/flex/mobileapps/WS19f279b149e7481c682e5a9412cf5976c17-8000.html
is probably still the clearest explanation you'll find though it's not entirely clear how this will affect the application at run-time on different devices. The best option is to just test on as many devices as you can (or need to support).