WiredPrairie

A little bit of everything: software, apps, usability, programming, design and whatever else

  • Home
  • About
  • Contact Me
  • Cooking
  • Nest Thermostat
  • Old Archives
  • Photography
  • Quick Searches
  • You need this

A bit of reflow, using TweenJS

Posted by Aaron on Sunday, May 13th 2012    Tweet

Inspired by some modern applications (especially the “Metro” look and feel), I wanted to put together an animated tile reflow script for an HTML page I was creating.

As the size of the page changes, the tiles move into their new positions.

SNAGHTML113b633f[4]

You can try it here, if you’re using a modern browser (IE9+, Chrome, FF, Safari, etc.).

Dependencies:

  1. TweenJS
  2. EaselJS (for the ticker used in TweenJS)
  3. CSSPlugin (an add on to the the TweenJS library)
  4. jQuery (1.7.2)

Relayouts are queued (as to prevent multiple from running).

Only boxes that will be visible to the end user (either animating to the screen or off the screen) are animated. It does not animate elements that do not start or end in the current viewport including boxes that would animate “through” the current viewport. I considered the latter to not add anything to the overall experience and just uses more CPU to perform the animations, so I intentionally left it out.

In the layout loop, the code verifies that the animation needs to run:

// here's the final destination
pos = { left: Math.round(x), top: Math.round(y) };

// check old and new positions, if either are in the viewport, we'll animate
if (isScrolledIntoView(pos.top + parentOfBoxesOffsetTop, boxH) || isScrolledIntoView(box.y + parentOfBoxesOffsetTop, boxH)) {
    Tween.get(box.e).to(pos, 500 + 500 * Math.random(),
        Ease.quadInOut).call(function () {
            --layoutPending;
            if (!layoutPending && queuedLayout) { queueLayout(); }
    });
} else {

If it needs to animate, the code uses the static Tween method “get” to start an animation on the current element.

  1. Tween.get(box.e) creates a new instance of the Tween class (initialized with the element to tween).
  2. Using that Tween instance, the CSS attributes (thanks to the handy CSSPlugin), for left and top are animated for at least 500ms and up to a full second. The easing function I chose is quadInOut. Tip: Here’s a great way to visualize easing options using TweenJS.
  3. Finally, when the animation completes, an anonymous function is called which decrements the number of pending animations and if there are no remaining elements to animate, and there’s something queued, another cycle is started.

All the code used by the demo is in default.html.

Colors of the boxes were set using hsl (only available in modern browsers):

box.style.backgroundColor = "hsl(" + c + ", 100%, 50%)";

Where “c” is:

c = (i / boxes * 360).toFixed(1);

Filed under: Coding     Tags: Animation, JavaScript, Metro, TweenJS
No Comment Yet   

Adding an External Tool for Compiling LESS files in WebStorm (on Windows)

Posted by Aaron on Friday, April 27th 2012    Tweet

Interested in converting/compiling LESS files into their CSS counterparts?

Here are the steps (from version 4 of WebStorm from JetBrains).

1. Install Node JS

2. Install the node package (using npm) for less (remember where you install this as you’ll need the path later):

    npm install less

3. In WebStorm, File > Settings, then under the IDE Settings heading, select External Tools.

4. Click on the + icon to add a new tool:

image

5. You’ll see a dialog very much like this:

SNAGHTMLcd7f5f5

6. Fill it out like this (substitute whatever you’d like of course):

SNAGHTMLceae4a7

I chose not to have the console window open every time the compilation occurs.

The only things you’ll need to change is the path to the file lessc. That file is actually JavaScript file (minus the extension). So, replace the first quoted parameter in “Parameters” above with the location that you installed the package for less in.

As it’s a JavaScript file you need to be executed, the “Program” is set to the node executable. Provide the full path (when I didn’t, it sometimes wouldn’t work and would complain that a path didn’t exist).

"###YOUR PATH TO LESSC###\lessc" $FilePath$ "$FileDir$\$FileNameWithoutExtension$.css"

I tried using the Working Directory option and it also worked inconsistently with Node. So, I used the options you see above and it seemed to work more consistently.

7. I also added a shortcut so I could execute it on demand:

SNAGHTMLcdbd3f4

SNAGHTMLcdc51ca

I picked Ctrl+Alt+L, as it was memorable (and available!).

While this is not using a file watcher technique (you could do that if you’d like instead), it works well enough for my workflow.

Filed under: Coding     Tags: JetBrains, Less, WebStorm
No Comment Yet   

Backup Reminder for Windows Home Server 2011

Posted by Aaron on Thursday, April 26th 2012    Tweet

This is just a reminder to anyone who uses Windows Home Server’s Backup functionality to verify Backups are working.

I love the “turn it on and forget about it” feature of WHS backup. Computers automatically wake, backup, and sleep. Nice.

However, I noticed last week that at some point WHS2011 had an issue more than a month ago where it no longer was backing up ANY of the Windows PCs in our house (2 laptops, 2 desktops).

No actionable errors had occurred in March that I could find, so I can’t pinpoint a reason. I needed to go to every Windows PC in our house and re-enable backups. Thankfully, it didn’t need to start over from scratch (it picked up where it left off).

image

Needless to say, having your computer backups silently fail is a bit worrisome. As many WHS2011 users likely don’t routinely go to the WHS dashboard – you might want to occasionally and check that every thing is OK.

I don’t use the LAUNCHPAD much as it tends to be the “software who cried wolf” too often. But, even if I had, I couldn’t see any indication in the Dashboard that I would have been alerted to this issue (since alerts are all saved until resolved or ignored).

SNAGHTML7ba7bdb

(The two warnings shown in the screenshot are for: “Important updates should be installed.” and “Free space is low.” AKA, A drive has only 62GB free (10%)).

If you do use the LAUNCHPAD, you can verify the last backup by clicking the “Backup” button. You should see something like this in the dialog that is opened:

image

Filed under: General, Recommendations     Tags: WHS2011, WindowsHomeServer
No Comment Yet   

SVG Setting Text Content Dynamically

Posted by Aaron on Tuesday, April 17th 2012    Tweet

Continuing on a theme of animating SVG, I’ve added a label in the center of the animation which contains the current angle of the ever-rotating marker (in fact in a centered horizontally and vertically SVG text node).

(Click image below to try it.)

image

At the bottom of the file from the previous post, I’ve added the following:

    <text id="currentValueAsText" x="300" y="300"
        style="text-anchor: middle;alignment-baseline:middle"
        fill="#FFFFFF" font-family="'Arial'" font-size="96" opacity=".6">0</text>

It’s a new text node. It’s set to centered both horizontally and vertically (using the text-anchor and alignment-baseline style properties respectively) at 300,300.

Setting the content is simple as well:

(function () {
    window.onload = loaded;
    function loaded() {
        var colorTemp = document.getElementById("color-temp");
        var reading = document.getElementById('current-reading');
        var currentVal = document.getElementById("currentValueAsText");
        var currentAngle = 0;
        var fill;

        var direction = 1;
        setInterval(function () {
            currentAngle += direction;
            if (currentAngle >= 120 || currentAngle <= -120) {
                direction *= -1;
            } else if (currentAngle === 0) {
                fill = direction === 1 ? "#BE1E2D" : "#10A2DC";
                colorTemp.setAttribute("fill", fill);
            }
            // adjust the opacity
            colorTemp.setAttribute("opacity", Math.abs(currentAngle) / 120.0);
            reading.setAttribute("transform", "rotate(" + currentAngle + ")");
            currentValueAsText.textContent = currentAngle.toString();

        }, 25);
    }
})();

Use the textContent property of the SVG text node to set the text.

Done. Smile

Filed under: Coding     Tags: Html, HTML5, JavaScript, SVG
No Comment Yet   

Spinning SVG Animation

Posted by Aaron on Monday, April 16th 2012    Tweet

Interested in learning a few capabilities of SVG animation this evening from JavaScript in a web page, I put together a simple demonstration.

Click on the image to launch the demo.

image

Animating SVG in a modern browser (including IE9) is generally easy enough. This example was slightly more interesting in that I wanted the thicker line to rotate based on the center point of the image, rather than the location of the line itself.

Not what I wanted:

image

Desired rotation:

image

The white bar would rotate around the center point (marked by the red arrow above).

I’ve included all of the code at the bottom of the post. (There’s quite a lot of path information).

The JavaScript just used an interval to move the line around the point:

(function () {
    window.onload = loaded;
    function loaded() {
        var colorTemp = document.getElementById("color-temp");
        var reading = document.getElementById('current-reading');
        var currentAngle = 0;
        var fill;

        var direction = 1;
        setInterval(function () {
            currentAngle += direction;
            if (currentAngle >= 120 || currentAngle <= -120) {
                direction *= -1;
            } else if (currentAngle === 0) {
                fill = direction === 1 ? "#BE1E2D" : "#10A2DC";
                colorTemp.setAttribute("fill", fill);
            }
            // adjust the opacity
            colorTemp.setAttribute("opacity", Math.abs(currentAngle) / 120.0);

            reading.setAttribute("transform", "rotate(" + currentAngle + ")");

        }, 25);
    }
})();

The angle is fixed between 120 and –120 degrees. When the angle reaches zero, the fill color is toggled.

As the angle adjusts, the line is updated as well as the opacity of the fill.

The overall size of the SVG drawing is 600×600. Knowing that (and wanting the exact center), I translated a group to an offset of 300x, 300y containing the line:

<g id="temp-transform" transform="translate(300,300)">
        <line id="current-reading" fill="none" stroke="#FFFFFF"
              stroke-width="5" stroke-linecap="round"
              stroke-miterlimit="10" x1="0" y1="-180" x2="0" y2="-120"/>
</g>

This effectively made the rotation now work from the center, once the line coordinates were adjusted to reflect the new translation.

This works because the contents of the outer group caused the new starting point (origin) to be 300x, 300y rather than the default 0x, 0y. You can see the line is from y –120 to y –180. That’s because I wanted the line to start in the top middle (as the x is set to 0 for the line).

I used Adobe Illustrator CS 5.5 to create the SVG image. Illustrator typically does not always handle fonts well when exporting as SVG. The final text node was this:

<text transform="matrix(1 0 0 1 254.1387 83.3198)" fill="#D1D3D4" font-family="'Arial'"      font-weight="bold" font-size="29.4616">thermo</text>

To make it work across browsers, I needed to modify the text node below slightly. Note the font name and missing bold attribute. It’s not a hard switch, but it’s annoying if you need to make changes to your SVG multiple times.

<text transform="matrix(1 0 0 1 254.1387 83.3198)" fill="#D1D3D4" font-family="'Arial-BoldMT'" font-size="29.4616">thermo</text>

If you have any questions, please leave a comment!

<!DOCTYPE HTML>
<html>
<head>
    <title>Svg Spinner Demo</title>
    <style>
        #demo1 svg {
            width: 300px;
            height: 300px;
        }

    </style>
