482 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			482 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 | |
| <html>
 | |
| <head>
 | |
| <title>Circle Class</title>
 | |
| <style type='text/css'>
 | |
| * {
 | |
|   margin: 0;
 | |
|   padding: 0;
 | |
|   position: absolute;
 | |
| }
 | |
| </style>
 | |
| <script type='text/javascript'>
 | |
| /*
 | |
|   This program is free software. It comes without any warranty, to
 | |
|   the extent permitted by applicable law. You can redistribute it
 | |
|   and/or modify it under the terms of the Do What The Fuck You Want
 | |
|   To Public License, Version 2, as published by Sam Hocevar. See
 | |
|   http://sam.zoy.org/wtfpl/COPYING for more details.
 | |
| */
 | |
| 
 | |
| /*
 | |
|   This JS class attempts to make an interactive site with the canvas element.
 | |
|   In time this will not only be a cirlce class, but more like an object class.
 | |
|   The fun stuff happens at the end of this file.
 | |
| */
 | |
| 
 | |
| function Circle(posX, posY, radius, fillColor, borderWidth, borderColor, visible) {
 | |
|   // Default to defaults if nothing is specified
 | |
|   if (posX == undefined) var posX = 0
 | |
|   if (posY == undefined) var posY = 0
 | |
|   if (radius == undefined) var radius = 50
 | |
|   if (fillColor == undefined) var fillColor = '#ddd'
 | |
|   if (borderWidth == undefined) var borderWidth = 2
 | |
|   if (borderColor == undefined) var borderColor = '#444'
 | |
|   if (visible == undefined) var visible = true
 | |
|   this.visible = visible
 | |
|   
 | |
|   // Get number in order of creation
 | |
|   this.num = objects.length
 | |
|   
 | |
|   // Create canvas element
 | |
|   this.element = document.createElement('canvas')
 | |
|   if (!this.visible) this.hide()
 | |
|   this.element.style.zIndex = this.num + 2
 | |
|   wrapper.appendChild(this.element)
 | |
|   this.context = this.element.getContext('2d')
 | |
|   
 | |
|   // Append to global objects
 | |
|   objects.splice(objects.length, objects.length, this)
 | |
|   
 | |
|   this.state = 'normal'
 | |
|   this.globalstate = 'normal'
 | |
|   this.savedstate = 'hover'
 | |
| 
 | |
|   this.x = posX
 | |
|   this.y = posY
 | |
|   this.radius = radius
 | |
|   this.fillColor = fillColor
 | |
|   this.borderWidth = borderWidth
 | |
|   this.borderColor = borderColor
 | |
|   
 | |
|   var i
 | |
|   
 | |
|   for (i in style_states) {
 | |
|     this[style_states[i]] = {}
 | |
|     this[style_states[i]].x = false
 | |
|     this[style_states[i]].y = false
 | |
|     this[style_states[i]].radius = false
 | |
|     this[style_states[i]].fillColor = false
 | |
|     this[style_states[i]].borderWidth = false
 | |
|     this[style_states[i]].borderColor = false
 | |
|   }
 | |
|   
 | |
|   for (i in event_states) {
 | |
|     this[event_states[i]] = '' //'dbg.innerHTML+=" '+event_states[i]+'"'
 | |
|   }
 | |
|   
 | |
|   // Keep track of mousedown events
 | |
|   this.mousedown_done = false
 | |
|     
 | |
|   // Keep track of hovering
 | |
|   this.hovering = false
 | |
|     
 | |
|   this.create()
 | |
| }
 | |
| 
 | |
