Responsive, cover-fit image tagging - javascript

I am working on a project where I have a slideshow with images as follows:
img {
width:100vw;
height:100vh;
object-fit:cover;
}
This makes the images fullscreen and behave like background-size:cover, so they fill out the whole viewport on any screen size without distortion.
I would like to tag certain points with text tooltips on these images. For this purpose I have found Tim Severien's Taggd, which works great on responsive images, but in my case the object-fit:cover; property makes the tagged positions inaccurate.
I have tried everything from CSS hacks to improving Tim's code, but I am out of ideas. If you have any solution or workaround in mind please share.
Thank you!

well i actually wanted to do the same thing.
here is what i've done.
maybe it will help someone in the future.
it would be great if this feature could be integrated in taggd.
function buildTags()
{
// be aware that image.clientWidth and image.clientHeight are available when image is loaded
var croppedWidth = false;
var expectedWidth = 0;
var croppedWidthHalf = 0;
var imageWidth = 0;
var croppedHeight = false;
var expectedHeight = 0;
var croppedHeightHalf = 0;
var imageHeight = 0;
var naturalRatio = image.naturalWidth/image.naturalHeight;
var coverRatio = image.clientWidth/image.clientHeight;
if(Math.abs(naturalRatio - coverRatio) < 0.01)
{
// the image is not cropped, nothing to do
}
else
{
if(naturalRatio > coverRatio)
{
// width is cropped
croppedWidth = true;
expectedWidth = image.clientHeight * naturalRatio;
croppedWidthHalf = (expectedWidth - image.clientWidth)/2;
imageWidth = image.clientWidth;
}
else
{
// height is cropped
croppedHeight = true;
expectedHeight = image.clientWidth / naturalRatio;
croppedHeightHalf = (expectedHeight - image.clientHeight)/2;
imageHeight = image.clientHeight;
}
}
function calcy(y)
{
if(croppedHeight)
{
var positiony = y * expectedHeight;
if(positiony > croppedHeightHalf)
return (positiony - croppedHeightHalf)/imageHeight;
else // tag is outside the picture because cropped
return 0; // TODO : handle that case nicely
}
else
return y;
}
function calcx(x)
{
if(croppedWidth)
{
var positionx = x * expectedWidth;
if(positionx > croppedWidthHalf)
return (positionx - croppedWidthHalf)/imageWidth;
else // tag is outside the picture because cropped
return 0; // TODO : handle that case nicely
}
else
return x;
}
var tags = [
Taggd.Tag.createFromObject({
position: { x: calcx(0.74), y: calcy(0.56) },
text: 'some tag',
}),
Taggd.Tag.createFromObject({
position: { x: calcx(0.9), y: calcy(0.29) },
text: 'some other tag',
}),
....
];
var taggd = new Taggd(image, options, tags);
}
$(window).bind("load", function() {buildTags();});

Is not possible. Think if the user has a tablet with 1024x768 resolution, when the user change view from horizontal to vertical the image can fill the space but you will loose part of the image, loose img quality, etc.
The best way for cross devices is to use big pictures and add in css
img {
height: auto;
width: 100%;
display: block;
}
And fill image background with a color;

Related

Tile based javascript game - laggy scroll

I am creating a tile based game in javascript. I am absolutely beginner.
The plan is to learn javascript while I trying to make this game. I am having serious lagging issues when I am trying to scroll the "game"
For a live preview you can see here whats bad:
http://iwansfactory.com/tycoon/index.html
My javascript generates them and they HTML part looks like this:
<div class="tiletype100" id="x0y0" style="left: 2151px; top: -540px;"></div>
The css:
.tiletype2 {
z-index: 0;
position: absolute;
width: 600px;
height: 800px;
background-image: url("http://iwansfactory.com/tycoon/road2.png");
background-repeat: no-repeat;
}
The javascript scroll function is this:
var right = document.documentElement.scrollLeft;
var bottom = document.documentElement.scrollTop;
var rightscrollvalue = 0;
var bottomscrollvalue = 0;
function rightenter() {
rightscrollvalue = 40;
scrollright();
}
function leftenter() {
rightscrollvalue = -40;
scrollright();
}
function rightout() {
rightscrollvalue = 0;
}
function scrollright() {
if (rightscrollvalue != 0) {
right = right + rightscrollvalue;
console.log(right);
window.scrollTo(right, bottom);
setTimeout(function() {
scrollright();
}, 50);
}
}
function bottomenter() {
bottomscrollvalue = 40;
scrollbottom();
}
function topenter() {
bottomscrollvalue = -40;
scrollbottom();
}
function bottomout() {
bottomscrollvalue = 0;
}
function scrollbottom() {
if (bottomscrollvalue != 0) {
bottom = bottom + bottomscrollvalue;
console.log(bottom);
window.scrollTo(right, bottom);
setTimeout(function() {
scrollbottom();
}, 50);
}
}
Your design uses large overlapping tiles that are mostly transparent. This requires a lot of CPU power for rendering, thus making the game laggy.
I propose you make your tiles smaller, just as large as they have to be (so there is a non-transparent pixel on every edge of the image) and use offsets for larger tiles so they get rendered at the right position.

