mirror of
https://github.com/SamEyeBam/animate.git
synced 2025-12-15 02:01:05 +00:00
So much play
This commit is contained in:
@@ -92,6 +92,10 @@ async function fetchConfig(className) {
|
||||
{ type: "range", min: -180, max: 180, defaultValue: 18, property: "rotate2" },
|
||||
{ type: "range", min: 0, max: 400, defaultValue: 160, property: "width2" },
|
||||
],
|
||||
Countdown: [
|
||||
{ type: "range", min: 300, max: 600, defaultValue: 342, property: "width" },
|
||||
{ type: "range", min: 100, max: 1000, defaultValue: 100, property: "limiter" },
|
||||
],
|
||||
NewWave: [
|
||||
{ type: "range", min: 300, max: 600, defaultValue: 342, property: "width" },
|
||||
{ type: "range", min: 2, max: 40, defaultValue: 4, property: "sides" },
|
||||
@@ -146,7 +150,7 @@ async function fetchConfig(className) {
|
||||
|
||||
|
||||
function addControl(item, instance) {
|
||||
let parentDiv = document.getElementById("custom");
|
||||
let parentDiv = document.getElementById("shape-controls");
|
||||
|
||||
let title = document.createElement("p");
|
||||
title.innerText = item.property + ": " + item.defaultValue;
|
||||
@@ -203,6 +207,9 @@ function addControl(item, instance) {
|
||||
control.innerText = item.text;
|
||||
control.className = "header";
|
||||
control.id = "elHeader" + item.text.replace(/\s+/g, '');
|
||||
// Headers are handled differently - add directly to parent
|
||||
parentDiv.appendChild(control);
|
||||
return { element: control, listener: eventListener };
|
||||
}
|
||||
else if (item.type === "color") {
|
||||
control = document.createElement("input");
|
||||
@@ -224,7 +231,6 @@ function addControl(item, instance) {
|
||||
control.checked = item.defaultValue;
|
||||
instance[item.property] = item.defaultValue;
|
||||
control.id = "el" + item.property;
|
||||
// control.height = "20px";
|
||||
control.addEventListener("change", (event) => {
|
||||
const newValue = event.target.checked;
|
||||
instance[item.property] = newValue;
|
||||
@@ -234,15 +240,128 @@ function addControl(item, instance) {
|
||||
|
||||
if (item.type != "header") {
|
||||
control.className = "control";
|
||||
// control.id = "el" + item.property;
|
||||
}
|
||||
|
||||
if (item.type != "button" && item.type != "header") {
|
||||
parentDiv.appendChild(title);
|
||||
}
|
||||
parentDiv.appendChild(control);
|
||||
// Create container div for the control
|
||||
let containerDiv = document.createElement("div");
|
||||
containerDiv.className = "control-container";
|
||||
|
||||
return { element: control, listener: eventListener };
|
||||
// Add title and control to container
|
||||
if (item.type != "button") {
|
||||
containerDiv.appendChild(title);
|
||||
}
|
||||
containerDiv.appendChild(control);
|
||||
|
||||
|
||||
let filtersDiv = document.createElement("div");
|
||||
|
||||
// if (item.type === "range") {
|
||||
// let addFilterButton = document.createElement("button");
|
||||
// addFilterButton.innerText = "Add Filter";
|
||||
// addFilterButton.className = "add-filter-button";
|
||||
// addFilterButton.addEventListener("click", () => {
|
||||
// const filterDiv = createFilter(item);
|
||||
// filtersDiv.appendChild(filterDiv);
|
||||
|
||||
// });
|
||||
// filtersDiv.appendChild(addFilterButton);
|
||||
// }
|
||||
|
||||
// Add filters div at the bottom
|
||||
filtersDiv.className = "control-filters";
|
||||
filtersDiv.id = "filters-" + item.property;
|
||||
containerDiv.appendChild(filtersDiv);
|
||||
|
||||
// Add the complete container to parent
|
||||
parentDiv.appendChild(containerDiv);
|
||||
|
||||
return { element: control, listener: eventListener, filtersDiv: filtersDiv };
|
||||
}
|
||||
|
||||
function createFilter(item) {
|
||||
const filterDiv = document.createElement("div");
|
||||
filterDiv.className = "filter-div";
|
||||
filterDiv.innerText = "sin filter"; // Placeholder text
|
||||
|
||||
|
||||
let minTitle = document.createElement("p");
|
||||
minTitle.innerText = "Min:" + item.defaultValue;
|
||||
filterDiv.appendChild(minTitle);
|
||||
|
||||
let sinMin = document.createElement("input");
|
||||
sinMin.type = "range";
|
||||
sinMin.id = "el-filter-" + item.property;
|
||||
sinMin.min = -item.max;//item.min;
|
||||
sinMin.max = item.max;
|
||||
sinMin.value = item.defaultValue;
|
||||
|
||||
eventListener = (event) => {
|
||||
const newValue = parseInt(event.target.value, 10);
|
||||
// instance[item.property] = newValue;
|
||||
minTitle.innerText = "Min: " + newValue;
|
||||
|
||||
if (item.callback) {
|
||||
item.callback(instance, newValue);
|
||||
}
|
||||
};
|
||||
|
||||
sinMin.addEventListener("input", eventListener);
|
||||
filterDiv.appendChild(sinMin);
|
||||
|
||||
let maxTitle = document.createElement("p");
|
||||
maxTitle.innerText = "Max:" + item.defaultValue;
|
||||
filterDiv.appendChild(maxTitle);
|
||||
|
||||
|
||||
let sinMax = document.createElement("input");
|
||||
sinMax.type = "range";
|
||||
sinMax.id = "el-filter-" + item.property;
|
||||
sinMax.min = item.min;
|
||||
sinMax.max = item.max;
|
||||
sinMax.value = item.defaultValue;
|
||||
|
||||
eventListener = (event) => {
|
||||
const newValue = parseInt(event.target.value, 10);
|
||||
// instance[item.property] = newValue;
|
||||
maxTitle.innerText = "Max: " + newValue;
|
||||
|
||||
if (item.callback) {
|
||||
item.callback(instance, newValue);
|
||||
}
|
||||
};
|
||||
sinMax.addEventListener("input", eventListener);
|
||||
filterDiv.appendChild(sinMax);
|
||||
|
||||
let rate = createFilterSlider("Rate", item, filterDiv);
|
||||
|
||||
return { filterDiv, min: sinMin, max: sinMax, rate: rate};
|
||||
}
|
||||
|
||||
function createFilterSlider(name, item, filterDiv) {
|
||||
let minTitle = document.createElement("p");
|
||||
minTitle.innerText = name + ":" + item.defaultValue;
|
||||
filterDiv.appendChild(minTitle);
|
||||
|
||||
let sinMin = document.createElement("input");
|
||||
sinMin.type = "range";
|
||||
sinMin.id = "el-filter-" + item.property;
|
||||
sinMin.min = item.min;
|
||||
sinMin.max = item.max;
|
||||
sinMin.value = item.defaultValue;
|
||||
|
||||
eventListener = (event) => {
|
||||
const newValue = parseInt(event.target.value, 10);
|
||||
// instance[item.property] = newValue;
|
||||
minTitle.innerText = name + ": " + newValue;
|
||||
|
||||
if (item.callback) {
|
||||
item.callback(instance, newValue);
|
||||
}
|
||||
};
|
||||
|
||||
sinMin.addEventListener("input", eventListener);
|
||||
filterDiv.appendChild(sinMin);
|
||||
return sinMin;
|
||||
}
|
||||
|
||||
function updateControlInput(value, controlName) {// Find and update the slider element
|
||||
|
||||
@@ -21,6 +21,7 @@ let drawObj = null;
|
||||
function createInstance(className, args) {
|
||||
const classMap = {
|
||||
NewWave: NewWave,
|
||||
Countdown: Countdown,
|
||||
RaysInShape: RaysInShape,
|
||||
PolyTwistColourWidth: PolyTwistColourWidth,
|
||||
FloralPhyllo: FloralPhyllo,
|
||||
@@ -88,9 +89,9 @@ function render(timestamp) {
|
||||
|
||||
}
|
||||
|
||||
ctx.font = "48px serif";
|
||||
ctx.fillStyle = "white"
|
||||
ctx.fillText(Math.floor(elapsedTime) + "ms", centerX - 100, centerY + 400);
|
||||
// ctx.font = "48px serif";
|
||||
// ctx.fillStyle = "white"
|
||||
// ctx.fillText(Math.floor(elapsedTime) + "ms", centerX - 100, centerY + 400);
|
||||
// drawCenter(300)
|
||||
|
||||
requestAnimationFrame(render);
|
||||
|
||||
@@ -6,8 +6,39 @@ class BaseShape {
|
||||
|
||||
initialise(config) {
|
||||
for (let item of config) {
|
||||
const { element, listener } = addControl(item, this);
|
||||
this.controls.push({ element, listener });
|
||||
const { element, listener, filtersDiv } = addControl(item, this);
|
||||
this.controls.push({ element, listener, });
|
||||
|
||||
if (item.type === "range" && item.property !== "rays") {
|
||||
// Initialize rangeFilter array for this control
|
||||
const controlIndex = this.controls.length - 1;
|
||||
this.controls[controlIndex].rangeFilters = [];
|
||||
|
||||
let addFilterButton = document.createElement("button");
|
||||
addFilterButton.innerText = "Add Filter";
|
||||
addFilterButton.className = "add-filter-button";
|
||||
|
||||
// Store the control index in the click handler closure
|
||||
addFilterButton.addEventListener("click", () => {
|
||||
const { filterDiv, eventListener, min, max, rate } = createFilter(item);
|
||||
filtersDiv.appendChild(filterDiv);
|
||||
|
||||
// Use the stored control index
|
||||
if (this.controls[controlIndex] && this.controls[controlIndex].rangeFilters) {
|
||||
this.controls[controlIndex].rangeFilters.push({
|
||||
element: filterDiv,
|
||||
listener: eventListener,
|
||||
min: min,
|
||||
max: max,
|
||||
rate: rate,
|
||||
});
|
||||
} else {
|
||||
console.error("Control or rangeFilters not found for index:", controlIndex);
|
||||
}
|
||||
});
|
||||
|
||||
filtersDiv.appendChild(addFilterButton);
|
||||
}
|
||||
}
|
||||
|
||||
const { element, listener } = addControl({ type: "range", min: 1, max: 500, defaultValue: 100, property: "speedMultiplier" }, this);
|
||||
@@ -24,17 +55,57 @@ class BaseShape {
|
||||
else {
|
||||
console.log("Element or listener not found for removal:", element, listener);
|
||||
}
|
||||
if (element && element.parentElement) {
|
||||
element.parentElement.removeChild(element);
|
||||
const titleElement = document.getElementById("elText" + element.id.slice(2));
|
||||
if (titleElement) {
|
||||
titleElement.parentElement.removeChild(titleElement);
|
||||
|
||||
// Find and remove the container div instead of individual elements
|
||||
if (element && element.id) {
|
||||
// Handle header elements which don't have container
|
||||
if (element.className === "header") {
|
||||
if (element.parentElement) {
|
||||
element.parentElement.removeChild(element);
|
||||
}
|
||||
} else {
|
||||
// For regular controls, find and remove the container
|
||||
const containerDiv = element.closest(".control-container");
|
||||
if (containerDiv && containerDiv.parentElement) {
|
||||
containerDiv.parentElement.removeChild(containerDiv);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
this.controls = [];
|
||||
}
|
||||
|
||||
updateFilters(elapsed) {
|
||||
for (let i = 0; i < this.controls.length; i++) {
|
||||
const control = this.controls[i];
|
||||
|
||||
if (control.rangeFilters?.length > 0) {
|
||||
let newValue = 0;
|
||||
for (let j = 0; j < control.rangeFilters.length; j++) {
|
||||
const filter = control.rangeFilters[j];
|
||||
// const value = parseFloat(filter.element.value);
|
||||
const min = parseFloat(filter.min.value);
|
||||
const max = parseFloat(filter.max.value);
|
||||
const rate = parseFloat(filter.rate.value);
|
||||
|
||||
const halfRange = (max - min) / 2;
|
||||
const filterValue = min + halfRange + Math.sin(elapsed * (1 / rate)) * halfRange; // Calculate the new value based on the range
|
||||
|
||||
if (filterValue >= min && filterValue <= max) {
|
||||
// console.log(newValue, min, max)
|
||||
newValue += filterValue;
|
||||
console.log("New Value:", newValue, filterValue, min, max);
|
||||
}
|
||||
}
|
||||
|
||||
control.element.value = newValue;
|
||||
const event = new Event('input', { bubbles: true });
|
||||
control.element.dispatchEvent(event);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
draw() {
|
||||
throw new Error("Draw function not implemented");
|
||||
}
|
||||
@@ -653,6 +724,7 @@ class NewWave extends BaseShape {
|
||||
|
||||
draw(rotation) {
|
||||
rotation *= this.speedMultiplier / 400
|
||||
this.updateFilters(rotation);
|
||||
ctx.lineWidth = this.lineWidth
|
||||
for (let j = 0; j < this.sides; j++) {
|
||||
const radRotation = rad(360 / this.sides * j)
|
||||
@@ -679,6 +751,60 @@ class NewWave extends BaseShape {
|
||||
}
|
||||
}
|
||||
|
||||
class Countdown extends BaseShape {
|
||||
constructor() {
|
||||
super();
|
||||
this.width;
|
||||
this.sides;
|
||||
}
|
||||
|
||||
secondsUntilDate(targetDate) {
|
||||
const now = new Date();
|
||||
const target = new Date(targetDate);
|
||||
const difference = target.getTime() - now.getTime();
|
||||
return Math.round(difference / 1000);
|
||||
}
|
||||
|
||||
drawProgressBar(progress, barWidth) {
|
||||
const colourBackground = "#0c2f69";
|
||||
const colourProgress = "#4287f5";
|
||||
// const barWidth = 400;
|
||||
const barHeight = 60;
|
||||
const barX = centerX - barWidth / 2;
|
||||
const barY = centerY + 350 - barHeight / 2;
|
||||
|
||||
ctx.fillStyle = colourBackground;
|
||||
ctx.beginPath();
|
||||
ctx.rect(barX, barY, barWidth, 60)
|
||||
ctx.fill();
|
||||
|
||||
ctx.fillStyle = colourProgress;
|
||||
ctx.beginPath();
|
||||
ctx.rect(barX, barY, (barWidth/100)*progress, 60)
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
draw(elapsedTime) {
|
||||
// elapsedTime *= this.speedMultiplier / 400
|
||||
|
||||
ctx.font = "48px serif";
|
||||
ctx.fillStyle = "white"
|
||||
const futureDate = '2025-05-31T08:20:00';
|
||||
const seconds = this.secondsUntilDate(futureDate);
|
||||
const minutes = Math.floor(seconds / 60);
|
||||
const hours = Math.floor(seconds / 3600);
|
||||
const percentRounded = (((elapsedTime / 1000) / seconds) * 100 ).toFixed(8);
|
||||
ctx.fillText(seconds + " Seconds", centerX - 100, centerY);
|
||||
ctx.fillText(minutes + " Minues", centerX - 100, centerY + 100);
|
||||
ctx.fillText(hours + " Hours", centerX - 100, centerY + 200);
|
||||
ctx.fillText(percentRounded + "% Closer", centerX - 100, centerY + 300);
|
||||
|
||||
// ctx.fillText(percentRounded + "% Closer", centerX - 100, centerY + 300);
|
||||
// this.drawProgressBar(percentRounded,400);
|
||||
this.drawProgressBar(percentRounded,1000);
|
||||
}
|
||||
}
|
||||
|
||||
class RaysInShape extends BaseShape {
|
||||
constructor(rays, speed, doesWave, speedVertRate, speedHorrRate, speedVert, speedHorr, boxSize, trailLength = 50, lineWidth, fade, colourFree, colourContained, boxVisible,) {
|
||||
super();
|
||||
@@ -702,9 +828,39 @@ class RaysInShape extends BaseShape {
|
||||
|
||||
initialise(config) { //is overide
|
||||
for (let item of config) {
|
||||
const { element, listener } = addControl(item, this);
|
||||
this.controls.push({ element, listener });
|
||||
const { element, listener, filtersDiv } = addControl(item, this);
|
||||
this.controls.push({ element, listener, });
|
||||
|
||||
if (item.type === "range" && item.property !== "rays") {
|
||||
// Initialize rangeFilter array for this control
|
||||
const controlIndex = this.controls.length - 1;
|
||||
this.controls[controlIndex].rangeFilters = [];
|
||||
|
||||
let addFilterButton = document.createElement("button");
|
||||
addFilterButton.innerText = "Add Filter";
|
||||
addFilterButton.className = "add-filter-button";
|
||||
|
||||
// Store the control index in the click handler closure
|
||||
addFilterButton.addEventListener("click", () => {
|
||||
const { filterDiv, eventListener, min, max, rate } = createFilter(item);
|
||||
filtersDiv.appendChild(filterDiv);
|
||||
|
||||
// Use the stored control index
|
||||
if (this.controls[controlIndex] && this.controls[controlIndex].rangeFilters) {
|
||||
this.controls[controlIndex].rangeFilters.push({
|
||||
element: filterDiv,
|
||||
listener: eventListener,
|
||||
min: min,
|
||||
max: max,
|
||||
rate: rate,
|
||||
});
|
||||
} else {
|
||||
console.error("Control or rangeFilters not found for index:", controlIndex);
|
||||
}
|
||||
});
|
||||
|
||||
filtersDiv.appendChild(addFilterButton);
|
||||
}
|
||||
}
|
||||
|
||||
// Add controls for speed multiplier and trail length
|
||||
@@ -841,9 +997,13 @@ class RaysInShape extends BaseShape {
|
||||
this.prepareRayObjects(); // Reinitialize rayObjects with the new number of rays
|
||||
}
|
||||
|
||||
|
||||
|
||||
draw(elapsed, deltaTime) {
|
||||
deltaTime *= this.speedMultiplier / 100;
|
||||
|
||||
this.updateFilters(elapsed);
|
||||
|
||||
if (this.doesWave) {
|
||||
const vertRate = this.speedVertRate / 100;
|
||||
const horrRate = this.speedHorrRate / 100;
|
||||
|
||||
Reference in New Issue
Block a user