made synthwave pixelated

This commit is contained in:
8BitBiscotti
2024-12-12 13:50:04 +01:00
parent 17187ad792
commit 367c844669
6 changed files with 160 additions and 42 deletions
+10
View File
@@ -13,6 +13,16 @@ function randomInt(min, max) {
}
function clampNearest(n, mul) {
if(n > 0)
return Math.ceil(n / mul) * mul;
else if( n < 0)
return Math.floor(n / mul) * mul;
else
return 0;
}
function showGrid() {
let canvasEl = document.createElement("canvas")
canvasEl.width = window.innerWidth
+1 -1
View File
@@ -15,7 +15,7 @@
<body style="background-color: #323232; color: #ffffff;">
<img src="/assets/starNoise_512x512.png" draggable="false" id="starNoise">
<img src="/assets/synthwaveSun_40x40.png" draggable="false" class="synthSun">
<canvas id="synthwave" style="position: absolute; bottom: 0%; left: 0%;"></canvas>
<canvas id="synthwave" style="position: absolute; bottom: round(0%, var(--pxDensityPx)); left: round(0%, var(--pxDensityPx));"></canvas>
<ul class="navBar">
<li>
+6 -1
View File
@@ -10,7 +10,12 @@ let tips = [
"m".repeat(200),
"Bad at a game? Just press the \"get good at games\" button!",
"I AM NOT A FEMBOY NOR GAY. (I support though :thumbsup:)",
"You should listen to that song that goes \"do do do do do do do do do.\""
"You should listen to that song that goes \"do do do do do do do do do.\"",
"Every pixel in this website's pixel art is positioned pixel perfect.",
"Shouldn't I be talking about tips?",
"Did you know that... uh... hold on let me think... I don't know, I forgot.",
"This tip is very helpful.",
"The synthwave terrain background is fully procedural. No images or gifs were used."
]
let selectedTip = tips[randomIntFrom0(tips.length)]
+1
View File
@@ -21,6 +21,7 @@ li {
left: 50%;
transform: translateX(-50%);
font-size: 0px;
width: max-content;
}
.navBtn {
background-color: transparent;
+2 -2
View File
@@ -1,4 +1,4 @@
let pxDensity = getComputedStyle(document.body).getPropertyValue("--pxDensity")
let pxDensity = parseFloat(getComputedStyle(document.body).getPropertyValue("--pxDensity"))
let pxDensityDefined = false
function calcPixelDensity() {
@@ -8,7 +8,7 @@ function calcPixelDensity() {
document.documentElement.style.setProperty("--pxDensity", Math.max(densityWidth, densityHeight))
document.documentElement.style.setProperty("--pxDensityPx", `${Math.max(densityWidth, densityHeight)}px`)
pxDensity = getComputedStyle(document.body).getPropertyValue("--pxDensity")
pxDensity = parseFloat(getComputedStyle(document.body).getPropertyValue("--pxDensity"))
pxDensityDefined = true
console.log("pxDensity: " + getComputedStyle(document.body).getPropertyValue("--pxDensity"))
+140 -38
View File
@@ -3,8 +3,11 @@ let ctx = canvas.getContext("2d")
let hills = []
let isAnimating = true
let pxInflate = 0.5
canvas.width = window.innerWidth
canvas.height = window.innerHeight
ctx.imageSmoothingEnabled = false;
function lerp(x, y, t) {
@@ -17,6 +20,86 @@ function hillCurve(x, width) {
}
function drawPixelLineLow(fromX, fromY, toX, toY) {
let dx = toX - fromX
let dy = toY - fromY
let yi = 1
if (dy < 0) {
yi = -1
dy = -dy
}
let d = 2 * dy - dx
y = fromY
for (let x = fromX; x <= toX; x++) {
ctx.rect(
clampNearest(x * pxDensity, pxDensity) - 0.5,
clampNearest(y * pxDensity, pxDensity) - 0.5,
pxInflate + pxDensity,
pxInflate + pxDensity
);
if (d > 0) {
y = y + yi;
d = d + (2 * (dy - dx));
}
else { d = d + 2 * dy; }
}
}
function drawPixelLineHigh(fromX, fromY, toX, toY) {
let dx = toX - fromX
let dy = toY - fromY
let xi = 1
if (dx < 0) {
xi = -1
dx = -dx
}
let d = 2 * dx - dy
x = fromX
for (let y = fromY; y <= toY; y++) {
ctx.rect(
clampNearest(x * pxDensity, pxDensity) - 0.5,
clampNearest(y * pxDensity, pxDensity) - 0.5,
pxInflate + pxDensity,
pxInflate + pxDensity
);
if (d > 0) {
x = x + xi;
d = d + (2 * (dx - dy));
}
else { d = d + 2 * dx; }
}
}
function drawPixelLine(fromX, fromY, toX, toY) {
if (Math.abs(toY - fromY) < Math.abs(toX - fromX)) {
if (fromX > toX) {
drawPixelLineLow(toX, toY, fromX, fromY);
}
else {
drawPixelLineLow(fromX, fromY, toX, toY);
}
}
else {
if (fromY > toY) {
drawPixelLineHigh(toX, toY, fromX, fromY);
}
else {
drawPixelLineHigh(fromX, fromY, toX, toY);
}
}
}
class Hill {
constructor(x, y, color, xRandom, width, frameCount) {
this.color = color
@@ -50,34 +133,47 @@ class Hill {
}
draw() {
ctx.strokeStyle = `rgb(${this.color[0]}, ${this.color[1]}, ${this.color[2]})`
draw(debug) {
ctx.lineWidth = pxDensity
let startX = (this.points[0][0] * this.widthMul) + ((-this.width * this.widthMul) / 2) + this.x
let startY = (this.points[0][1] * this.widthMul) + this.y
let startX = ((this.points[0][0] * this.widthMul) + ((-this.width * this.widthMul) / 2) + this.x) / pxDensity
let startY = ((this.points[0][1] * this.widthMul) + this.y) / pxDensity
let previousX = startX
let previousY = startY
ctx.beginPath()
ctx.moveTo(startX, startY)
if (debug) { ctx.moveTo(startX * pxDensity, startY * pxDensity) }
for (let point of this.points) {
ctx.lineTo(
(point[0] * this.widthMul) + ((-this.width * this.widthMul) / 2) + this.x,
(point[1] * this.widthMul) + this.y
)
let x = ((point[0] * this.widthMul) + ((-this.width * this.widthMul) / 2) + this.x) / pxDensity
let y = ((point[1] * this.widthMul) + this.y) / pxDensity
if (debug) { ctx.lineTo(x * pxDensity, y * pxDensity) }
else { drawPixelLine(previousX, previousY, x, y) }
previousX = x
previousY = y
}
if (debug) {
ctx.strokeStyle = "#ff0000"
ctx.stroke()
}
else {
ctx.fillStyle = `rgb(${this.color[0]}, ${this.color[1]}, ${this.color[2]})`
ctx.fill()
}
ctx.stroke()
}
animateStep(stepSize, colorIncrement) {
animateStep(stepSize, colorIncrement, debug) {
if (this.i >= this.frameCount) {
hills.pop(this)
return
}
this.y += stepSize
this.draw()
this.draw(debug)
this.i += 1
@@ -88,7 +184,35 @@ class Hill {
}
const iterToNewHill = 15
function connectHills(hill, previousHill, idx) {
if (previousHill && idx != 0) {
for (idx in previousHill.points) {
let startX = (previousHill.points[idx][0] * previousHill.widthMul) + ((-previousHill.width * previousHill.widthMul) / 2) + previousHill.x
let startY = (previousHill.points[idx][1] * previousHill.widthMul) + previousHill.y
let endX = (hill.points[idx][0] * hill.widthMul) + ((-hill.width * hill.widthMul) / 2) + hill.x
let endY = (hill.points[idx][1] * hill.widthMul) + hill.y
let grad = ctx.createLinearGradient(startX, startY, endX, endY)
let col = hill.color
let pCol = previousHill.color
grad.addColorStop(0, `rgb(${pCol[0]}, ${pCol[1]}, ${pCol[2]})`)
grad.addColorStop(1, `rgb(${col[0]}, ${col[1]}, ${col[2]})`)
ctx.strokeStyle = grad
ctx.strokeStyle = "#ff0000"
ctx.lineWidth = pxDensity
ctx.beginPath()
ctx.moveTo(startX, startY)
ctx.lineTo(endX, endY)
ctx.stroke()
}
}
}
const iterToNewHill = 25
let iters = 0
let previousHill = undefined
@@ -107,34 +231,12 @@ function animateSynthWave() {
for (let idx in hills) {
let hill = hills[idx]
hill.animateStep(hill.stepSize, -0.2)
//hill.animateStep(hill.stepSize, -0.2, true)
hill.animateStep(hill.stepSize, -0.2, false)
hill.stepSize = -0.005
hill.widthMul *= 1.01
if (previousHill && idx != 0) {
for (idx in previousHill.points) {
let startX = (previousHill.points[idx][0] * previousHill.widthMul) + ((-previousHill.width * previousHill.widthMul) / 2) + previousHill.x
let startY = (previousHill.points[idx][1] * previousHill.widthMul) + previousHill.y
let endX = (hill.points[idx][0] * hill.widthMul) + ((-hill.width * hill.widthMul) / 2) + hill.x
let endY = (hill.points[idx][1] * hill.widthMul) + hill.y
let grad = ctx.createLinearGradient(startX, startY, endX, endY)
let col = hill.color
let pCol = previousHill.color
grad.addColorStop(0, `rgb(${pCol[0]}, ${pCol[1]}, ${pCol[2]})`)
grad.addColorStop(1, `rgb(${col[0]}, ${col[1]}, ${col[2]})`)
ctx.strokeStyle = grad
ctx.lineWidth = pxDensity
ctx.beginPath()
ctx.moveTo(startX, startY)
ctx.lineTo(endX, endY)
ctx.stroke()
}
}
//connectHills(hill, previousHill, idx)
previousHill = hill
}