mirror of
https://github.com/leporello-js/leporello-js
synced 2026-01-13 13:04:30 -08:00
canvas
This commit is contained in:
68
docs/examples/animated_fractal_tree/animated_fractal_tree.js
Normal file
68
docs/examples/animated_fractal_tree/animated_fractal_tree.js
Normal file
@@ -0,0 +1,68 @@
|
||||
// Original source: http://bricault.mit.edu/recursive-drawing
|
||||
// Author: Sarah Bricault
|
||||
|
||||
// Canvas setup
|
||||
const canvas = document.createElement('canvas')
|
||||
canvas.width = 700
|
||||
canvas.height = 700
|
||||
document.body.appendChild(canvas)
|
||||
const ctx = canvas.getContext('2d')
|
||||
ctx.translate(canvas.width / 2, canvas.height)
|
||||
|
||||
// Draw a tree
|
||||
await fractalTreeBasic({totalIterations: 10, basicLength: 10, rotate: 25})
|
||||
|
||||
function sleep() {
|
||||
return new Promise(resolve => setTimeout(resolve, 3))
|
||||
}
|
||||
|
||||
async function fractalTreeBasic({totalIterations, basicLength, rotate}) {
|
||||
|
||||
// Draw the tree trunk
|
||||
const trunkLength = basicLength * 2 * Math.pow(1.2, totalIterations + 1)
|
||||
const width = Math.pow(totalIterations, 0.6)
|
||||
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(0, 0)
|
||||
ctx.lineTo(0, - trunkLength)
|
||||
ctx.lineWidth = width
|
||||
ctx.strokeStyle = 'black'
|
||||
ctx.stroke()
|
||||
|
||||
await drawBranch(90, [0, - trunkLength], totalIterations + 1)
|
||||
|
||||
async function drawBranch(angle, startPoint, iterations) {
|
||||
const len = basicLength * Math.pow(1.2, iterations)
|
||||
|
||||
const width = Math.pow(iterations, 0.6)
|
||||
|
||||
const red = Math.floor(255 - (iterations / totalIterations) * 255)
|
||||
const green = 0
|
||||
const blue = Math.floor( 255 - (iterations / totalIterations) * 255)
|
||||
const color = `rgb(${red}, ${green}, ${blue})`
|
||||
|
||||
const x1 = startPoint[0]
|
||||
const y1 = startPoint[1]
|
||||
|
||||
const y2 = y1 - len * Math.sin((angle * Math.PI) / 180)
|
||||
const x2 = x1 + len * Math.cos((angle * Math.PI) / 180)
|
||||
|
||||
console.log('draw branch', x1, y1, x2, y2)
|
||||
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(x1, y1)
|
||||
ctx.lineTo(x2, y2)
|
||||
ctx.lineWidth = width
|
||||
ctx.strokeStyle = color
|
||||
ctx.stroke()
|
||||
|
||||
await sleep()
|
||||
|
||||
if (iterations - 1 > 0) {
|
||||
// draw left branch
|
||||
await drawBranch(angle + rotate, [x2, y2], iterations - 1)
|
||||
// draw right branch
|
||||
await drawBranch(angle - rotate, [x2, y2], iterations - 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
98
docs/examples/canvas_animation_bubbles/bubbles.js
Normal file
98
docs/examples/canvas_animation_bubbles/bubbles.js
Normal file
@@ -0,0 +1,98 @@
|
||||
// Original source:
|
||||
// https://www.freecodecamp.org/news/how-to-create-animated-bubbles-with-html5-canvas-and-javascript/
|
||||
|
||||
const canvas = document.createElement('canvas')
|
||||
canvas.style.backgroundColor = '#00b4ff'
|
||||
document.body.appendChild(canvas)
|
||||
canvas.width = window.innerWidth
|
||||
canvas.height = window.innerHeight
|
||||
|
||||
const context = canvas.getContext("2d")
|
||||
|
||||
context.font = "30px Arial"
|
||||
context.textAlign = 'center'
|
||||
context.fillStyle = 'white'
|
||||
context.fillText('Click to spawn bubbles', canvas.width/2, canvas.height/2)
|
||||
|
||||
let circles = []
|
||||
|
||||
function draw(circle) {
|
||||
context.beginPath()
|
||||
context.arc(circle.x, circle.y, circle.radius, 0, 2 * Math.PI)
|
||||
context.strokeStyle = `hsl(${circle.hue} 100% 50%)`
|
||||
context.stroke()
|
||||
|
||||
const gradient = context.createRadialGradient(
|
||||
circle.x,
|
||||
circle.y,
|
||||
1,
|
||||
circle.x + 0.5,
|
||||
circle.y + 0.5,
|
||||
circle.radius
|
||||
)
|
||||
|
||||
gradient.addColorStop(0.3, "rgba(255, 255, 255, 0.3)")
|
||||
gradient.addColorStop(0.95, "#e7feff")
|
||||
|
||||
context.fillStyle = gradient
|
||||
context.fill()
|
||||
}
|
||||
|
||||
function move(circle, timeDelta) {
|
||||
circle.x = circle.x + timeDelta*circle.dx
|
||||
circle.y = circle.y - timeDelta*circle.dy
|
||||
}
|
||||
|
||||
let intervalId
|
||||
|
||||
function startAnimation() {
|
||||
if(intervalId == null) {
|
||||
intervalId = setInterval(animate, 20)
|
||||
}
|
||||
}
|
||||
|
||||
function stopAnimation() {
|
||||
if(intervalId != null) {
|
||||
clearInterval(intervalId)
|
||||
intervalId = null
|
||||
}
|
||||
}
|
||||
|
||||
let prevFrameTime
|
||||
|
||||
const animate = () => {
|
||||
const now = Date.now()
|
||||
const timeDelta = prevFrameTime == null ? 0 : now - prevFrameTime
|
||||
prevFrameTime = now
|
||||
|
||||
if(circles.length == 0) {
|
||||
return
|
||||
}
|
||||
|
||||
context.clearRect(0, 0, canvas.width, canvas.height)
|
||||
|
||||
circles.forEach(circle => {
|
||||
move(circle, timeDelta)
|
||||
draw(circle)
|
||||
})
|
||||
}
|
||||
|
||||
const createCircles = (event) => {
|
||||
startAnimation()
|
||||
|
||||
circles = circles.concat(Array.from({length: 50}, () => (
|
||||
{
|
||||
x: event.pageX,
|
||||
y: event.pageY,
|
||||
radius: Math.random() * 50,
|
||||
dx: Math.random() * 0.3,
|
||||
dy: Math.random() * 0.7,
|
||||
hue: 200,
|
||||
}
|
||||
)))
|
||||
}
|
||||
|
||||
canvas.addEventListener("click", createCircles)
|
||||
|
||||
window.onfocus = startAnimation
|
||||
window.onblur = stopAnimation
|
||||
62
docs/examples/fractal_tree/fractal_tree.js
Normal file
62
docs/examples/fractal_tree/fractal_tree.js
Normal file
@@ -0,0 +1,62 @@
|
||||
// Original source: http://bricault.mit.edu/recursive-drawing
|
||||
// Author: Sarah Bricault
|
||||
|
||||
// Canvas setup
|
||||
const canvas = document.createElement('canvas')
|
||||
canvas.width = 700
|
||||
canvas.height = 700
|
||||
document.body.appendChild(canvas)
|
||||
const ctx = canvas.getContext('2d')
|
||||
ctx.translate(canvas.width / 2, canvas.height)
|
||||
|
||||
// Draw a tree
|
||||
fractalTreeBasic({totalIterations: 10, basicLength: 10, rotate: 25})
|
||||
|
||||
function fractalTreeBasic({totalIterations, basicLength, rotate}) {
|
||||
|
||||
// Draw the tree trunk
|
||||
const trunkLength = basicLength * 2 * Math.pow(1.2, totalIterations + 1)
|
||||
const width = Math.pow(totalIterations, 0.6)
|
||||
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(0, 0)
|
||||
ctx.lineTo(0, - trunkLength)
|
||||
ctx.lineWidth = width
|
||||
ctx.strokeStyle = 'black'
|
||||
ctx.stroke()
|
||||
|
||||
drawBranch(90, [0, - trunkLength], totalIterations + 1)
|
||||
|
||||
function drawBranch(angle, startPoint, iterations) {
|
||||
const len = basicLength * Math.pow(1.2, iterations)
|
||||
|
||||
const width = Math.pow(iterations, 0.6)
|
||||
|
||||
const red = Math.floor(255 - (iterations / totalIterations) * 255)
|
||||
const green = 0
|
||||
const blue = Math.floor( 255 - (iterations / totalIterations) * 255)
|
||||
const color = `rgb(${red}, ${green}, ${blue})`
|
||||
|
||||
const x1 = startPoint[0]
|
||||
const y1 = startPoint[1]
|
||||
|
||||
const y2 = y1 - len * Math.sin((angle * Math.PI) / 180)
|
||||
const x2 = x1 + len * Math.cos((angle * Math.PI) / 180)
|
||||
|
||||
console.log('draw branch', x1, y1, x2, y2)
|
||||
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(x1, y1)
|
||||
ctx.lineTo(x2, y2)
|
||||
ctx.lineWidth = width
|
||||
ctx.strokeStyle = color
|
||||
ctx.stroke()
|
||||
|
||||
if (iterations - 1 > 0) {
|
||||
// draw left branch
|
||||
drawBranch(angle + rotate, [x2, y2], iterations - 1)
|
||||
// draw right branch
|
||||
drawBranch(angle - rotate, [x2, y2], iterations - 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user