</head>
<body>

<div id="demo1">
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
     width="600px" height="600px" viewBox="0 0 600 600" enable-background="new 0 0 600 600" xml:space="preserve">
<g>
    <radialGradient id="SVGID_1_" cx="298.9106" cy="196.146" r="399.267" gradientUnits="userSpaceOnUse">
        <stop  offset="0" style="stop-color:#D9D9D9"/>
        <stop  offset="1" style="stop-color:#C2C2C2"/>
    </radialGradient>
    <path fill="url(#SVGID_1_)" d="M300.646,595.41c-78.957,0-153.188-30.747-209.02-86.579C35.795,453,5.048,378.77,5.048,299.812
        c0-78.957,30.748-153.188,86.579-209.02S221.689,4.214,300.646,4.214c78.958,0,153.188,30.748,209.019,86.579
        c55.832,55.831,86.579,130.063,86.579,209.02c0,78.958-30.747,153.188-86.579,209.019
        C453.834,564.663,379.604,595.41,300.646,595.41z"/>
    <path fill="#808285" d="M300.646,6.214c39.637,0,78.086,7.762,114.281,23.071c34.961,14.787,66.359,35.957,93.324,62.922
        s48.135,58.364,62.923,93.325c15.309,36.193,23.07,74.643,23.07,114.28s-7.762,78.086-23.07,114.281
        c-14.788,34.961-35.958,66.359-62.923,93.324s-58.363,48.135-93.324,62.923c-36.194,15.309-74.644,23.07-114.281,23.07
        s-78.087-7.762-114.28-23.07c-34.961-14.788-66.36-35.958-93.325-62.923s-48.135-58.363-62.922-93.324
        C14.81,377.898,7.048,339.449,7.048,299.812s7.762-78.087,23.071-114.28c14.787-34.961,35.957-66.36,62.922-93.325
        s58.364-48.135,93.325-62.922C222.559,13.976,261.009,6.214,300.646,6.214 M300.646,2.214
        C136.287,2.214,3.048,135.453,3.048,299.812S136.287,597.41,300.646,597.41s297.598-133.239,297.598-297.598
        S465.005,2.214,300.646,2.214L300.646,2.214z"/>