| Circle.prototype.create = function() {
 | |
|   var posX, posY, radius, fillColor, borderWidth, borderColor, i
 | |
|   
 | |
|   posX = this.get('x')
 | |
|   posY = this.get('y')
 | |
|   radius = this.get('radius')
 | |
|   fillColor = this.get('fillColor')
 | |
|   borderWidth = this.get('borderWidth')
 | |
|   borderColor = this.get('borderColor')
 | |
|   
 | |
|   var mn = radius * 2 + borderWidth
 | |
|   var mnh = mn / 2
 | |
|   
 | |
|   this.element.width = mn
 | |
|   this.element.height = mn
 | |
|   this.element.style.width = mn + 'px'
 | |
|   this.element.style.height = mn + 'px'
 | |
|   this.element.style.left = posX - mnh + 'px'
 | |
|   this.element.style.top = posY - mnh + 'px'
 | |
|   
 | |
|   // Create the circle
 | |
|   this.context.beginPath()
 | |
|   this.context.arc(mnh, mnh, radius, 0, Math.PI*2, true)
 | |
|   
 | |
|   if (typeof(fillColor) == 'string')
 | |
|     this.context.fillStyle = fillColor
 | |
|   else {
 | |
|     if (fillColor[0] == 'linear') {
 | |
|       var x1, y1, x2, y2
 | |
|       if (fillColor.length > 2) {
 | |
|         var angle = (fillColor[2] + 45) % 360 // Center it
 | |
|         
 | |
|         if (angle >= 0 && angle < 90) {
 | |
|           x1 = (angle / 90) * mn
 | |
|           y1 = 0
 | |
|           x2 = ((90 - angle) / 90) * mn
 | |
|           y2 = mn
 | |
|         }
 | |
|         else if (angle >= 90 && angle < 180) {
 | |
|           x1 = mn
 | |
|           y1 = ((angle - 90) / 90) * mn
 | |
|           x2 = 0
 | |
|           y2 = ((90 - (angle - 90)) / 90) * mn
 | |
|         }
 | |
|         else if (angle >= 180 && angle < 270) {
 | |
|           x1 = ((90 - (angle - 180)) / 90) * mn
 | |
|           y1 = mn
 | |
|           x2 = ((angle - 180) / 90) * mn
 | |
|           y2 = 0
 | |
|         }
 | |
|         else if (angle >= 270 && angle < 360) {
 | |
|           x1 = 0
 | |
|           y1 = ((90 - (angle - 270)) / 90) * mn
 | |
|           x2 = mn
 | |
|           y2 = ((angle - 270) / 90) * mn
 | |
|         }
 | |
|       }
 | |
|       else {
 | |
|         x1 = mnh
 | |
|         y1 = 0
 | |
|         x2 = mnh
 | |
|         y2 = mn
 | |
|       }
 | |
|       var grad = this.context.createLinearGradient(x1, y1, x2, y2)
 | |
|     }
 | |
|     else {
 | |
|       var lenpos, reallen, angle, x1, y1
 | |
|       if (fillColor.length > 2) {
 | |
|         lenpos = (fillColor[2])
 | |
|         if (fillColor.length > 3) {
 | |
|           angle = (fillColor[3] + 45)
 | |
|           while (angle < 0) {
 | |
|             angle += 360
 | |
|           }
 | |
|           angle = angle % 360
 | |
|         }
 | |
|         else angle = 0
 | |
|       }
 | |
|       else {
 | |
|         lenpos = 0
 | |
|         angle = 0
 | |
|       }
 | |
|       
 | |
|       reallen = lenpos * radius
 | |
|       
 | |
|       if (angle >= 0 && angle < 90) {
 | |
|           x1 = mnh + Math.sin((angle - 45) * Math.PI / 180) * reallen
 | |
|           y1 = mnh - Math.cos((angle - 45) * Math.PI / 180) * reallen
 | |
|         }
 | |
|         else if (angle >= 90 && angle < 180) {
 | |
|           x1 = mnh + Math.cos((angle - 135) * Math.PI / 180) * reallen
 | |
|           y1 = mnh + Math.sin((angle - 135) * Math.PI / 180) * reallen
 | |
|         }
 | |
|         else if (angle >= 180 && angle < 270) {
 | |
|           x1 = mnh - Math.sin((angle - 225) * Math.PI / 180) * reallen
 | |
|           y1 = mnh + Math.cos((angle - 225) * Math.PI / 180) * reallen
 | |
|         }
 | |
|         else if (angle >= 270 && angle < 360) {
 | |
|           x1 = mnh - Math.cos((angle - 315) * Math.PI / 180) * reallen
 | |
|           y1 = mnh - Math.sin((angle - 315) * Math.PI / 180) * reallen
 | |
|         }
 | |
|       
 | |
|       var grad = this.context.createRadialGradient(x1, y1, 0, mnh, mnh, radius)
 | |
|     }
 | |
|     
 | |
|     for (i in fillColor[1]) {
 | |
|       grad.addColorStop(i / (fillColor[1].length - 1), fillColor[1][i])
 | |
|     }
 | |
| 
 | |
|     this.context.fillStyle = grad
 | |
|   }
 | |
|   this.context.lineWidth = borderWidth
 | |
|   this.context.strokeStyle = borderColor
 | |
|   
 | |
|   // Clear the screen
 | |
|   this.context.clearRect(0, 0, mn, mn)
 | |
|   this.context.stroke()
 | |
|   this.context.fill()
 | |
| }
 | |
| 
 | |
| Circle.prototype.standby = function() {
 | |
|   if (!this.visible) return false
 | |
|   
 | |
|   var posX, posY, radius, borderWidth
 | |
|   
 | |
|   posX = this.get('x')
 | |
|   posY = this.get('y')
 | |
|   radius = this.get('radius')
 | |
|   borderWidth = this.get('borderWidth')
 | |
|   
 | |
|   if (!object_hover && Math.sqrt(Math.pow((x - posX), 2) + Math.pow((y - posY), 2)) < radius + borderWidth / 2) {
 | |
|     // If the cursor is inside the circle
 | |
|     
 | |
|     // No more objects may react
 | |
|     object_hover = true
 | |
|     
 | |
|     if (!this.hovering)
 | |
|       this.eval(this.onmouseover)
 | |
|     else if (x != ox || y != oy)
 | |
|       this.eval(this.onmousemove)
 | |
|     
 | |
|     // We're hovering!
 | |
|     this.hovering = true
 | |
|     
 | |
|     if (this.globalstate == 'onmousedown') {
 | |
|       this.state = 'active'
 | |
|       this.savedstate = 'active'
 | |
|       if (!this.onmousedown_done) {
 | |
|         this.onmousedown_done = true
 | |
|         this.eval(this.onmousedown)
 | |
|       }
 | |
|     }
 | |
|     else if (this.globalstate == 'onmouseup') {
 | |
|       this.state = 'hover'
 | |
|       this.savedstate = 'hover'
 | |
|       this.eval(this.onmouseup)
 | |
|       if (this.onmousedown_done)
 | |
|         this.eval(this.onclick)
 | |
|       
 | |
|       this.onmousedown_done = false
 | |
|     }
 | |
|     else {
 | |
|       // Last resort
 | |
|       this.state = this.savedstate
 | |
|     }
 | |
|   }
 | |
|   else {
 | |
|     // If the cursor is outside the circle
 | |
|     
 | |
|     if (this.hovering) {
 | |
|       // No more hovering..
 | |
|       this.hovering = false
 | |
|       this.eval(this.onmouseout)
 | |
|     }
 | |
|     // Reset everything
 | |
|     this.state = 'normal'
 | |
|     
 | |
|     if (this.globalstate == 'onmouseup') {
 | |
|       this.savedstate = 'hover'
 | |
|       this.onmousedown_done = false
 | |
|     }
 | |
|   }
 | |
|   
 | |
|   this.globalstate = 'normal'
 | |
|   
 | |
|   // Create it and draw it to the screen
 | |
|   this.create()
 | |
|   
 | |
|   return true
 | |
| }
 | |
| 
 | |
