jQuery Transfer with Flair

jQuery UI’s Transfer effect is a very convenient utility to give an illusion that an element flies to another element. You just need to do the following:

$( "#fromElem" ).effect( "transfer", {to: "#toElem", class: "transferElem"}, 500);

jQuery creates an new <div> element that moves from $(“#fromElem”) to $(“#toElem”) in 500ms. If you want to style the new element, the class name you specified in the 2nd argument is applied on the new element. The height and width are calculated at each step by jQuery.

The usual properties on the class are: borders, background, gradients, box-shadow, etc. All of these are fine except you only get a solid block element.

What if you want some markup (aka child elements) in the new element?

Here’s how I did it

  1. At somewhere you starts the effect.
  2. Immediately after the .effect() call, trigger a “transferStarted” custom event. You can name the event anything you like.
  3. Live-binding “transferStarted” custom event with a event handler function. Let’s call it handleEffectStarted(). Live-binding the important, since the moving element does not exists on the document on page loaded.
  4. In handleEffectStarted(), you are free to create any DOM elements inside $(“#transferElem”).

In my case, I want the moving element contains a person’s image, as if the photo is moving from on place to another. So I dynamically created an <img> in handleEffectStarted(), where the img src is the person’s photo.

Advertisements
Posted in JavaScript | Leave a comment

Triangle

Often you are asked to create a button like this:

Button with Triangle

Button with Triangle

Solution 1: The entire button is an image, with text on it. This solution increases your number of request; relies on CDN, effects accessibility.

Solution 2: Use CSS3 border-radius for the rounded corner. But what about the triangle. You don’t want to a triangle image because of the same reason in Solution 1. Let’s take the CSS challenge, shall we?

If you are familiar with box model, you can have thick border but content size is 0 by 0. What if you just have one side of the border with 0 by 0 content, what you got?

Simple triangle

Simple triangle

HTML:
<div class="triangle"></div>

CSS:
.triangle {
border-color: #FF0000 transparent transparent transparent;
border-width: 10px;
border-style: solid;
width: 0;
height: 0;
}

Change border-color, you can get all 4 triangles pointing to different directions. Play with border width you can get thin or fat triangles too.

You end up a piece of markup for merely decoration purpose.

Solution 3: The most semantic markup with simple CSS is to use Unicode triangle characters. You can find there hex code here. However you don’t want to put these decoration character in markup. Hint…hint…CSS content property to the rescue.

HTML:
<button class="triangle-right">Search</button>

CSS:

button {
border: none;
border-radius: 10px;
color: #FFF;
background-color:#f00;
}
.triangle-right:after {
content: ' \25B6';
font-size: 84.6%;
}

You got it!  Change the character, you gets all 4 directions. You may change font color to control the overall shape, but you can’t make it thin or fat. For that, back to solution 2.

Posted in Tips | Leave a comment

innerHTML vs innerText

This seems to be a very old topic. However I encountered a very interesting bug lately made me think about it again.

What do you think the following jQuery code will display?

myDiv1.html("A&W");
myDiv2.html("A&W Restaurant");

If you are like me, a Firefox or Chrome user, you see everything as you expected. But if you use IE8, you may be surprised. IE8 and lower displays:

A
A&W Restaurant

Why is &W lost from myDiv1? It all comes with IE tries to be smart but not quite there yet. It tries to interpret &W or any character after & as an HTML Entity. Unfortunately, without trailing ; (semi-colon), it can’t. And even more unfortunately, it strips it off.

The fix? In my case, I shouldn’t expect the string to be HTML, so the right call should be using $.text(). However, if the string can sometimes be HTML, you know you should always HTML-encode the string before setting innerHTML. Here is a handy jQuery way to html-encode a string:

function htmlEncode(s) { return $("<div/>").text(s).html(); }

So now they display all the same on all browsers:

$("#myDiv").html(htmlEncode("A&W"));

Even though creating a dangling div does not manipulate DOM, it still need resource from rendering engine. It will slow down your JavaScript if runs many times over.

Posted in JavaScript | Leave a comment

CSS3 TypeWriter

Have you tackled this before? I got this in a recent job search, and they asked me to do this offline exercise.

Using Object Oriented Native Javascript (no libraries) come up with a solution to produce a typewriter effect.

The typewriter effect should involve having each character fade in one by one as if a typewriter was being used to write the text. You need a p tag full of text that you will use as the  base. The text does not matter, lorem ipsum generated text is sufficient.

Here are the rules for the test:

You should not use intervals anywhere in your solution

You must use a linked list data structure in your solution.

Each letter should fade in as it is “typed”, where the fade is an opacity change from 0 to 100% in .2s (the time can change as you desire).

This only needs to work in Safari 5/Webkit.

You can use lorem ipsum generator to create text inside <p>.

I want to use CSS3 Transition on “opacity” to achieve the animation. Instead applying transition on <p>, it should be applied on each character.

How to make each character become an element on which you can apply transition? Break each character in to its own span. And make sure they are not visible by apply initial opacity to 0.

Once you got all the <span>s, all you need to do is to apply transition on each of them and each have a delay 0.2 seconds longer than its previous <span>

span.style.webkitTransition = "opacity 0.2s linear " + parseFloat(i * 0.2) + "s";
span.style.opacity = 1;

I created a JavaScript class called “Typewriter”. It’s constructor is attached to the <p>. The constructor breaks text into <span>s.

Typewriter expose a public function “start()”, called on any event you want to have the animation start.

One drawback is you cannot get the original text of <p> any more. So Typewriter constructor remembers original text before breaking up text, and expose another public function “getText()” which returns the original text.

Posted in CSS3 | 3 Comments

HTML5 SVG

American Flag

American Flag

In my previous post, I explained how to draw an American flag using HTML5 <canvas>. In this post, I’ll explain another solution using SVG. For this example, I’m using <polygon> tag. You can let server produce the polygons’ markup, or you can use javascript to write them out.

You first use simple <div>s and CSS to layout the stripes and blue rectangle. The same 10 points’ coordinates are used for a single polygon. The rest to logic to shift coordinated horizontally and for each row remain the same as in the previous post.

Here is the syntax for one polygon:

<polygon  points="x0,y0 x1,y1 ..." fill="#FFFFFF"></polygon>

Here is the code for SVG part inside blue rectangle:

<div class="blue" id="blue">
<script type="text/javascript">
html = "<svg id=\"svgelem\" height=\"178\" width=\"219\" xmlns=\"http://www.w3.org/2000/svg\">";

var points = [[7,15], [12,15], [14,9], [16,15], [21,15], [17,19], [20,25], [14,21], [9,25], [11,19]],
	points_count = points.length,
	row = 9,
	stars_per_row,
	r,
	s,
	p,
	x,
	y;

	for (r = 0; r < row; r++) {
		stars_per_row = (r % 2) ? 5 : 6;	
		for (s = 0; s < stars_per_row; s++) {
			html += "<polygon  points='"
			for (p = 0; p < points_count; p++) {
				x = points[p][0] + 38 * s + (r % 2) * 16;
				y = points[p][1] + 18 * r;
				html += x + "," + y + " ";
			}
			html += "' fill='#FFFFFF'></polygon>";
		}
	}

html += "</svg>";
document.write(html);
</script>
</div> <!-- blue -->
<div class=”blue” id=”blue”>
<script type=”text/javascript”>
html = “<svg id=\”svgelem\” height=\”178\” width=\”219\” xmlns=\”http://www.w3.org/2000/svg\”>”;

var points = [[7,15], [12,15], [14,9], [16,15], [21,15], [17,19], [20,25], [14,21], [9,25], [11,19]],
points_count = points.length,
row = 9,
stars_per_row,
r,
s,
p,
x,
y;

for (r = 0; r < row; r++) {
stars_per_row = (r % 2) ? 5 : 6;
for (s = 0; s < stars_per_row; s++) {
html += “<polygon  points='”
for (p = 0; p < points_count; p++) {
x = points[p][0] + 38 * s + (r % 2) * 16;
y = points[p][1] + 18 * r;
html += x + “,” + y + ” “;
}
html += “‘ fill=’#FFFFFF’></polygon>”;
}
}

html += “</svg>”;
document.write(html);
</script>
</div> <!– blue –>

Posted in HTML5 | Leave a comment

HTML5 <canvas>

American Flag

American Flag

Implement an American flag without using image.

Here is one solution using <canvas>.

Most front-end engineers can use simple <div>s and css to show the red/white strips and the blue rectangle at the upper-left corner.

To output the 50 stars, you need an <canvas> inside the blue rectangle <div>.

Then, use Javascript to generate 50 stars.

Use “path” to draw each star. There are 10 points in the path. You only need to specify the 10 point coordinates for the top-left-most star. Close the path and fill it with white color. This is how you draw one star.

Build a loop for each row. There are 6 stars on odd rows, 5 stars on even rows. In each row, you need horizontally shift the coordinated of the previous star. When on a odd row, you only need to increase y. When on a even row, besides y, you also need ti increase x so the the star is positions in the middle on the 2 stars of the previous row.

The outer-most loop generates total 9 row.

<!DOCTYPE HTML>
<html>
<head>
<title>American Flag</title>
<style type="text/css">
.flag {
 width: 470px;
 height: 331px;
 background-color: #FFF;
 position: relative;
}
.red {
 background-color: #CC0000;
 height: 25px;
}
.white {
 background-color: #FFFFFF;
 height: 26px;
}
.blue {
 width: 219px;
 height: 178px;
 position: absolute;
 top: 0;
 left: 0;
 background-color: #000066;
}
</style>
</head>

<body>
 <div>
<script type="text/javascript">
var html = "",
 stripe,
 stripeClass;
for (stripe = 0; stripe < 13; stripe++) {
 stripeClass = (stripe % 2) ?  "white" : "red";
 html += "<div class=\"" + stripeClass + "\"></div>";
}
document.write(html);
</script>

 <div id="blue">
 <canvas id="canvas" width="219" height="178"></canvas>
 </div> <!-- blue -->
 </div> <!-- flag -->

<script>
var c=document.getElementById("canvas"),
 cxt=c.getContext("2d"),
 points = [[7,15], [12,15], [14,9], [16,15], [21,15], [17,19], [20,25], [14,21], [9,25], [11,19]],
 points_count = points.length,
 row = 9,
 stars_per_row,
 r,
 s,
 p;

cxt.fillStyle="#ffffff";

for (r = 0; r < row; r++) {
 stars_per_row = (r % 2) ? 5 : 6;
 for (s = 0; s < stars_per_row; s++) {
 cxt.beginPath();
 x = points[0][0] + 38 * s + (r % 2) * 16;
 y = points[0][1] + 18 * r;
 cxt.moveTo(x, y)
 for(p = 1; p < points_count; p++) {
 x = points[p][0] + 38 * s + (r % 2) * 16;
 y = points[p][1] + 18 * r;
 cxt.lineTo(x, y);
 }
 cxt.closePath();
 cxt.fill();
 }
}
</script>
</body>
</html>



Posted in HTML5 | Leave a comment