Created
June 6, 2011 21:35
-
-
Save insidegui/1011179 to your computer and use it in GitHub Desktop.
Extensões úteis para trabalhar com canvas
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
// frameRate padrão será 25fps | |
CanvasRenderingContext2D.prototype.frameRate = 1000/25 | |
// setFrameRate(rate) | |
// @rate: frame rate a ser utilizado (em quadros por segundo - fps -) (ex: 30) | |
CanvasRenderingContext2D.prototype.setFrameRate = function(rate) | |
{ | |
// transforma o frame rate passado de quadros por segundo para ms | |
this.frameRate = Math.round(1000/rate); | |
return this.frameRate; | |
} | |
// roundRect(x, y, width, height, radius) | |
// desenha um retângulo com cantos arredondados | |
// @x: posição X no canvas para desenhar o retângulo (ex: 10) | |
// @y: posição Y no canvas para desenhar o retângulo (ex: 10) | |
// @width: largura do retângulo | |
// @height: altura do retângulo | |
// @radius: quantidade de "arredondamento" | |
CanvasRenderingContext2D.prototype.roundRect = function(x, y, width, height, radius) | |
{ | |
this.beginPath() | |
this.moveTo(x + radius, y) | |
this.lineTo(x + width - radius, y) | |
this.quadraticCurveTo(x + width, y, x + width, y + radius) | |
this.lineTo(x + width, y + height - radius) | |
this.quadraticCurveTo(x + width, y + height, x + width - radius, y + height) | |
this.lineTo(x + radius, y + height) | |
this.quadraticCurveTo(x, y + height, x, y + height - radius) | |
this.lineTo(x, y + radius) | |
this.quadraticCurveTo(x, y, x + radius, y) | |
this.closePath() | |
} | |
// size() | |
// retorna objeto contendo o tamanho do contexto e o centro na horizontal e na vertical (x/y) | |
CanvasRenderingContext2D.prototype.size = function() | |
{ | |
return { | |
width : this.canvas.width, | |
height : this.canvas.height, | |
centerX : this.canvas.width / 2, | |
centerY : this.canvas.height / 2 | |
}; | |
} | |
// animatedSprite(imageFile, totalFrames, frameWidth, x, y, loop, clearAtEnd) | |
// anima um sprite, que deve ser uma imagem com os diferentes frames distribuídos horizontalmente, a proporção do frame deve ser de 1:1 | |
// @imageFile: url da imagem que será utilizada como sprite animado (ex: "animation.png") | |
// @totalFrames: número de frames da animação (ex: 5) | |
// @frameWidth: largura do frame (ex: 75) | |
// @x: posição X no canvas para desenhar o sprite (ex: 10) | |
// @y: posição Y no canvas para desenhar o sprite (ex: 10) | |
// @loop: número de vezes para repetir a animação ou "bounce" para ir e voltar | |
// -1 ou true -> a animação repetirá infinitamente | |
// 0 ou 1 -> a animação será executada somente uma vez | |
// "bounce" -> quando chegar ao final, a animação irá "rebobinar" e reproduzir novamente | |
// @clearAtEnd: limpar o canvas quando a animação terminar (só se aplica se não houver loop) | |
CanvasRenderingContext2D.prototype.animatedSprite = function(imageFile, totalFrames, frameWidth, x, y, loop, clearAtEnd) { | |
// cria a imagem | |
var image = new Image() | |
image.setAttribute("src", imageFile) | |
// inicializa as variáveis | |
var timer = 0 // timer da animação | |
var currentFrame = 1 // frame atual | |
ctx = this // contexto do canvas | |
var rewind = false // define se está reproduzindo de trás pra frente | |
var i = 0 // contador de repetição | |
var imageData = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height) | |
// renderiza um quadro da imagem | |
var renderFrame = function(frame) | |
{ | |
// limpa o context | |
ctx.clearRect(x, y, frameWidth, frameWidth) | |
// insere o que estava "por trás" da animação primeiro | |
ctx.putImageData(imageData, 0, 0) | |
// pega o quadro atual da imagem com base no frame passado e no frameWidth e desenha no canvas | |
context.drawImage(image, frame*frameWidth, 0, frameWidth, frameWidth, x, y, frameWidth, frameWidth) | |
} | |
// executado quando a imagem é carregada pelo browser | |
image.onload = function() | |
{ | |
// pega informações de tamanho do context | |
ctxSize = ctx.size() | |
// inicializa o timer da animação | |
timer = setInterval(function(){ | |
// renderiza o quadro atual | |
renderFrame(currentFrame) | |
// cálculos de loop | |
// se não estiver rebobinando ... | |
if(rewind === false) { | |
// ... incrementa o frame atual em 1 | |
currentFrame++ | |
// se tiver chegado ao final da animação | |
if(currentFrame == totalFrames-1) { | |
// verifica qual o tipo de loop especificado | |
// se for do tipo bounce... | |
if(loop == "bounce") { | |
// ... "rebobina" a animação | |
rewind = true | |
// se não, verifica se o parametro loop é um número... | |
} else if(parseInt(loop) != "NaN") { | |
// ... se for um número, volta para o primeiro quadro da animação | |
currentFrame = 1 | |
// incrementa o contador | |
i++ | |
// se o parametro loop for -1 ou true, a animação repetirá infinitamente | |
// caso não seja... | |
if(loop != -1 && loop !== true) { | |
// ... se i for maior ou igual que o número de vezes que é para repetir... | |
if(i >= loop) { | |
// ... pára o timer da animação | |
clearInterval(timer) | |
// se for para limpar o quadro no final ... | |
if(clearAtEnd === true) { | |
// ... limpa o canvas | |
context.clearRect(0, 0, ctxSize.width, ctxSize.height) | |
// restaura imagem que estava no canvas antes da animação | |
ctx.putImageData(imageData, 0, 0) | |
} | |
} | |
} | |
} else { | |
clearInterval(timer) | |
} | |
} | |
} | |
// se estiver rebobinando... | |
if(rewind === true) { | |
// subtrai 1 do currentFrame | |
currentFrame-- | |
// se o frame atual for o primeiro ... | |
if(currentFrame == 1) { | |
// ... passa a reproduzir para frente como antes | |
rewind = false | |
} | |
} | |
}, ctx.frameRate) | |
} | |
} | |
// checkerboard(color, size) | |
// preenche o canvas com um padrão checkerboard | |
// @color: a cor dos quadrados (opcional / default "#CCC") (ex: "red" / "#F00" / "rgba(255,0,0,1)") | |
// @size: o tamanho dos quadrados (opcional / default 10) (ex: 20) | |
CanvasRenderingContext2D.prototype.checkerboard = function(color, size) | |
{ | |
if(typeof(color) == "undefined") { | |
color = "#CCC" | |
size = 10 | |
} | |
x = 0 | |
y = 0 | |
width = this.canvas.width | |
height = this.canvas.height | |
for(var h = 0; h < (height/size); h++) { | |
if(h % 2 == 0) { | |
var increment = 0 | |
} else { | |
var increment = size | |
} | |
for(var i = 0; i < (width/size); i++) { | |
if(i%2==0) { | |
var theColor = color | |
} else { | |
var theColor = "white" | |
} | |
this.fillStyle = theColor | |
this.fillRect(x+increment+size*i,y+size*h,size,size) | |
} | |
} | |
} | |
// fadedSphere(x,y,radius,color) | |
// desenha uma esfera "desbotada" | |
// @x: posição x onde desenhar a esfera (centro da esfera) (ex: 50) | |
// @y: posição y onde desenhar a esfera (centro da esfera) (ex: 50) | |
// @radius: raio da esfera (default 5) (ex: 10) | |
// @color: array com cor da esfera (default [255,255,255,0.5]) (ex: [255,0,0,1]) | |
CanvasRenderingContext2D.prototype.fadedSphere = function(x,y,radius,color) | |
{ | |
this.save() | |
if(typeof(radius) == "undefined") radius=5 | |
if(typeof(color) == "undefined") color = new Array(255, 255, 255, 0.5) | |
var grad = this.createRadialGradient(x, y, 1, x, y, radius) | |
grad.addColorStop(0, this.arrayToRGBA(color)) | |
if(color.length == 4) color.pop() | |
color.push(0) | |
grad.addColorStop(1, this.arrayToRGBA(color)) | |
this.fillStyle = grad | |
this.roundRect(x-radius, y-radius, radius*2, radius*2, radius) | |
this.globalCompositeOperation = "lighter"; | |
this.fill() | |
this.restore() | |
} | |
// arrayToRGBA(colorArray) | |
// transforma um array em cor no formato rgba para ser usada em fillStyle, strokeStyle ou gradientes | |
// @colorArray: array contendo as cores r,g,b e (opcionalmente) a. | |
// EXEMPLOS: | |
// var color = new Array(123,200,129) | |
// ctx.arrayToRGBA(color) // retornará "rgba(123,200,129,1)" | |
// | |
// var color = new Array(100,0,100, 0.5) | |
// ctx.arrayToRGBA(color) // retornará "rgba(100,0,100, 0.5)" | |
CanvasRenderingContext2D.prototype.arrayToRGBA = function(colorArray) | |
{ | |
var output = "rgba(" | |
output += colorArray[0] | |
output += ","+colorArray[1] | |
output += ","+colorArray[2] | |
if(colorArray.length == 3) { | |
output += ",1)" | |
} else { | |
output += ","+colorArray[3]+")" | |
} | |
return output | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment