to-pixels.ts 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. /**
  2. * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. */
  6. /*
  7. * This code has been modified from https://github.com/mikolalysenko/to-px,
  8. * copyright (c) 2015 Mikola Lysenko. MIT License
  9. */
  10. import parseUnit from './parse-unit'
  11. const PIXELS_PER_INCH = 96
  12. function getPropertyInPX(element: Element, prop: string) {
  13. const parts = parseUnit(getComputedStyle(element).getPropertyValue(prop))
  14. return parts[0] * toPixels(parts[1], element)
  15. }
  16. // This brutal hack is needed
  17. function getSizeBrutal(unit: string, element: Element) {
  18. const testDIV = document.createElement('div')
  19. testDIV.style.setProperty('font-size', '128' + unit)
  20. element.appendChild(testDIV)
  21. const size = getPropertyInPX(testDIV, 'font-size') / 128
  22. element.removeChild(testDIV)
  23. return size
  24. }
  25. export default function toPixels(str: string, element: Element = document.body): number {
  26. str = (str || 'px').trim().toLowerCase()
  27. switch (str) {
  28. case '%': // Ambiguous, not sure if we should use width or height
  29. return element.clientHeight / 100.0
  30. case 'ch':
  31. case 'ex':
  32. return getSizeBrutal(str, element)
  33. case 'em':
  34. return getPropertyInPX(element, 'font-size')
  35. case 'rem':
  36. return getPropertyInPX(document.body, 'font-size')
  37. case 'vw':
  38. return window.innerWidth/100
  39. case 'vh':
  40. return window.innerHeight/100
  41. case 'vmin':
  42. return Math.min(window.innerWidth, window.innerHeight) / 100
  43. case 'vmax':
  44. return Math.max(window.innerWidth, window.innerHeight) / 100
  45. case 'in':
  46. return PIXELS_PER_INCH
  47. case 'cm':
  48. return PIXELS_PER_INCH / 2.54
  49. case 'mm':
  50. return PIXELS_PER_INCH / 25.4
  51. case 'pt':
  52. return PIXELS_PER_INCH / 72
  53. case 'pc':
  54. return PIXELS_PER_INCH / 6
  55. }
  56. return 1
  57. }