Skip to content

Instantly share code, notes, and snippets.

@mrcoles
Created February 15, 2018 18:22
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mrcoles/5bf502eb2b1f3c80ed1e8a6fe3399300 to your computer and use it in GitHub Desktop.
Save mrcoles/5bf502eb2b1f3c80ed1e8a6fe3399300 to your computer and use it in GitHub Desktop.
A lightweight approach to pausing gifs on a webpage.
/** .pause-gif */
.wrap-pause-gif {
position: relative;
text-align: center;
}
.pause-gif {
visibility: hidden;
}
.pause-gif.processed {
visibility: visible;
}
.wrap-pause-gif .wrap-canvas {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
opacity: 1;
transition: opacity .5s ease-in-out;
}
.wrap-pause-gif.show-still .wrap-canvas {
opacity: 0;
}
.wrap-pause-gif img,
.wrap-pause-gif .wrap-canvas canvas {
max-width: 100%;
}
window.PauseGifs = function(contextSelector) {
var d = document;
// supports checks
var supports = {
querySelectorAll: !!d.querySelectorAll,
canvas: (function() {
var elem = d.createElement("canvas");
return !!(elem.getContext && elem.getContext("2d"));
})(),
classList: (function() {
var elem = d.createElement("div");
return !!elem.classList;
})()
};
// gifs
if (supports.querySelectorAll && supports.canvas && supports.classList) {
var query = (contextSelector ? contextSelector + " " : "") + "img.pause-gif";
var elts = d.querySelectorAll(query);
var i = elts.length;
var elt, p;
while (i > 0) {
i--;
elt = elts[i];
p = elt.parentNode;
p.classList.add("wrap-pause-gif");
_asCanvas(elt, _insertCanvas);
}
} else {
try {
var s = d.createElement("style");
s.innerHTML = ".pause-gif { visibility: visible; }";
d.getElementsByTagName("head")[0].appendChild(s);
} catch (e) {}
}
function _insertCanvas(img, canvas) {
_drawTriangle(canvas);
var wrap = d.createElement("span");
wrap.className = "wrap-canvas";
wrap.appendChild(canvas);
img.parentNode.appendChild(wrap);
img.parentNode.addEventListener(
"click",
function() {
this.classList.toggle("show-still");
},
false
);
img.classList.add("processed");
}
function _asCanvas(img, cb) {
var imgObj = new Image();
imgObj.src = img.src;
imgObj.onload = function() {
var c = d.createElement("canvas");
c.width = this.width;
c.height = this.height;
var ctx = c.getContext("2d");
ctx.drawImage(img, 0, 0);
cb(img, c);
};
}
function _drawTriangle(canvas) {
var w = canvas.width;
var h = canvas.height;
var dim = 20;
dim = Math.min(dim, w / 2 - 5, h / 2 - 5);
var ctx = canvas.getContext("2d");
ctx.save();
ctx.fillStyle = "rgba(255, 255, 255, .85)";
ctx.beginPath();
ctx.moveTo(w / 2 - dim * 0.7, h / 2 - dim);
ctx.lineTo(w / 2 - dim * 0.7, h / 2 + dim);
ctx.lineTo(w / 2 + dim, h / 2);
ctx.closePath();
ctx.fill();
ctx.restore();
}
};
@mrcoles
Copy link
Author

mrcoles commented Feb 15, 2018

I added this to my blog. I write posts in markdown with the "extras" extension enabled, which let’s me use special attributes.

In my Python code the markdown conversion looks like this:

from django_markwhat.templatetags.markup import markdown
body_html = markdown(body, 'extra,codehilite')

I can then use the special attributes support to add classes to the gifs as such:

![some animation](/media/img/animation.gif){.pause-gif}

Then, if I want to target all posts on my blog, they all live under the CSS class "post", so I run the PauseGifs function as so (either at the bottom of the body or in a document ready function):

PauseGifs('.post');

See a pause gifs example here.

It’s not perfect, since it cannot start at the beginning of the gif each time. There are more advanced approaches that grab the gif via an XHR request, parse it manually, then let you control the GIF exactly how you want, see libgif-js or freezeframe.js.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment