<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Martini Lab Blog &#187; tips</title>
	<atom:link href="http://www.martinilab.com/blog/tag/tips/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.martinilab.com/blog</link>
	<description>Web design, CSS, scripting, Adobe, tips and other scraps of things that come my way</description>
	<lastBuildDate>Fri, 20 Aug 2010 20:58:52 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Webmail adds image spacing</title>
		<link>http://www.martinilab.com/blog/224/webmail-adds-image-spacing/</link>
		<comments>http://www.martinilab.com/blog/224/webmail-adds-image-spacing/#comments</comments>
		<pubDate>Fri, 20 Aug 2010 16:27:07 +0000</pubDate>
		<dc:creator>Chris Williams</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://www.martinilab.com/blog/?p=224</guid>
		<description><![CDATA[Attention you HTML email authors. Your newsletters are jacked. Webmail apps, in an effort to prevent the automatic downloading of images in order to prevent open rates for spammers, use scripts to manipulate the loading of images. Unfortunately, this changes &#8230; <a href="http://www.martinilab.com/blog/224/webmail-adds-image-spacing/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Attention you HTML email authors.  Your newsletters are jacked.  Webmail apps, in an effort to prevent the automatic downloading of images in order to prevent open rates for spammers, use scripts to manipulate the loading of images.  Unfortunately, this changes the default property for <code>display</code> for images and causes gaps or spacing to occur.</p>
<h3>For example</h3>
<p>Weak sauce!</p>
<p><a href="http://www.flickr.com/photos/amboy00/4910806646/"><img alt="Email with image gaps" src="http://farm5.static.flickr.com/4097/4910806646_6123125530.jpg" title="email broken" class="alignnone" width="500" height="442" /></a></p>
<h3>Inline fix</h3>
<p>The fix is simple, add an inline style to all of your images.</p>
<pre>&lt;img src="..." style="display: block;"... &gt;</pre>
<p>This change works on gmail, hotmail, yahoo, mobileme, etc.</p>
<p>Awesome sauce!</p>
<p><a href="http://www.flickr.com/photos/amboy00/4910204573/in/photostream/"><img alt="This email has no gaps in its images" src="http://farm5.static.flickr.com/4122/4910204573_88a4ec4f28.jpg" title="email fixed" class="alignnone" width="500" height="442" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.martinilab.com/blog/224/webmail-adds-image-spacing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tackling Safari’s slow gif “feature” with jQuery</title>
		<link>http://www.martinilab.com/blog/75/tackling-safaris-slow-gif-feature-with-jquery/</link>
		<comments>http://www.martinilab.com/blog/75/tackling-safaris-slow-gif-feature-with-jquery/#comments</comments>
		<pubDate>Fri, 17 Apr 2009 23:19:36 +0000</pubDate>
		<dc:creator>Chris Williams</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[adobe]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[hacks]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Photoshop]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[usability]]></category>
		<category><![CDATA[WebKit]]></category>

		<guid isPermaLink="false">http://www.martinilab.com/blog/?p=75</guid>
		<description><![CDATA[Safari’s WebKit has a funny behavior of displaying animated gif files at a lower frame rate than Firefox. From what I can tell, WebKit (including Google Chrome) caps the animated gif frame rates at 10fps. While it may be faster &#8230; <a href="http://www.martinilab.com/blog/75/tackling-safaris-slow-gif-feature-with-jquery/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Safari’s WebKit has a funny behavior of displaying animated gif files at a lower frame rate than Firefox. From what I can tell, WebKit (including Google Chrome) caps the animated gif frame rates at 10fps. While it may be faster than some IE6 browsers, it’s not exactly helpful for those files with higher frame rates.</p>
<p>For example, the popular ajax loader file that hails from Apple’s own <a href="http://developer.apple.com/documentation/userexperience/Conceptual/AppleHIGuidelines/XHIGControls/XHIGControls.html">asynchronous progress indicator</a>, has 12 points and loops around once a second.  Well, for one thing, 12fps is really choppy, but it already plays slower on Apple’s nifty browser.</p>
<h2>jQuery to the rescue</h2>
<p>Did you know that jQuery can control css background positions? Are you thinking what I’m thinking?<br />
<span id="more-75"></span></p>
<h2>But first, back to drawing board</h2>
<p>So the first part was to break up the animated gif frames and spread them out across a very long canvas. Since Photoshop no longer opens animated gif files (unless you own ImageReady somewhere), Fireworks can open the file. Use Fireworks to export the frames to individual files and THEN Photoshop can import all the files as a stack.</p>
<p>File <code>&lt;Scripts&gt;</code> Load Files into Stack…</p>
<p>For our ajax loader, expand all the layers next to each other and then save it out to its own gif.  The file size won’t be that difference in fact.</p>
<h2>Now let’s get back to jQuery</h2>
<p>In our html, just set the div with a width and height to match your gif to prevent clipping and let the script do the rest.</p>
<pre lang="javascript" line="1">

$(document).ready(function(){
	var bgimage = 'url(images/ajax-loader-long.gif)';
	var frames = 24;
	var mpf = parseInt(1000/frames)  // how many miliseconds in each frame
	var currentFrame = 0;
	var offset = 0;

	$('.animate').css('background-image', bgimage);

	function animate() {
		offset = currentFrame * 64;
		$('.animate').css('background-position', '-' + offset + 'px 0px');
		currentFrame = (currentFrame == frames) ? 1 : currentFrame + 1;
	}

	setInterval(animate, mpf);
});
</pre>
<p>Now we have a script that will snap the position of the background over each “frame” at the correct frame rate. Actually, the frame rate is not divisible by 1000, but it’s close and it’s not like you could tell.</p>
<p>The only problem with this script is that it’s constantly running. If you look at the page in Firebug, your going to see the code whipping around with new values all the time. Annoying! Also, chances are your page isn’t going to need some animation playing constantly. Ajax loaders are intermittently called when a simple action is called as a… asynchronous progress indicator! Who knew.</p>
<p>So we’re going to put in a cancel command to this script: <strong>clearTimeout</strong>.</p>
<pre lang="javascript" line="1">

$(document).ready(function(){
	var bgimage = 'url(images/ajax-loader-long.gif)';
	var frames = 24;
	var mpf = parseInt(1000/frames)  // how many miliseconds in each frame
	var currentFrame = 0;
	var offset = 0;
	var runAnimate = 0;

	$('.animate').css('background-image', bgimage);

	function animate() {
		offset = currentFrame * 64;
		$('.animate').css('background-position', '-' + offset + 'px 0px');
		currentFrame = (currentFrame == frames) ? 1 : currentFrame + 1;
	}

	runAnimate = setInterval(animate, mpf);

	$('.animate').toggle(
		function () {
			clearTimeout(runAnimate);
		},
		function () {
			runAnimate = setInterval(animate, mpf);
		}
	);
});
</pre>
<p>Add in a toggle so show how to turn on and off the animation and were done.</p>
<p>It even works on ie6!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.martinilab.com/blog/75/tackling-safaris-slow-gif-feature-with-jquery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>jQuery missing layerX</title>
		<link>http://www.martinilab.com/blog/68/jquery-missing-layerx/</link>
		<comments>http://www.martinilab.com/blog/68/jquery-missing-layerx/#comments</comments>
		<pubDate>Wed, 08 Apr 2009 18:41:46 +0000</pubDate>
		<dc:creator>Chris Williams</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[event]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://www.martinilab.com/blog/?p=68</guid>
		<description><![CDATA[Getting the Mouse position in jQuery is very simple. However, getting the position from within an element take some extra steps. Normally, a javascript event such as onmousemove would use event.layerX and event.layerY to get the coordinates of our mouse &#8230; <a href="http://www.martinilab.com/blog/68/jquery-missing-layerx/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Getting the Mouse position in jQuery is very simple.  However, getting the position from within an element take some extra steps.</p>
<p>Normally, a javascript event such as <code>onmousemove</code> would use <code>event.layerX</code> and <code>event.layerY</code> to get the coordinates of our mouse when it moves.</p>
<p>For jQuery, <code>pageX</code> and <code>pageY</code> will return values from the top left of the page and not the layer.  Unless the element you’re working with is left-aligned, you need to calculate the offset of that element as well.  Not only that (unless there is a better way to do this) the offset values returned doesn’t include the offset values of the parent tag.</p>
<p>In this example, I have two divs.</p>
<pre lang="html4strict" line="1">
&lt;div id="frame"&gt;
	&lt;div id="content"&gt;&lt;/div&gt;
&lt;/div&gt;
</pre>
<p>And you can imagine that <code>#frame</code> is centered and has padding. Getting <code>#content</code>’s offset won’t include anything outside of the frame so <code>$(#content).offset().left;</code> would only get you the distance of itself and its parent.</p>
<h2>Get your layerX for jQuery</h2>
<p>For this example, we are using a known set of divs so we can just write out each div in this script.</p>
<pre lang="javascript" line="1">

$(document).ready(function(){
	$('#canvasForeground').mousemove(function(e){
		var myLayerX = $('#content').offset().left + $('#frame').offset().left;
		var myLayerY = $('#content').offset().top + $('#frame').offset().top;
		var x = 0, y = 0;
		x = e.pageX - myLayerX;
		y = e.pageY - myLayerY;
	});
});
</pre>
<p>The variables are declared inside the event function to handle window resizing.  Now were this a more complicated page and the element in question has deeply nested or even dynamically generated, writing our all the parent tags wouldn’t necessarily work (or be very efficient).* But the approach would remain the same.  That’s it!</p>
<p>*<em>standard apology for poor code writing skills</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.martinilab.com/blog/68/jquery-missing-layerx/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adobe Illustrator Eraser on Wacom strokes</title>
		<link>http://www.martinilab.com/blog/23/adobe-illustrator-eraser-on-wacom-strokes/</link>
		<comments>http://www.martinilab.com/blog/23/adobe-illustrator-eraser-on-wacom-strokes/#comments</comments>
		<pubDate>Sat, 25 Oct 2008 17:39:25 +0000</pubDate>
		<dc:creator>Chris Williams</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[adobe]]></category>
		<category><![CDATA[cs3]]></category>
		<category><![CDATA[illustrator]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://www.martinilab.com/blog/?p=23</guid>
		<description><![CDATA[Scott, here’s how to save your brush strokes in Illustrator CS3 and still be able to edit them!]]></description>
			<content:encoded><![CDATA[<p>Scott, here’s how to save your brush strokes in Illustrator CS3 and still be able to edit them!</p>
<p><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/Mnu8Rb4I7os&#038;hl=en&#038;fs=1"></param><param name="allowFullScreen" value="true"></param><embed src="http://www.youtube.com/v/Mnu8Rb4I7os&#038;hl=en&#038;fs=1" type="application/x-shockwave-flash" allowfullscreen="true" width="425" height="344"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://www.martinilab.com/blog/23/adobe-illustrator-eraser-on-wacom-strokes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