Responsive Image Gallery with a content hover effect

After 3 days of trying to figure something out I have come to you, the good people of stackoverflow.
I have managed to create a quite nice looking responsive, masonry type gallery on my website, that I found on CodePen, here - http://codepen.io/justinklemm/pen/iCelj
Heres how it looks on my site - dangoodeofficial.co.uk/290-2
HTML
<div class="gallery">
<img src="http://31.media.tumblr.com/tumblr_loumsfBCuE1qeo682o1_500.jpg">
<img src="http://24.media.tumblr.com/tumblr_m1yru9PNMV1qeo682o1_500.jpg">
<img src="http://24.media.tumblr.com/tumblr_m24ic6kY6Q1qeo682o1_500.jpg">
<img src="http://31.media.tumblr.com/tumblr_lriz0lDN2y1qeo682o1_500.jpg">
<img src="http://24.media.tumblr.com/tumblr_lrmgjaL62O1qeo682o1_500.jpg">
</div>
CSS
body {
padding: 2px 0 0 2px;
}
.gallery img {
float: left;
padding: 0 2px 2px 0;
}
JAVASCRIPT
function scaleGallery()
{
// This is roughly the max pixels width/height of a square photo
var widthSetting = 400;
// Do not edit any of this unless you know what you're doing
var containerWidth = $(".gallery").width();
var ratioSumMax = containerWidth / widthSetting;
var imgs = $(".gallery img");
var numPhotos = imgs.length, ratioSum, ratio, photo, row, rowPadding, i = 0;
while (i < numPhotos) {
ratioSum = rowPadding = 0;
row = new Array();
while (i < numPhotos && ratioSum < ratioSumMax) {
photo = $(imgs[i]);
// reset width to original
photo.width("");
ratio = photo.width() / photo.height();
rowPadding += getHorizontalPadding(photo);
// if this is going to be first in the row, clear: left
if(ratioSum == 0) photo.css("clear", "left"); else photo.css("clear", "none");
ratioSum += ratio;
row.push(photo);
i++;
// if only 1 image left, squeeze it in
if(i == numPhotos - 1) ratioSumMax = 999;
}
unitWidth = (containerWidth - rowPadding) / ratioSum;
row.forEach(function (elem) {
elem.width(unitWidth * elem.width() / elem.height());
});
}
}
function getHorizontalPadding(elem)
{
var padding = 0;
var left = elem.css("padding-left");
var right = elem.css("padding-right");
padding += parseInt(left ? left.replace("px", "") : 0);
padding += parseInt(right ? right.replace("px", "") : 0);
return padding;
}
$(window).load(scaleGallery);
$(window).resize(scaleGallery);
What I am trying to achieve now is something very similar to this - http://thesaxman.com/#gallery
I am not great at HTML/CSS, so I am not sure where to start, as I have tried taking examples from many different hover effect tutorials but I can not get anything to work.
Any help is going to be most highly appreciated.
Thank you,
Dan

How To Scale A Sprite Image In JS