</g>
<g>
    <radialGradient id="SVGID_2_" cx="299.0464" cy="204.2632" r="368.0053" gradientUnits="userSpaceOnUse">
        <stop  offset="0" style="stop-color:#141414"/>
        <stop  offset="1" style="stop-color:#080808"/>
    </radialGradient>
    <path fill="url(#SVGID_2_)" d="M300.646,572.266c-72.775,0-141.194-28.34-192.654-79.8c-51.459-51.46-79.8-119.879-79.8-192.654
        s28.34-141.194,79.8-192.654s119.879-79.8,192.654-79.8s141.194,28.34,192.654,79.8c51.46,51.46,79.8,119.879,79.8,192.654
        s-28.34,141.194-79.8,192.654S373.421,572.266,300.646,572.266z"/>
    <path d="M300.646,29.358c36.512,0,71.931,7.15,105.271,21.252c32.205,13.622,61.129,33.123,85.968,57.962
        c24.84,24.839,44.341,53.763,57.963,85.968c14.102,33.34,21.252,68.759,21.252,105.271c0,36.512-7.15,71.931-21.252,105.271
        c-13.622,32.205-33.123,61.129-57.963,85.968c-24.839,24.84-53.763,44.341-85.968,57.963
        c-33.34,14.102-68.759,21.252-105.271,21.252c-36.513,0-71.931-7.15-105.271-21.252c-32.205-13.622-61.129-33.123-85.968-57.963
        c-24.839-24.839-44.34-53.763-57.962-85.968c-14.102-33.34-21.252-68.759-21.252-105.271c0-36.513,7.15-71.931,21.252-105.271
        c13.622-32.205,33.123-61.129,57.962-85.968s53.763-44.34,85.968-57.962C228.715,36.509,264.133,29.358,300.646,29.358
         M300.646,25.358c-151.577,0-274.454,122.877-274.454,274.454c0,151.576,122.877,274.454,274.454,274.454
        c151.576,0,274.454-122.878,274.454-274.454C575.1,148.235,452.222,25.358,300.646,25.358L300.646,25.358z"/>
</g>
<g>
    <radialGradient id="SVGID_3_" cx="299.5176" cy="232.4409" r="259.4771" gradientUnits="userSpaceOnUse">
        <stop  offset="0" style="stop-color:#212121"/>
        <stop  offset="1" style="stop-color:#0D0D0D"/>
    </radialGradient>
    <path fill="url(#SVGID_3_)" d="M300.646,491.916c-105.927,0-192.104-86.178-192.104-192.104
        c0-105.927,86.178-192.104,192.104-192.104c105.926,0,192.104,86.178,192.104,192.104
        C492.75,405.738,406.572,491.916,300.646,491.916z"/>
    <path d="M300.646,109.708c25.666,0,50.561,5.026,73.996,14.938c22.638,9.575,42.968,23.283,60.429,40.743
        c17.46,17.46,31.167,37.791,40.742,60.428c9.912,23.435,14.938,48.331,14.938,73.996s-5.025,50.561-14.938,73.996
        c-9.575,22.638-23.282,42.968-40.742,60.429c-17.461,17.46-37.791,31.167-60.429,40.742c-23.435,9.912-48.33,14.938-73.996,14.938
        s-50.562-5.025-73.996-14.938c-22.637-9.575-42.968-23.282-60.428-40.742c-17.46-17.461-31.168-37.791-40.743-60.429
        c-9.912-23.435-14.938-48.33-14.938-73.996s5.026-50.562,14.938-73.996c9.575-22.637,23.283-42.968,40.743-60.428
        s37.791-31.168,60.428-40.743C250.084,114.733,274.98,109.708,300.646,109.708 M300.646,105.708
        c-107.201,0-194.104,86.903-194.104,194.104c0,107.201,86.903,194.104,194.104,194.104c107.201,0,194.104-86.903,194.104-194.104
        C494.75,192.611,407.847,105.708,300.646,105.708L300.646,105.708z"/>