| Circle.prototype.eval = function(code) {
 | |
|   var codetype = typeof(code)
 | |
|   if (codetype == 'function')
 | |
|     code = (code + '').split('function ')[1].split('{')[0]
 | |
|   try {
 | |
|     eval(code)
 | |
|     return true
 | |
|   }
 | |
|   catch(e) {
 | |
|     return false
 | |
|   }
 | |
| }
 | |
| 
 | |
| Circle.prototype.getobj = function() {
 | |
|   if (this.state == 'normal')
 | |
|     return this
 | |
|   else
 | |
|     return this[this.state]
 | |
| }
 | |
| 
 | |
| Circle.prototype.get = function(circlevar) {
 | |
|   var cobj = this.getobj()
 | |
|   if (cobj[circlevar] === false) {
 | |
|   if (this.state == 'active' && this.hover[circlevar] !== false)
 | |
|     return this.hover[circlevar]
 | |
|   else return this[circlevar]
 | |
|   }
 | |
|   else return cobj[circlevar]
 | |
| }
 | |
| 
 | |
| Circle.prototype.set = function(circle_var, value) {
 | |
|   this[circle_var] = value
 | |
|   for (var i in event_states) {
 | |
|     this[event_states[i]][circle_var] = value
 | |
|   }
 | |
| }
 | |
| 
 | |
| Circle.prototype.hide = function() {
 | |
|   this.element.style.display = 'none'
 | |
|   this.visible = false
 | |
| }
 | |
| 
 | |
| Circle.prototype.show = function() {
 | |
|   this.element.style.display = 'block'
 | |
|   this.visible = true
 | |
| }
 | |
| 
 | |
| 
 | |
| Circle.prototype.raiseIndex = function(amount) {
 | |
|   if (amount == undefined) var amount = 1
 | |
|   return this.changeIndex(amount)
 | |
| }
 | |
| 
 | |
| Circle.prototype.lowerIndex = function(amount) {
 | |
|   if (amount == undefined) var amount = 1
 | |
|   return this.changeIndex(-amount)
 | |
| }
 | |
| 
 | |
| Circle.prototype.toTop = function() {
 | |
|   return this.changeIndex(objects.length - this.num - 1)
 | |
| }
 | |
| 
 | |
| Circle.prototype.toBottom = function() {
 | |
|   return this.changeIndex(-this.num)
 | |
| }
 | |
| 
 | |
| Circle.prototype.changeIndex = function(crement) {
 | |
|   if (objects.length > this.num + crement && 0 <= this.num + crement) {
 | |
|     objects.splice(this.num, 1)
 | |
|     objects.splice(this.num + crement, 0, this)
 | |
|     this.update_indexes()
 | |
|     return true
 | |
|   }
 | |
|   else
 | |
|     return false
 | |
| }
 | |
| 
 | |
| Circle.prototype.remove = function() {
 | |
|   objects.splice(this.num, 1)
 | |
|   this.update_indexes()
 | |
|   wrapper.removeChild(this.element)
 | |
|   delete this
 | |
| }
 | |
| 
 | |
| Circle.prototype.update_indexes = function() {
 | |
|   for (var i in objects) {
 | |
|     objects[i].num = i * 1
 | |
|     objects[i].element.style.zIndex = i * 1 + 2
 | |
|   }
 | |
| }
 | |
| 
 | |
| function standby() {
 | |
|   for (var i = objects.length - 1; i > -1; i--) {
 | |
|     objects[i].standby()
 | |
|   }
 | |
|   object_hover = false
 | |
|   ox = x
 | |
|   oy = y
 | |
|   timer = setTimeout('standby()')
 | |
| }
 | |
| 
 | |
