New wiki-page
mNo edit summary |
mNo edit summary |
||
Line 1: | Line 1: | ||
<script> | <script> | ||
class FogParticle { | |||
constructor(ctx, canvasWidth, canvasHeight) { | |||
this.ctx = ctx | |||
this.canvasWidth = canvasWidth | |||
this.canvasHeight = canvasHeight | |||
this.x = 0 | |||
this.y = 0 | |||
} | |||
setPosition(x, y) { | |||
this.x = x | |||
this.y = y | |||
} | |||
setVelocity(x, y) { | |||
this.xVelocity = x | |||
this.yVelocity = y | |||
} | |||
setImage(image) { | |||
this.image = image | |||
} | |||
render() { | |||
if (!this.image) return | |||
this.ctx.drawImage( | |||
this.image, | |||
this.x - this.image.width / 2, | |||
this.y - this.image.height / 2, | |||
400, | |||
400 | |||
) | |||
this.x += this.xVelocity | |||
this.y += this.yVelocity | |||
if (this.x >= canvasWidth) { | // Check if has crossed the right edge | ||
this. | if (this.x >= this.canvasWidth) { | ||
this.x = canvasWidth | this.xVelocity = -this.xVelocity | ||
this.x = this.canvasWidth | |||
} | } | ||
// Check if has crossed the left edge | |||
else if (this.x <= 0) { | else if (this.x <= 0) { | ||
this. | this.xVelocity = -this.xVelocity | ||
this.x = 0 | this.x = 0 | ||
} | } | ||
// Check if has crossed the bottom edge | |||
if (this.y >= this.canvasHeight) { | |||
this.yVelocity = -this.yVelocity | |||
this.y = this.canvasHeight | |||
} | |||
// Check if has crossed the top edge | |||
else if (this.y <= 0) { | |||
this.yVelocity = -this.yVelocity | |||
this.y = 0 | |||
} | |||
} | |||
} | |||
if (this. | class Fog { | ||
this. | |||
this. | constructor({ selector, density = 50, velocity = 2, particle, bgi } = {}) { | ||
const canvas = document.querySelector(selector) | |||
const bcr = canvas.parentElement.getBoundingClientRect() | |||
this.ctx = canvas.getContext('2d') | |||
this.canvasWidth = canvas.width = bcr.width | |||
this.canvasHeight = canvas.height = bcr.height | |||
this.particleCount = density | |||
this.maxVelocity = velocity | |||
this.particle = particle | |||
this.bgi = bgi | |||
this._createParticles() | |||
this._setImage() | |||
if (!this.bgi) return | |||
const img = new Image() | |||
img.onload = () => { | |||
const size = coverImg(img, this.canvasWidth, this.canvasHeight) | |||
this.bgi = { img, w: size.w, h: size.h } | |||
this._render() | |||
} | } | ||
img.src = this.bgi | |||
} | |||
this. | _createParticles() { | ||
this. | this.particles = [] | ||
const random = (min, max) => Math.random() * (max - min) + min | |||
for (let i = 0; i < this.particleCount; i++) { | |||
const particle = new FogParticle(this.ctx, this.canvasWidth, this.canvasHeight) | |||
particle.setPosition( | |||
random(0, this.canvasWidth), | |||
random(0, this.canvasHeight) | |||
) | |||
particle.setVelocity( | |||
random(-this.maxVelocity, this.maxVelocity), | |||
random(-this.maxVelocity, this.maxVelocity) | |||
) | |||
this.particles.push(particle) | |||
} | } | ||
} | |||
_setImage() { | |||
if (!this.particle) return | |||
const img = new Image() | |||
img.onload = () => this.particles.forEach(p => p.setImage(img)) | |||
img.src = this.particle | |||
} | |||
} | |||
_render() { | |||
if (this.bgi) { | |||
this.ctx.drawImage(this.bgi.img, 0, 0, this.bgi.w, this.bgi.h) | |||
} else { | |||
this.ctx.fillStyle = "rgba(0, 0, 0, 1)" | |||
this.ctx.fillRect(0, 0, this.canvasWidth, this.canvasHeight) | |||
} | |||
this.particles.forEach(p => p.render()) | |||
requestAnimationFrame(this._render.bind(this)) | |||
} | |||
} | } | ||
class Eraser { | |||
constructor({ bgCanvas, brushCanvas, bgi, radius = 120 } = {}) { | |||
bgCanvas = this.bgCanvas = document.querySelector(bgCanvas) | |||
this.brushCanvas = document.querySelector(brushCanvas) | |||
this.bgCtx = this.bgCanvas.getContext('2d') | |||
this.brushCtx = this.brushCanvas.getContext('2d') | |||
this.parentElement = this.bgCanvas.parentElement | |||
const bcr = this.parentElement.getBoundingClientRect() | |||
this.canvasWidth = this.bgCanvas.width = this.brushCanvas.width = bcr.width | |||
this.canvasHeight = this.bgCanvas.height = this.brushCanvas.height = bcr.height | |||
this.brushRadius = radius | |||
this.bgi = new Image() | |||
this.bgi.onload = this._attachEvents.bind(this) | |||
this.bgi.src = bgi | |||
this.utils = { | |||
distanceBetween(point1, point2) { | |||
return Math.sqrt(Math.pow(point2.x - point1.x, 2) + Math.pow(point2.y - point1.y, 2)) | |||
}, | |||
angleBetween(point1, point2) { | |||
return Math.atan2(point2.x - point1.x, point2.y - point1.y) | |||
}, | |||
getMousePos(e) { | |||
const bcr = bgCanvas.getBoundingClientRect() | |||
return { | |||
x: e.clientX - bcr.left, | |||
y: e.clientY - bcr.top | |||
} | |||
} | |||
} | } | ||
} | } | ||
_attachEvents() { | |||
this.parentElement.addEventListener('mousemove', this._onMouseMove.bind(this)) | |||
this.parentElement.addEventListener('mouseleave', this._onMouseLeave.bind(this)) | |||
} | } | ||
_onMouseMove(e) { | |||
const currentPoint = this.utils.getMousePos(e) | |||
this.lastPoint = this.lastPoint || currentPoint | |||
const dist = this.utils.distanceBetween(this.lastPoint, currentPoint) | |||
const angle = this.utils.angleBetween(this.lastPoint, currentPoint) | |||
for (let ii = 0; ii < dist; ii += 5) { | |||
const x = this.lastPoint.x + (Math.sin(angle) * ii) | |||
const y = this.lastPoint.y + (Math.cos(angle) * ii) | |||
const brush = this.brushCtx.createRadialGradient(x, y, 0, x, y, this.brushRadius) | |||
brush.addColorStop(0, 'rgba(0, 0, 0, 1)') | |||
brush.addColorStop(.3, 'rgba(0, 0, 0, .1)') | |||
brush.addColorStop(1, 'rgba(0, 0, 0, 0)') | |||
this.brushCtx.fillStyle = brush | |||
this.brushCtx.fillRect( | |||
x - this.brushRadius, | |||
y - this.brushRadius, | |||
} | this.brushRadius * 2, | ||
this.brushRadius * 2 | |||
) | |||
} | |||
} | this.lastPoint = currentPoint | ||
this.bgCtx.globalCompositeOperation = 'source-over' | |||
const size = coverImg(this.bgi, this.canvasWidth, this.canvasHeight) | |||
this.bgCtx.drawImage(this.bgi, 0, 0, size.w, size.h) | |||
this.bgCtx.globalCompositeOperation = 'destination-in' | |||
this.bgCtx.drawImage(this.brushCanvas, 0, 0) | |||
} | |||
_onMouseLeave() { | |||
this.lastPoint = null | |||
} | |||
} | |||
const coverImg = (img, width, height) => { | |||
if ( | const ratio = img.width / img.height | ||
let w = width | |||
let h = w / ratio | |||
}, | if (h < height) { | ||
h = height | |||
w = h * ratio | |||
} | |||
return { w, h } | |||
} | } | ||
// const bgi = 'http://saijogeorge.com/test/assets/images/mybackground.png' | |||
const bgi = 'http://www.wallpaperup.com/uploads/wallpapers/2013/02/20/42433/big_thumb_a4789e7543f7b7467e6b1efcba41eaa0.jpg' | |||
new Fog({ | |||
selector: '#fog', | |||
particle: 'http://asista.pl/f/fog-particle.png', | |||
density: 80, | |||
bgi, | |||
}) | |||
</script> | </script> | ||
<canvas id="canvas" width="750" height="390"></canvas> | <canvas id="canvas" width="750" height="390"></canvas> |
Revision as of 12:58, 17 July 2017
<script> class FogParticle {
constructor(ctx, canvasWidth, canvasHeight) { this.ctx = ctx this.canvasWidth = canvasWidth this.canvasHeight = canvasHeight this.x = 0 this.y = 0 }
setPosition(x, y) { this.x = x this.y = y }
setVelocity(x, y) { this.xVelocity = x this.yVelocity = y }
setImage(image) { this.image = image }
render() { if (!this.image) return
this.ctx.drawImage( this.image, this.x - this.image.width / 2, this.y - this.image.height / 2, 400, 400 )
this.x += this.xVelocity this.y += this.yVelocity
// Check if has crossed the right edge if (this.x >= this.canvasWidth) { this.xVelocity = -this.xVelocity this.x = this.canvasWidth } // Check if has crossed the left edge else if (this.x <= 0) { this.xVelocity = -this.xVelocity this.x = 0 }
// Check if has crossed the bottom edge if (this.y >= this.canvasHeight) { this.yVelocity = -this.yVelocity this.y = this.canvasHeight } // Check if has crossed the top edge else if (this.y <= 0) { this.yVelocity = -this.yVelocity this.y = 0 } }
}
class Fog {
constructor({ selector, density = 50, velocity = 2, particle, bgi } = {}) { const canvas = document.querySelector(selector) const bcr = canvas.parentElement.getBoundingClientRect() this.ctx = canvas.getContext('2d') this.canvasWidth = canvas.width = bcr.width this.canvasHeight = canvas.height = bcr.height
this.particleCount = density this.maxVelocity = velocity this.particle = particle this.bgi = bgi
this._createParticles() this._setImage()
if (!this.bgi) return
const img = new Image() img.onload = () => { const size = coverImg(img, this.canvasWidth, this.canvasHeight) this.bgi = { img, w: size.w, h: size.h } this._render() } img.src = this.bgi }
_createParticles() { this.particles = []
const random = (min, max) => Math.random() * (max - min) + min
for (let i = 0; i < this.particleCount; i++) { const particle = new FogParticle(this.ctx, this.canvasWidth, this.canvasHeight)
particle.setPosition( random(0, this.canvasWidth), random(0, this.canvasHeight) ) particle.setVelocity( random(-this.maxVelocity, this.maxVelocity), random(-this.maxVelocity, this.maxVelocity) )
this.particles.push(particle) } }
_setImage() { if (!this.particle) return
const img = new Image() img.onload = () => this.particles.forEach(p => p.setImage(img)) img.src = this.particle }
_render() { if (this.bgi) { this.ctx.drawImage(this.bgi.img, 0, 0, this.bgi.w, this.bgi.h) } else { this.ctx.fillStyle = "rgba(0, 0, 0, 1)" this.ctx.fillRect(0, 0, this.canvasWidth, this.canvasHeight) }
this.particles.forEach(p => p.render())
requestAnimationFrame(this._render.bind(this)) }
}
class Eraser {
constructor({ bgCanvas, brushCanvas, bgi, radius = 120 } = {}) { bgCanvas = this.bgCanvas = document.querySelector(bgCanvas) this.brushCanvas = document.querySelector(brushCanvas) this.bgCtx = this.bgCanvas.getContext('2d') this.brushCtx = this.brushCanvas.getContext('2d')
this.parentElement = this.bgCanvas.parentElement const bcr = this.parentElement.getBoundingClientRect() this.canvasWidth = this.bgCanvas.width = this.brushCanvas.width = bcr.width this.canvasHeight = this.bgCanvas.height = this.brushCanvas.height = bcr.height
this.brushRadius = radius
this.bgi = new Image() this.bgi.onload = this._attachEvents.bind(this) this.bgi.src = bgi
this.utils = { distanceBetween(point1, point2) { return Math.sqrt(Math.pow(point2.x - point1.x, 2) + Math.pow(point2.y - point1.y, 2)) }, angleBetween(point1, point2) { return Math.atan2(point2.x - point1.x, point2.y - point1.y) }, getMousePos(e) { const bcr = bgCanvas.getBoundingClientRect() return { x: e.clientX - bcr.left, y: e.clientY - bcr.top } } } }
_attachEvents() { this.parentElement.addEventListener('mousemove', this._onMouseMove.bind(this)) this.parentElement.addEventListener('mouseleave', this._onMouseLeave.bind(this)) }
_onMouseMove(e) { const currentPoint = this.utils.getMousePos(e) this.lastPoint = this.lastPoint || currentPoint
const dist = this.utils.distanceBetween(this.lastPoint, currentPoint) const angle = this.utils.angleBetween(this.lastPoint, currentPoint)
for (let ii = 0; ii < dist; ii += 5) { const x = this.lastPoint.x + (Math.sin(angle) * ii) const y = this.lastPoint.y + (Math.cos(angle) * ii)
const brush = this.brushCtx.createRadialGradient(x, y, 0, x, y, this.brushRadius) brush.addColorStop(0, 'rgba(0, 0, 0, 1)') brush.addColorStop(.3, 'rgba(0, 0, 0, .1)') brush.addColorStop(1, 'rgba(0, 0, 0, 0)')
this.brushCtx.fillStyle = brush this.brushCtx.fillRect( x - this.brushRadius, y - this.brushRadius, this.brushRadius * 2, this.brushRadius * 2 ) }
this.lastPoint = currentPoint
this.bgCtx.globalCompositeOperation = 'source-over' const size = coverImg(this.bgi, this.canvasWidth, this.canvasHeight) this.bgCtx.drawImage(this.bgi, 0, 0, size.w, size.h) this.bgCtx.globalCompositeOperation = 'destination-in' this.bgCtx.drawImage(this.brushCanvas, 0, 0) }
_onMouseLeave() { this.lastPoint = null }
}
const coverImg = (img, width, height) => {
const ratio = img.width / img.height let w = width let h = w / ratio if (h < height) { h = height w = h * ratio } return { w, h }
}
// const bgi = 'http://saijogeorge.com/test/assets/images/mybackground.png' const bgi = 'http://www.wallpaperup.com/uploads/wallpapers/2013/02/20/42433/big_thumb_a4789e7543f7b7467e6b1efcba41eaa0.jpg'
new Fog({
selector: '#fog', particle: 'http://asista.pl/f/fog-particle.png', density: 80, bgi,
})
</script>
<canvas id="canvas" width="750" height="390"></canvas>