Scale Converter

by Andrew Maxwell

HTML

<body ng-app="myApp" ng-controller="ctrl">
    <p>If 
        <select ng-model="from" ng-options="item.name for item in items"></select> 
        were the size of 
        <select ng-model="to" ng-options="item.name for item in items"></select>
    </p>
    
    <ul>
        <li ng-repeat="item in items">
            {{ item.name | capitalize }} 
            would be 
            <span ng-class="{bold: item.size * to.size / from.size > 1e-3}">{{ item.size * to.size / from.size | distance }}</span>
            wide
        </li>
    </ul>
    
    <button ng-show="!edit" ng-click="edit = true">Edit Sizes</button>
    <div ng-show="edit" style="margin-top: 15px">
        <div ng-repeat="item in items">
            <input ng-model="item.name"/>
            <input ng-model="item.size" title="in meters"/>
            <button ng-click="items.splice(items.indexOf(item), 1)">Delete</button>
        </div>
        <button ng-click="items.push({name: 'New Item', size: 1})">Add an Item</button>
        <button ng-click="edit = false">Done</button>
    </div>
</body>

CSS

* {font-family: sans-serif}
.bold {font-weight: bold}

JavaScript

var myApp = angular.module("myApp", [])

myApp.filter("capitalize", function(){
    return function(string){
        return string.charAt(0).toUpperCase() + string.slice(1);
    }
})

myApp.filter("distance", function(){
    var units = [
        {unit: "planck lengths", conversion: 6.1873559e34},
        {unit: "yoctometers", conversion: 1e24},
        {unit: "zeptometers", conversion: 1e21},
        {unit: "attometers", conversion: 1e18},
        {unit: "femtometers", conversion: 1e15},
        {unit: "picometers", conversion: 1e12},
        {unit: "nanometers", conversion: 1e9},
        {unit: "microns", conversion: 1e6},
        {unit: "millimeters", conversion: 1000},
        {unit: "inches", conversion: 39.3701},
        {unit: "feet", conversion: 3.28084},
        {unit: "miles", conversion: 0.000621371},
        //{unit: "lightseconds", conversion: 3.33564095e-9},
        //{unit: "lightminutes", conversion: 5.5594016e-11},
        {unit: "astronomical units", conversion: 6.68458712e-12},
        //{unit: "lighthours", conversion: 9.2656693e-13},
        //{unit: "lightdays", conversion: 3.8606955419822766e-14},
        {unit: "lightyears", conversion: 1.05702341e-16},
        {unit: "hubble lengths", conversion: 1.0570266e-25}
    ]
    return function(meters){
        for (var i = 0; i < units.length; i++){
            var convertedLength = meters * units[i].conversion
            if (i == units.length - 1 || convertedLength < units[i].conversion / units[i + 1].conversion / 2){
                var digits = convertedLength > 10 ? 0 : convertedLength > 1 ? 1: 2
                return convertedLength.toFixed(digits) + " " + units[i].unit
            }
        }
    }
})

myApp.controller("ctrl", function($scope){
    
    $scope.items = [
        {name: "a plank length", size: 1.6162e-35},
        {name: "a proton", size: 1.7e-15},
        {name: "a uranium nucleus", size: 15e-15},
        {name: "a hydrogen atom", size: 1.058e-10},
        {name: "a...