| window.onload = function() {
 | |
|   // Globals
 | |
|   x = 0
 | |
|   y = 0
 | |
|   ox = 0
 | |
|   oy = 0
 | |
|   objects = new Array()
 | |
|   object_hover = false
 | |
|   getwh()
 | |
|   event_states = ['onmouseover', 'onmouseout', 'onmousemove', 'onmousedown', 'onmouseup', 'onclick']
 | |
|   style_states = ['hover', 'active']
 | |
|   globalstate = 'normal'
 | |
|   
 | |
|   // Creating the wrapper
 | |
|   wrapper = document.createElement('div')
 | |
|   wrapper.style.position = 'absolute'
 | |
|   document.body.appendChild(wrapper)
 | |
|   /*dbg = document.createElement('div')
 | |
|   dbg.style.position = 'absolute'
 | |
|   document.body.appendChild(dbg)*/
 | |
|   
 | |
|   // Adjust on resize
 | |
|   window.onresize = function() {
 | |
|     getwh()
 | |
|   }
 | |
|   
 | |
|   window.onmousedown = function() {
 | |
|     for (var i in objects) {
 | |
|       objects[i].globalstate = 'onmousedown'
 | |
|     }
 | |
|   }
 | |
|   
 | |
|   window.onmouseup = function() {
 | |
|     for (var i in objects) {
 | |
|       objects[i].globalstate = 'onmouseup'
 | |
|     }
 | |
|   }
 | |
|   
 | |
|   standby()
 | |
|   
 | |
|   loadobjects()
 | |
| }
 | |
| 
 | |
| window.onmousemove = function(e) {
 | |
|   if (!e) var e = window.event
 | |
|   if (e.pageX || e.pageY) {
 | |
|     x = e.pageX
 | |
|     y = e.pageY
 | |
|   }
 | |
|   else if (e.clientX || e.clientY) {
 | |
|     x = e.clientX + document.body.scrollLeft
 | |
|     y = e.clientY + document.body.scrollTop
 | |
|   }
 | |
| }
 | |
| 
 | |
| function getwh() {
 | |
|   if (self.innerHeight) {
 | |
|     h = self.innerHeight
 | |
|     w = self.innerWidth
 | |
|   }
 | |
|   else if (document.documentElement && document.documentElement.clientHeight) {
 | |
|     h = document.documentElement.clientHeight
 | |
|     w = document.documentElement.clientHeight
 | |
|   }
 | |
|   else if (document.body) {
 | |
|     h = document.body.clientHeight
 | |
|     w = document.body.clientWidth
 | |
|   }
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| function loadobjects() {
 | |
|   circ = new Circle(250, 250, 50, ['radial', ['#00ff00', '#dd33ee', '#888', '#00ffff']], 0, '#000')
 | |
|   circ.hover.fillColor = ['radial', ['#0000ff', '#dd33ee', '#333', '#00ffff']]
 | |
|   circ.active.fillColor = ['linear', ['#fff', '#000'], -45]
 | |
|   
 | |
|   circ2 = new Circle(270, 280, 30, '#eee', 5, '#333')
 | |
|   circ2.hover.fillColor = '#ff00ff'
 | |
|   circ2.active.fillColor = '#ff0000'
 | |
|   
 | |
|   circ3 = new Circle(260, 220, 25, ['radial', ['#fff', '#000']], 7, '#333')
 | |
|   circ3.hover.fillColor = ['radial', ['#000', '#fff']]
 | |
|   
 | |
|   circ4 = new Circle(340, 290, 60, ['radial', ['rgb(221, 87, 42)', 'rgb(155, 60, 28)'], .6, -10], 0, '#333')
 | |
|   circ4.hover.fillColor = ['radial', ['#fff', '#000'], .4, 40]
 | |
|   
 | |
|   // Below is a list of functions that can be used on a circle.
 | |
|   /*
 | |
|   changeIndex
 | |
|   raiseIndex
 | |
|   lowerIndex
 | |
|   toTop
 | |
|   toBottom
 | |
|   hide
 | |
|   show
 | |
|   remove
 | |
|   */
 | |
| }
 | |
| </script>
 | |
| </head>
 | |
| <body></body>
 | |
| </html> |