Created
January 14, 2012 13:12
-
-
Save sgss/1611380 to your computer and use it in GitHub Desktop.
Length representation class
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Length | |
self = @ | |
@_pattern : /^\s*([+\-]?\s*[\d.]+(?:e[+\-]\d+)?)\s*([^\s]+)?\s*$/ | |
@_units: | |
pixel : 'pixel' | |
millimeter : 'millimeter' | |
centimeter : 'centimeter' | |
inch : 'inch' | |
point : 'point' | |
pica : 'pica' | |
@_notations: | |
'px' : 'pixel' | |
'mm' : 'millimeter' | |
'cm' : 'centimeter' | |
'in' : 'inch' | |
'pt' : 'point' | |
'pc' : 'pica' | |
@_conversions: | |
pixel: | |
pixel : 1 | |
millimeter : 25.4 / 96 | |
centimeter : 2.54 / 96 | |
inch : 1 / 96 | |
point : 72 / 96 | |
pica : 6 / 96 | |
millimeter: | |
pixel : 96 / 25.4 | |
millimeter : 1 | |
centimeter : 0.1 | |
inch : 1 / 25.4 | |
point : 72 / 25.4 | |
pica : 6 / 25.4 | |
centimeter: | |
pixel : 96 / 2.54 | |
millimeter : 10 | |
centimeter : 1 | |
inch : 1 / 2.54 | |
point : 72 / 2.54 | |
pica : 6 / 2.54 | |
inch: | |
pixel : 96 | |
millimeter : 25.4 | |
centimeter : 2.54 | |
inch : 1 | |
point : 72 | |
pica : 6 | |
point: | |
pixel : 96 / 72 | |
millimeter : 25.4 / 72 | |
centimeter : 2.54 / 72 | |
inch : 1 / 72 | |
point : 1 | |
pica : 1 / 12 | |
pica: | |
pixel : 96 / 6 | |
millimeter : 25.4 / 6 | |
centimeter : 2.54 / 6 | |
inch : 1 / 6 | |
point : 12 | |
pica : 1 | |
@_relativeUnits: | |
multiple : 'multiple' | |
em : 'em' | |
percent : 'percent' | |
permille : 'permille' | |
@_relativeNotations: | |
'x' : 'multiple' | |
'em' : 'em' | |
'%' : 'percent' | |
'‰' : 'permille' | |
@_relativeCoefficients: | |
multiple : 1 | |
em : 1 | |
percent : 0.01 | |
permille : 0.001 | |
# function : Pixel <value> | |
# returns : Length | |
# | |
@Pixel: (value) -> new self value, self._units.pixel | |
@Pixel.toString = -> self._units.pixel | |
# function : Millimeter <value> | |
# returns : Length | |
# | |
@Millimeter: (value) -> new self value, self._units.millimeter | |
@Millimeter.toString = -> self._units.millimeter | |
# function : Centimeter <value> | |
# returns : Length | |
# | |
@Centimeter: (value) -> new self value, self._units.centimeter | |
@Centimeter.toString = -> self._units.centimeter | |
# function : Inch <value> | |
# returns : Length | |
# | |
@Inch: (value) -> new self value, self._units.inch | |
@Inch.toString = -> self._units.inch | |
# function : Point <value> | |
# returns : Length | |
# | |
@Point: (value) -> new self value, self._units.point | |
@Point.toString = -> self._units.point | |
# function : Pica <value> | |
# returns : Length | |
# | |
@Pica: (value) -> new self value, self._units.pica | |
@Pica.toString = -> self._units.pica | |
# function : create [value], [unit], [primitive] | |
# returns : Length | |
# | |
@create: (value, unit, primitive) -> new self value, unit, primitive | |
# function : extract <notation> | |
# returns : Object | |
# | |
@extract: (notation) -> | |
if self._pattern.test notation | |
{ value: Number(RegExp.$1), unit: RegExp.$2 } | |
else | |
{ value: 0, unit: null } | |
# function : profileUnit unit | |
# returns : Object | |
# | |
@profileUnit: (unit) -> | |
unit = unit?.toString().toLowerCase() | |
if self._notations[unit]? | |
{ unit: self._notations[unit], relative: no, absolute: yes } | |
else if self._units[unit]? | |
{ unit: unit, relative: no, absolute: yes } | |
else if self._relativeNotations[unit]? | |
{ unit: self._relativeNotations[unit], relative: yes, absolute: no } | |
else if self._relativeUnits[unit]? | |
{ unit: unit, relative: yes, absolute: no } | |
else | |
{ unit: null, relative: no, absolute: no } | |
# function : relativate <value>, <length>, [unit] | |
# returns : mixed | |
# | |
@convertValueRelativeTo: (value, length, targetUnit) -> | |
length = new Length length | |
{ unit: targetUnit, relative: targetRelative, absolute: targetAbsolute } = self.profileUnit targetUnit | |
if value instanceof self | |
# absolute to relative | |
if targetRelative | |
value.valueOf(length.getUnit()) / length.valueOf() / self._relativeCoefficients[targetUnit] | |
# absolute to absolute | |
else if targetAbsolute | |
value[targetUnit]() | |
# default absolute | |
else | |
value | |
else | |
{ value, unit } = Length.extract value | |
{ unit, relative, absolute } = self.profileUnit unit | |
if relative | |
# relative to relative | |
if targetRelative | |
value * self._relativeCoefficients[unit] / self._relativeCoefficients[targetUnit] | |
# relative to absolute | |
else if targetAbsolute | |
new Length length.valueOf(targetUnit) * value * self._relativeCoefficients[unit], targetUnit | |
# default relative | |
else | |
new Length length.valueOf() * value * self._relativeCoefficients[unit], length.getUnit() | |
else if absolute | |
# absolute to relative | |
if targetRelative | |
new Length(value, unit).valueOf(length.getUnit()) / length.valueOf() / self._relativeCoefficients[targetUnit] | |
# absolute to absolute | |
else if targetAbsolute | |
new Length value, targetUnit, unit | |
# default absolute | |
else | |
new Length value, unit | |
#--------------------------------------------------------------------------- | |
# | |
# Initialization | |
# | |
#--------------------------------------------------------------------------- | |
# function : Length [value], [unit], [primitive] | |
# | |
constructor: (value, unit, primitive) -> | |
# Length <length>, [unit], primitive | |
if value instanceof self | |
if isString unit | |
unit = unit.toLowerCase() | |
if self._notations[unit]? | |
unit = self._notations[unit] | |
else unless self._units[unit]? | |
unit = value._unit | |
if isString primitive | |
primitive = primitive.toLowerCase() | |
if self._notations[primitive]? | |
primitive = self._notations[primitive] | |
else unless self._units[primitive] | |
primitive = value._primitive | |
@_value = value.valueOf primitive | |
@_unit = unit | |
@_primitive = primitive | |
else | |
if isString unit | |
unit = unit.toLowerCase() | |
if self._notations[unit]? | |
unit = self._notations[unit] | |
else unless self._units[unit]? | |
unit = self._units.pixel | |
if isString primitive | |
primitive = primitive.toLowerCase() | |
if self._notations[primitive]? | |
primitive = self._notations[primitive] | |
else unless self._units[primitive]? | |
primitive = unit | |
# Length [value], [unit = 'pixel'], [primitive] | |
if isNumber value | |
@_value = value | |
@_unit = unit | |
@_primitive = primitive | |
# Length <notation> | |
else if self._pattern.test value | |
found = RegExp.$2.toLowerCase() | |
if self._notations[found] | |
unit = self._notations[found] | |
else if self._units[found] | |
unit = found | |
@_value = Number(RegExp.$1) | |
@_unit = unit | |
@_primitive = unit | |
# Length | |
else | |
@_value = 0 | |
@_unit = unit | |
@_primitive = primitive | |
#--------------------------------------------------------------------------- | |
# | |
# Utility | |
# | |
#--------------------------------------------------------------------------- | |
# method : valueOf [unit] | |
# returns : Number | |
# | |
valueOf: (unit) -> | |
if self._notations[unit]? | |
unit = self._notations[unit] | |
if not unit? | |
unit = @_unit | |
@_value * self._conversions[@_primitive][unit] | |
# method : toString | |
# returns : String | |
# | |
toString: -> @_value + ' ' + @_unit | |
# method : equals <other> | |
# returns : Boolean | |
# | |
equals: (other) -> | |
if other? and other.valueOf? | |
@valueOf(Length.Pixel) is other.valueOf(Length.Pixel) | |
else | |
@valueOf(@_primitive) is other | |
# method : clone | |
# returns : Length | |
# | |
clone: -> new self @_value, @_unit, @_primitive | |
#--------------------------------------------------------------------------- | |
# | |
# Accessing Property | |
# | |
#--------------------------------------------------------------------------- | |
# method : getValue | |
# returns : Number | |
# | |
getValue: -> @_value | |
# method : getUnit | |
# returns : String | |
# | |
getUnit: -> @_unit | |
# method : getPrimitive | |
# returns : String | |
# | |
getPrimitive: -> @_primitive | |
#--------------------------------------------------------------------------- | |
# | |
# Converting Unit | |
# | |
#--------------------------------------------------------------------------- | |
# method : pixel | |
# returns : Length | |
# | |
pixel: -> | |
if @_unit isnt self._units.pixel | |
new self @_value, self._units.pixel, @_primitive | |
else | |
@ | |
# method : millimeter | |
# returns : Length | |
# | |
millimeter: -> | |
if @_unit isnt self._units.millimeter | |
new self @_value, self._units.millimeter, @_primitive | |
else | |
@ | |
# method : centimeter | |
# returns : Length | |
# | |
centimeter: -> | |
if @_unit isnt self._units.centimeter | |
new self @_value, self._units.centimeter, @_primitive | |
else | |
@ | |
# method : inch | |
# returns : Length | |
# | |
inch: -> | |
if @_unit isnt self._units.inch | |
new self @_value, self._units.inch, @_primitive | |
else | |
@ | |
# method : point | |
# returns : Length | |
# | |
point: -> | |
if @_unit isnt self._units.point | |
new self @_value, self._units.point, @_primitive | |
else | |
@ | |
# method : pica | |
# returns : Length | |
# | |
pica: -> | |
if @_unit isnt self._units.pica | |
new self @_value, self._units.pica, @_primitive | |
else | |
@ | |
#--------------------------------------------------------------------------- | |
# | |
# Manipulating Numeric Value | |
# | |
#--------------------------------------------------------------------------- | |
# method : abs | |
# returns : Length | |
# | |
abs: -> new self @valueOf().abs(), @_primitive | |
# method : ceil [precision] | |
# returns : Length | |
# | |
ceil: (precision) -> new self @valueOf().ceil(precision), @_primitive | |
# method : floor [precision] | |
# returns : Length | |
# | |
floor: (precision) -> new self @valueOf().floor(precision), @_primitive | |
# method : round [precision] | |
# returns : Length | |
# | |
round: (precision) -> new self @valueOf().round(precision), @_primitive | |
# method : pow [p] | |
# returns : Length | |
# | |
pow: (p) -> new self @valueOf().pow(p), @_primitive | |
#------------------------------------------------------------------------------- | |
# | |
# Converting Length to Number | |
# | |
#------------------------------------------------------------------------------- | |
merge Number, | |
# function : Pixel <value> | |
# returns : Length | |
# | |
Pixel: (value) -> | |
if value instanceof Length | |
value.valueOf Length._units.pixel | |
else | |
new Length(value).valueOf Length._units.pixel | |
# function : Millimeter <value> | |
# returns : Length | |
# | |
Millimeter: (value) -> | |
if value instanceof Length | |
value.valueOf Length._units.millimeter | |
else | |
new Length(value).valueOf Length._units.millimeter | |
# function : Centimeter <value> | |
# returns : Length | |
# | |
Centimeter: (value) -> | |
if value instanceof Length | |
value.valueOf Length._units.centimeter | |
else | |
new Length(value).valueOf Length._units.centimeter | |
# function : Inch <value> | |
# returns : Length | |
# | |
Inch: (value) -> | |
if value instanceof Length | |
value.valueOf Length._units.inch | |
else | |
new Length(value).valueOf Length._units.inch | |
# function : Point <value> | |
# returns : Length | |
# | |
Point: (value) -> | |
if value instanceof Length | |
value.valueOf Length._units.point | |
else | |
new Length(value).valueOf Length._units.point | |
# function : Pica <value> | |
# returns : Length | |
# | |
Pica: (value) -> | |
if value instanceof Length | |
value.valueOf Length._units.millimeter | |
else | |
new Length(value).valueOf Length._units.pica | |
#------------------------------------------------------------------------------- | |
# | |
# Converting Number to Length | |
# | |
#------------------------------------------------------------------------------- | |
merge Number::, | |
# method : pixel | |
# returns : Length | |
# | |
pixel: -> new Length @, Length._units.pixel | |
# method : millimeter | |
# returns : Length | |
# | |
millimeter: -> new Length @, Length._units.millimeter | |
# method : centimeter | |
# returns : Length | |
# | |
centimeter: -> new Length @, Length._units.centimeter | |
# method : inch | |
# returns : Length | |
# | |
inch: -> new Length @, Length._units.inch | |
# method : point | |
# returns : Length | |
# | |
point: -> new Length @, Length._units.point | |
# method : pica | |
# returns : Length | |
# | |
pica: -> new Length @, Length._units.pica | |
#------------------------------------------------------------------------------- | |
# | |
# Converting String to Length | |
# | |
#------------------------------------------------------------------------------- | |
merge String::, | |
# method : toLength | |
# returns : Length | |
# | |
toLength: -> new Length @ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment