The code below is loading an svg into the canvas via RaphaelJS. There are mouseover/mouseout events, on click on an element of the svg, and drag/zoom.I would like to know, what are some good practices, or how to improve the productivity and maybe shorten my code. One issues may be that I use a lot of iterations through the elements(~2000-3000) on the svg image. This is not the only problem in my code, so if anyone has any ideas, I am ready to try them. Raphael.fn.select = (selector) ->  type     = selector.charAt(0)  selector = selector.substr(1)  attr     = if type == '.' then 'class' else 'id'  els      = []  bot      = this.bottom  while bot    if bot.node.getAttribute(attr) == selector      els.push(bot)    bot = bot.next  return if type == '.' then els else els[0] or null;((window) ->  'use strict'  loadSVG = (file) ->    response = null    $.ajax({      type: 'GET',      url: file,      dataType: 'xml',      async: false,      success: (svgXML) ->        response = svgXML    })    return response  selectedPoints = []  disabledPoints = ['seggiolino_1637', 'seggiolino_1881', 'seggiolino_1984', 'seggiolino_889', 'seggiolino_891', 'seggiolino_893', 'seggiolino_890', 'seggiolino_892', 'seggiolino_894']  settings =    clickAnimTime: 0    hoverScale: 2    animTime: 300    animEase: 'backOut'    scale: 3    vb:      x: 0      y: 0      width: 1606      height: 1039    paper:      width: 800      height: 480  states =    default:      transform: ''      fill: '#008000'      'stroke-width': 0    hover:      transform: 's' + settings.hoverScale    disabled:      fill: '#eaeaea'      'stroke-width': 1      stroke: '#333333'    selected:      transform: 's' + settings.hoverScale      fill: '#AA8834'      'stroke-width': 2      stroke: '#AA8834'  container = document.getElementById('mapContainer')  paper     = new Raphael(container, settings.vb.width, settings.vb.height)  map       = paper.importSVG(loadSVG('img/svgscala.svg'))  draggable = container.getElementsByTagName('svg')[0]  paper.setSize(settings.paper.width, settings.paper.height)  viewBoxWidth  = settings.vb.width  viewBoxHeight = settings.vb.height  dx = 0  dy = 0  oX = 0  oY = 0  oWidth  = viewBoxWidth  oHeight = viewBoxHeight  mousedown = false  startX = 0  startY = 0  viewBox = paper.setViewBox(oX, oY, viewBoxWidth, viewBoxHeight, true)  viewBox.x = oX  viewBox.y = oY  zoomLevel = 0  firedCallback = false  paper.select('#' + point).attr(states.disabled) for point in disabledPoints  map.hover(() ->    if disabledPoints.indexOf(this.node.getAttribute('id')) == -1      this[0].style.cursor = 'pointer'      this.animate(states.hover, settings.clickAnimTime, settings.animEase)    else      this[0].style.cursor = 'not-allowed'  , () ->    if disabledPoints.indexOf(this.node.getAttribute('id')) == -1      if selectedPoints.indexOf(this.node.getAttribute('id')) == -1        this.animate(states.default, settings.clickAnimTime, settings.animEase)  )  map.click(() ->    cx = this.attr('cx')    cy = this.attr('cy')    if disabledPoints.indexOf(this.node.getAttribute('id')) == -1      if selectedPoints.indexOf(this.node.getAttribute('id')) == -1        selectedPoints.push(this.node.getAttribute('id'))        this.animate(states.selected, settings.clickAnimTime, settings.animEase)      else        removeId = selectedPoints.indexOf(this.node.getAttribute('id'))        selectedPoints.splice(removeId, 1)        this.animate(states.default, settings.clickAnimTime, settings.animEase)  )  wheel = (e) ->    e = e or window.event    delta = 0    if e.wheelDelta      delta = e.wheelDelta / 120    else if e.detail      delta = -e.detail / 3    if delta then handle(e, delta)    handleAreas()    if e.preventDefault then e.preventDefault()    return e.returnValue = false  handle = (e, delta) ->    vBOw = viewBoxWidth    vBOh = viewBoxHeight    factor = 0    if delta > 0      zoomLevel++      viewBoxWidth  *= 0.95      viewBoxHeight *= 0.95      factor = 0.95    else      zoomLevel--      viewBoxWidth  *= 1.05      viewBoxHeight *= 1.05      factor = 1.05    viewBox.x -= (e.pageX - (viewBoxWidth - vBOw)) * (factor - 1)    viewBox.y -= (e.pageY - (viewBoxHeight - vBOh)) * (factor - 1)    paper.setViewBox(viewBox.x, viewBox.y, viewBoxWidth, viewBoxHeight)  draggable.onmousedown = (e) ->    if paper.getElementByPoint(e.pageX, e.pageY) != null      return    e = e or window.event    mousedown = true    startX = e.pageX    startY = e.pageY  document.onmousemove = (e) ->    if mousedown == false then return    document.body.style.cursor = '-webkit-grabbing'    e  = e or window.event    dx = startX - e.pageX    dy = startY - e.pageY    x  = viewBoxWidth / paper.width    y  = viewBoxHeight / paper.height    dx *= x    dy *= y    paper.setViewBox(viewBox.x + dx, viewBox.y + dy, viewBoxWidth, viewBoxHeight)  document.onmouseup = (e) ->    document.body.style.cursor = 'initial'    if mousedown == false then return    e = e or window.event    viewBox.x += dx    viewBox.y += dy    mousedown  = false  handleAreas = () ->    if zoomLevel > 30      if not firedCallback        firedCallback = true        a.attr('fill', '') for a in paper.select('.area')        console.log 'zoomed in'    else      if firedCallback        firedCallback = false        a.attr('fill', 'red') for a in paper.select('.area')  draggable.addEventListener('DOMMouseScroll', wheel, false)  draggable.onmousewheel = draggable.onmousewheel = wheel)(window)Maybe some of you know a shorthand expression in CoffeeScript, or maybe you can suggest a nice trick in JS. The code works fine, but I won't say I'm happy with it. I will post the code in compiled JavaScript if someone needs it.
Loading an SVG into the canvas
javascript;coffeescript;svg;raphael.js