I am using a JS code which originally was written for individual PNG images, but I am converting to using a Sprite Image.
The code originally pulled an image for one part of the code and shrank when the thumbnail was called. What would be the best way to make the same affect now that it's calling a Sprite Class?
//<![CDATA[
var awards2 = {
start : function(){
if(location.href.match(/\/topic\/\d+\/?/)){
for(var a=0;a<t_award2.users.length;a++){
awards2.present(a);
}
}
},
present : function(a){
var award2 = t_award2.users[a];
if($("."+award2[0]+"-awards2").size() == 0){
$("a.member[href="+main_url+"profile/"+award2[0]+"/]").parent().parent().next().find("dl.user_info dd.spacer").before('<dt>'+t_award2.name+':</dt><dd class="'+award2[0]+'-awards2"><div onmouseover="awards2.tooltip.open(event,'+a+');" onmouseout="awards2.tooltip.bye('+a+');" id="'+a+'-award2" class="'+award2[2]+'" alt="'+award2[1]+'" width="'+t_award2.thumbnail[0]+'px" height="'+t_award2.thumbnail[1]+'px" /></dd>');
} else {
$("."+award2[0]+"-awards2").append('<div onmouseover="awards2.tooltip.open(event,'+a+');" onmouseout="awards2.tooltip.bye('+a+');" id="'+a+'-award2" class="'+award2[2]+'" alt="'+award2[1]+'" width="'+t_award2.thumbnail[0]+'px" height="'+t_award2.thumbnail[1]+'px" />');
}
},
tooltip : {
current : 0,
open : function(event,a){
var award2 = t_award2.users[a];
var pos = awards2.mouse.locate(event);
awards2.tooltip.coords = [pos[0],pos[1]];
if($("#"+a+"-tooltip").size() == 0)$("body").append('<div id="'+a+'-tooltip" style="position:absolute;max-width:500px;"><table><thead><tr><th colspan="2">'+award2[1]+'</th></tr></thead><tbody><tr><td><div class="'+award2[2]+'" alt="'+award2[1]+'" /></td><td>'+award2[3]+'<hr /><strong>Received:</strong> '+award2[4]+'</td></tr></tbody></table></div>');
var elem = document.getElementById(a+"-tooltip");
elem.style.left = pos[0]+10+"px";
elem.style.top = pos[1]+10+"px";
awards2.tooltip.current = a;
document.onmousemove = awards2.tooltip.update;
},
update : function(event){
var pos = awards2.mouse.locate(event);
var elem = document.getElementById(awards2.tooltip.current+"-tooltip");
if(elem !== null){
elem.style.left = pos[0]+10+"px";
elem.style.top = pos[1]+10+"px";
} else {
document.onmousemove = null;
}
},
bye : function(a){
switch(t_award2.closeFunction){
case "slide":$("#"+a+"-tooltip").slideToggle("fast",function(){$(this).remove();});break;
case "fade": $("#"+a+"-tooltip").fadeOut("fast",function(){$(this).remove();});break;
default: $("#"+a+"-tooltip").remove();break;
}
}
},
mouse : {
locate : function(event){
e = event || window.event;
coords = [0,0]
if (e.pageX || e.pageY) {
coords = [e.pageX,e.pageY];
}
else {
var de = document.documentElement;
var b = document.body;
coords = [e.clientX + (de.scrollLeft || b.scrollLeft) - (de.clientLeft || 0),e.clientY + (de.scrollTop || b.scrollTop) - (de.clientTop || 0)];
}
return coords;
}
}
}
awards2.start();
//]]>
.exampleclass
{ display: inline-block; background: url(‘sprite.png') no-repeat; overflow: hidden; text-indent: -9999px; text-align: left; }
.exampleclass { background-position: -2px -3491px; width: 50px; height: 50px; }
<script type="text/javascript">
//<![CDATA[
var t_award2 = {
name : “Award”,
thumbnail : [20,20],
closeFunction : "fade",
users : [
[user ID,”Name”,”exampleclass”,”Message”,”Date”],
[user ID,”Name”,”exampleclass”,”Message”,”Date”]
]
}
//]]>
</script>
I read somewhere I'd need something like background-size but I know nothing about how to implement that. Currently when this code runs, the thumbnail loads as the regular size which is too big.
Thanks in advance :)
A couple of weeks ago I looked into creating responsive sprites as well and, while there is a lot of good information out there, none of it ended up working for what I wanted. Here are two of the best examples in my opinion, though both aren't without their drawbacks.
The second link talks about background size but it ends up being tricky depending on whether or not your sprites are all the same size.
http://tobyj.net/responsive-sprites/
http://blog.brianjohnsondesign.com/responsive-background-image-sprites-css-tutorial/

How to make vertical auto scrolling image inside div?

I need auto scrolling image placed inside a div. I saw a code for horizontal auto scroll on this page
http://www.dynamicsights.com/cssscrollback.php
I modified it a little to turn it into vertical auto scroll, but for some reason it stopped working. Can someone please tell me what I did wrong, and is there easier way to make vertical auto scroll?
<div id="scroller"></div>
css:
#scroller
{
width:250px; height:120px;
background-image:url(images/background.png); /* size of that image is 250x600 */
}
js:
function StartMove()
{
var BGImage = new Image();
BGImage.src = "images/background.png";
window.cssMaxHeight = 600;
window.cssYPos = 0;
setInterval("MoveBackGround()", 50);
}
function MoveBackGround()
{
window.cssYPos ++;
if (window.cssYPos >= window.cssMaxHeight)
{
clearInterval(MoveBackGround())
}
toMove=document.getElementById("scroller");
toMove.style.backgroundPosition="0 "+window.cssYPos+"px";
}
Code has so many global variables and removing the interval is wrong.
(function() {
var cssMaxHeight, cssYPos, interval, moveTo;
function MoveBackGround() {
cssYPos++;
if (cssYPos >= cssMaxHeight) {
window.clearInterval(interval);
}
toMove = document.getElementById("scroller");
toMove.style.backgroundPosition = "0 " + cssYPos + "px";
}
function StartMove() {
var BGImage = new Image();
BGImage.src = "images/background.png";
cssMaxHeight = 600;
cssYPos = 0;
interval = setInterval(MoveBackGround, 50);
}
StartMove();
}());

Chrome crashes when trying to modify CSS3 animation from Javascript

I have an HTML file with this:
<div id="container"></div>
and I have a stylesheet with a CSS3 animation defined:
.image {
position: absolute;
-webkit-animation-name: image-create;
-webkit-animation-duration: 1s;
}
#-webkit-keyframes image-create {
from {
width: 0px;
height: 0px;
}
to {
width: 500px;
height: 500px;
}
}
This should make an image grow from 0x0 to 500x500.
In my Javascript file I have the following:
var findAnimation = function(name) {
for (var i in document.styleSheets) {
var styleSheet = document.styleSheets[i];
for (var j in styleSheet.cssRules) {
var rule = styleSheet.cssRules[j];
if (rule.type === 7 && rule.name == name) {
return rule;
}
}
}
return null;
}
var addImage = function(x, y, src) {
var image = new Image();
image.src = src;
image.className = "image";
image.style.width = "500px";
image.style.height = "500px";
image.style.left = x;
image.style.top = y;
image.onload = function() {
document.getElementById("container").appendChild(image);
var animation = findAnimation("image-create");
for (var i in animation.cssRules) {
var rule = animation.cssRules[i];
if (rule.keyText == "0%") {
rule.style.top = y;
rule.style.left = x;
}
if (rule.keyText == "100%") {
rule.style.top = 0;
rule.style.left = 0;
}
}
}
}
addImage(100, 100, "http://i.imgur.com/KGfgH.jpg");
​
When addImage() is called, I'm trying to create an image at the coordinates (x, y). The animation should make it grow while also move from the location where the image was created (x, y) to the top left corner (0, 0).
Instead, Chrome just crashes to the "Aw, snap" page. Does anyone know why this is the case?
EDIT: Here is an example. This crashes for me if I visit it: http://jsfiddle.net/LVpWS/10/
In this one I commented out some lines and it does not crash: http://jsfiddle.net/LVpWS/21/
EDIT2: It works if I switch back to Chrome 20.
I've isolated the error:
The page crashes (Aw, snap) when a new property is added to a WebKitCSSKeyframeRule instance.
The bug can be reproduced in Chrome 21.0.1180.57 using the following code: http://jsfiddle.net/LVpWS/68/
<style id="sheet">
#-webkit-keyframes test {
from {}
}</style><script>
var keyFramesRule = document.getElementById('sheet').sheet.cssRules[0];
var keyFrameRule = keyFramesRule[0];
keyFrameRule.style.top = 0;</script>
This crash does not happen when the property already exists in the rule. Replace from {} with from{top:1px;} to check that: http://jsfiddle.net/LVpWS/69/.

Categories