</g>
<g opacity="0.8">
    <path id="color-temp" fill="#BE1E2D" opacity="0" d="M300.646,489.309c-104.489,0-189.497-85.008-189.497-189.497c0-104.489,85.008-189.497,189.497-189.497
        c104.489,0,189.497,85.008,189.497,189.497C490.143,404.301,405.135,489.309,300.646,489.309z"/>
    <path d="M300.646,110.815c25.515,0,50.266,4.997,73.566,14.852c22.505,9.519,42.718,23.146,60.075,40.504
        s30.984,37.57,40.504,60.075c9.854,23.3,14.852,48.051,14.852,73.566s-4.997,50.266-14.852,73.566
        c-9.52,22.505-23.146,42.718-40.504,60.075s-37.57,30.984-60.075,40.504c-23.3,9.854-48.051,14.852-73.566,14.852
        s-50.266-4.997-73.566-14.852c-22.505-9.52-42.718-23.146-60.075-40.504s-30.985-37.57-40.504-60.075
        c-9.855-23.3-14.852-48.051-14.852-73.566s4.997-50.266,14.852-73.566c9.519-22.505,23.146-42.718,40.504-60.075
        s37.57-30.985,60.075-40.504C250.38,115.812,275.131,110.815,300.646,110.815 M300.646,109.815
        c-104.933,0-189.997,85.064-189.997,189.997c0,104.932,85.064,189.997,189.997,189.997c104.932,0,189.997-85.064,189.997-189.997
        C490.643,194.879,405.578,109.815,300.646,109.815L300.646,109.815z"/>
</g>
<g id="temperature-markings">
        <line fill="none" stroke="#C7C8CA" stroke-width="5" stroke-miterlimit="10"
              x1="300.646" y1="123.751" x2="300.646" y2="161.603"/>
        <line fill="none" stroke="#C7C8CA" stroke-width="5" stroke-miterlimit="10"
              x1="422.102" y1="371.971" x2="454.881" y2="390.896"/>
        <line fill="none" stroke="#C7C8CA" stroke-width="5" stroke-miterlimit="10"
              x1="146.41" y1="390.896" x2="179.191" y2="371.97"/>
</g>
<g id="temp-transform" transform="translate(300,300)">
        <line id="current-reading" fill="none" stroke="#FFFFFF"
              stroke-width="5" stroke-linecap="round"
              stroke-miterlimit="10" x1="0" y1="-180" x2="0" y2="-120"/>
</g>
    <text transform="matrix(1 0 0 1 254.1387 83.3198)" fill="#D1D3D4" font-family="'Arial'"
          font-weight="bold" font-size="29.4616">thermo</text>
</svg>

</div>

<script type="text/javascript">

    (function () {

        window.onload = loaded;

        function loaded() {
            var colorTemp = document.getElementById("color-temp");
            var reading = document.getElementById('current-reading');
            var currentAngle = 0;
            var fill;

            var direction = 1;
            setInterval(function () {
                currentAngle += direction;
                if (currentAngle >= 120 || currentAngle <= -120) {
                    direction *= -1;
                } else if (currentAngle === 0) {
                    fill = direction === 1 ? "#BE1E2D" : "#10A2DC";
                    colorTemp.setAttribute("fill", fill);
                }
                // adjust the opacity
                colorTemp.setAttribute("opacity", Math.abs(currentAngle) / 120.0);

                reading.setAttribute("transform", "rotate(" + currentAngle + ")");

            }, 25);
        }
    })();

</script>
</body>
</html>
Filed under: Coding     Tags: Html, JavaScript, SVG, Thermostat
1 Comment   
« Older Entries
Google
Custom Search
Follow @wiredprairie

Archives

  • May 2012 (1)
  • April 2012 (9)
  • March 2012 (6)
  • February 2012 (4)
  • January 2012 (14)
  • December 2011 (5)
  • November 2011 (1)
  • August 2011 (1)
  • July 2011 (1)
  • June 2011 (1)
  • May 2011 (1)
  • March 2011 (1)

Pages

  • About
  • Contact Me
  • Cooking
    • GE Advantium Oven
  • Nest Thermostat
  • Old Archives
  • Photography
  • Quick Searches
  • You need this
    • Software Development Bookshelf

Links

  • Old WiredPrairie Archives - Here lies the old WiredPraire content …
  • Quick Searches - A few filtered searches on Google to cut down the signal to noise ratio …
  • SnugUp - Best SmugMug Uploader for Windows

Subscribe

  •  Subscribe in a reader

     Subscribe to comments

    add

Browse Our Tag Archives

.NET AIR Ajax Ajax; JavaScript Android API ASP.NET binding bug CSharp Ember.JS Experience Expression Blend Flash Flex hash Html IE8 IE9 Interviews Issue Java JavaScript JSON knockoutjs MVC Nest Phone Problem Razor Review Safari Silverlight SmugMug SnugUp SproutCore SVG TECHED templates Thermostat Typography Silverlight Flash View Source WindowsPhone7 WP7 WPF

©2007-2012 WiredPrairie

Disclaimer: All data and information provided on this site is for informational purposes only.

In association with Amazon.

WordPress Themes by Irish Band & Steel Band
(And, quite a few tweaks by WiredPrairie)