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.