How to include Retina images in Timber? - timber

I'd really like to improve my website (built with Timber) for Retina displays and browsed through past issues on GitHub as well as the Docs. So I added a srcset and used the retina filter (which is deprecated?) and that retina resizing works quite well, but not really in conjunction with the standard resize filter. Also, I saw that there's an ImageHelper class which provides a retina_resize function/filter(?), but I'm not quite sure how to use it.
This is my code right now:
<img srcset="{{ TimberImage(image).src | resize(208) | retina(1) }} 1x, {{ TimberImage(image).src | retina(2) | resize(416) | retina(2) }} 2x">
Any tips about the best practices for Retina-ready images in Timber are greatly appreciated :)
Thanks!

Best approach is to create a Macro that will generate the HTML markup for you. I use a Macro that takes an image ID and will check the media width and output the appropriate HTML for retina images.
You can view the Macro that I created here.
You would then use the Macro like this to generate the appropriate HTML
{% import '_macros/_img.twig' as m_img %}
{{m_img.fixed(imageId, 50, {alt: 'post thumbnail', class: 'fixed'})}}

Related

PNG Images crashing on iPhone and other mobile devices

I really have no idea why this is happening and I really hope someone had this issue before! My current problem is I'm running an ecommerce website with approx. 2500 products. All product images are in PNG format because the must be transparent (Design-Requirement). On Desktop everything works fine, going on mobile the Images start crashing or however you would call that. Images are being replaced by already loaded ones and sometimes they reverse colors.
All images are in RGB / PNG-24 (Size: 732 x 732 px).
The code I'm using in case of relevance:
<img title"{{ product.name }}"
alt="{{ product.name }}"
itemprop="contentUrl"
class="product-img"
src="{{ product.thumbnail.src }}"
srcset="{{ product.thumbnail.src|resize(250, 250)|retina(1) }} 1x,
{{ product.thumbnail.src|resize(250, 250)|retina(2) }} 2x,
{{ product.thumbnail.src|resize(250, 250)|retina(3) }} 3x,
{{ product.thumbnail.src|resize(250, 250)|retina(4) }} 4x" />
The shop runs on Wordpress / WooCommerce and uses Timber Twig for templating. In my opinion this is an image error not a code problem.
Any help appreciated :)
What's happening is Safari is running out of memory. This can result in strange artifacts, or the page crashing entirely, leaving only a shell of the app remaining.
All browsers on iOS use UIWebView internally, so even Chrome will show this issue.
The only way to solve this is to limit how much you load to the page. Try to only show images that need to be shown, and hide what the user isn't looking at. Use a pager if needed, or dynamically resize all images before displaying them.
A weird trick I have used previously is to load all images to canvas elements instead. These typically have a smaller memory footprint. Canvas does not support transparency directly but you can draw things on top of each other to simulate it.
A basic way to handle changing all images to canvas is like this
$(function(){
$("canvas").each(function(){
var newImage = new Image();
var self=this;
var ctx = self.getContext("2d");
newImage.onload = function () {
var orgWidth = newImage.naturalWidth;
var orgHeight = newImage.naturalHeight;
ctx.drawImage(newImage, 0, 0, orgWidth, orgHeight, 0, 0, self.width, self.height);
};
newImage.src = $(self).data("url");
});
});
canvas{
width:100%;
height:100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas data-url="https://www.google.ca/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png"></canvas>
Obviously this hand nothing todo with any image format or similar.. While surfing for another problem I found this Blogpost about "iOS6 html hardware acceleration changes and how to fix them".
http://indiegamr.com/ios6-html-hardware-acceleration-changes-and-how-to-fix-them/
Pretty old, but still a problem on iOS 11. I am using filter so set a shadow on my image. All was working but not on the iPhone. So I added following lines:
-webkit-transform: translateZ(0);
-webkit-perspective: 1000;
-webkit-backface-visibility: hidden;
That's it! :)

Hugo: Automatically Link Headers

With Hugo static site generator, is it possible to have it automatically put links around header elements? I see that it does fill in the ID attribute so it can be referenced but I would like to automatically create the link as well, like this:
<a href="/post/cool-blog-post#some-interesting-title">
<h2 id="some-interesting-title">Some Interesting Title</h2>
</a>
I did not see anyway in the documentation to do this and I think it would be helpful for users linking to a particular point in a lengthy post.
As far as I'm aware it's not possible to achieve it out-of-the-box, that is, out-of-the-hugo.
I had this same wish myself; I solved it via jQuery, wrapping all h2's and h3's dynamically with links, generating slugs on the go:
Then I've got a sticky sidebar nav which acts as a way to smooth-scroll between the headings, plus it highlights the current heading:
Today I would code it differently code-wise (probably without jQuery) but I'm quite happy with how it works. I think JS overhead is minimal, especially if coded neatly.
This doesn't seem to be possible out of the box. There are two ways of working around it that I can think of: using JavaScript, as revelt suggested, or using HTML in your markdown.
For example, consider the HTML you supplied above.
<a href="/post/cool-blog-post#some-interesting-title">
<h2 id="some-interesting-title">Some Interesting Title</h2>
</a>
If you put this code directly into a Hugo markdown document, it will produce the kind of link you are looking for. However, this is a pain to type every time, so to reduce your work you can make a shortcode.
In layouts/shortcodes/link-heading.html:
{{ $id := .Get 0 | lower | replaceRE "[^0-9a-z]" "-" | replaceRE "-+" "-" -}}
<a href="#{{ $id }}">
<h2 id="{{ $id }}">{{ .Get 0 }}</h2>
</a>
In your markdown document:
{{< link-heading "Some Interesting Title" >}}
I have left the base URL out here, but you can pass it as a parameter from your markdown document if you want. (Of course, then you have to know what the URL is without having Hugo do it for you, which is not ideal.)
This approach has the disadvantages that you can't use the normal markdown heading syntax, and that you don't get Hugo's built-in resolution of duplicate anchors. But it will get the job done.
Easy enough with javascript, add this snippet before your closing </body> tag:
<script>
(function addHeadingLinks(){
var article = document.getElementById('article');
var headings = article.querySelectorAll('h1, h2, h3, h4, h5, h6');
headings.forEach(function(heading){
if(heading.id){
var a = document.createElement('a');
a.innerHTML = heading.innerHTML;
a.href = '#'+heading.id;
heading.innerHTML = '';
heading.appendChild(a);
}
});
})();
</script>

dynamic responsive image grid with separator

I need to achieve the following grid(this is for desktop version):
So far I have listed the images, added the separator after each of them and tried to apply this plugin: https://github.com/brunjo/rowGrid.js to the container.
The separator is a pic too, it has to be responsive, on desktop I would need 4 in a row, but on tablet 6. Here my html so far:
<div id="competences">
{% for competence in competences %}
<div class="item-c">
<a href="">
<img src="/uploads/competence/{{ competence.logo }}" alt="{{ competence.name }}">
</a>
<img src="{{ asset('bundles/aeliusfront/images/competencies_separator.png') }}" class="cross_separator">
</div>
{% endfor %}
</div>
Any help, idea would be appreciated, Thanks.
PS. The tablet version has to be full-width, and has to contain 6 images on one row, with the same style(separator)
I had a quick look at rowGrid.js, it looks like its a nice plugin to fit images into a given width, but I don't think you can constrain how many are in each row.
I've written a plugin myself: here. With it you can specify an exact layout in rows and columns which changes at given width breakpoints of the container. This will solve the basic layout grid issue. You might find some other plugins that will also do that, I imagine it would be possible with media queries too, you could for instance set the images at 25% width for the 4 across layout, and at 16.66% width for the 6 across.
The separator just needs some CSS to work properly. My plugin script creates container divs to hold each row. In this case you can do something like this:
.cross-separator:first-child { display: none }
.hs-row-container:first-child .cross-separator { display: none}
You'd need to use css to position the cross separator to the top left corner of the image.
Hope this is clear enough.

AngularJS view rendering issue

I am using ng-view to render dynamic data on my page. When the page loads, if I use static html I get this (top):
When Angular loads the page the data is there but it's like the element is still empty (bottom).
If I make even the slightest adjustment in Chrome dev tools, the items snap into place but I cannot get them to prefill without using CSS to make them static sizes, which doesn't work because text is different sizes. The elements in question have CSS of inline-block.
As you can see in this screenshot, I have tried two ways of populating the data, both with the same result:
<div class="cd-rating" ng-class="caseData.scoreClass">
<span class="score" ng-bind="caseData.adjustedScore | number:0" ng-cloak>N/A</span>
<span class="verdict">{{caseData.recommendation}}</span>
</div>
Here is the what the HTML looks like in the browser:
<div class="cd-rating medium" ng-class="caseData.scoreClass">
<span class="score ng-binding" ng-bind="caseData.adjustedScore | number:0">349</span>
<span class="verdict ng-binding">review</span>
</div>
If I hard-code that HTML identically, then it renders perfectly. It's only when Angularjs renders it that the elements are collapsed, appearing if there is not content.
I would also like to add that I am using RequireJS and manually bootstrapping the app instead of using the ng-app directive, in case that matters.
Any ideas on how to make the view fill the elements?
EDIT: Here is a video that demonstrates the behavior: http://youtu.be/zTwv-o6mWRM
I am not able to figure out what exactly you mean by the "..data is still there but the element is empty.." - the only issue that I find with the rendering by AngularJS is that the "Review" (button?) is overwritten with the number.
Looking at your code (which, as #Wingman4l7 suggests needs to be posted in the question rather than as a image), I see that you are using bindings to define a class dynamically. Instead, can you use the ng-class directive and see if it resolves the issue?
That is, replace:
<div class="cd-rating {{caseData.scoreClass}}">
with
<div class="cd-rating" ng-class="caseData.scoreClass">
instead and check if the issue gets resolved?

What's the best way to handle Retina Displays? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I set retina graphics for my website?
What is the best method for adding 2x images to webpages that will be displayed on the new iPad with Retina graphics?
I've gone through these articles.
http://www.kylejlarson.com/blog/2012/creating-retina-images-for-your-website/
http://www.teamdf.com/web/automatically-serve-retina-artwork/191/
http://retinajs.com/
There are various suggested methods for tackling the problem of Retina displays (and large display screens etc.) unfortunately most of these are just that, suggestions.
The two most popular are the suggestion of adding a tag, which accepts multiple images and the browser will load only one (dependant on media queries specified by the developer):
<picture alt="angry pirate">
<source src=hires.png media="min-width:800px">
<source src=midres.png media="min-width:480px">
<source src=lores.png>
<!-- fallback for browsers without support -->
<img src=midres.png alt="angry pirate">
</picture>
The other suggestion is specifying multiple sources for an image using 'srcset' on an image:
<img alt="Cat Dancing" src="small-1.jpg"
srcset="small-2.jpg 2x, // this is pretty cool
large-2.jpg 100w, // meh
large-2.jpg 100w 2x // meh#2x
">
I personally think this is a lot more ugly (and it leaves you less control as the browser decides which image to load) but from my understanding the second solution has been added to the official spec (in some capacity)
Outside of these suggestions the only real current solution is to start with an image 2x the original size (or 1.5x depending on your preference)
It may be possible to try and get all fancy and do a JavaScript solution, but I think that would be over complicating things ...
Below is a really good articles which discusses the issue you describe (I feel I'm rambling a bit!):
http://www.alistapart.com/articles/mo-pixels-mo-problems/

Resources