This commit is contained in:
2026-03-13 12:20:05 +10:00
parent c3a72893c3
commit 52b800df5c
3 changed files with 121 additions and 18 deletions

View File

@@ -20,18 +20,23 @@ document.addEventListener("DOMContentLoaded", function () {
updateAnimationControllsDisplay();
enableAnimCheckbox.addEventListener("change", updateAnimationControllsDisplay);
animAlongPathCheckbox.addEventListener("change", updateAnimationControllsDisplay);
startAnimButton.addEventListener("click", () => {
runAnimation(setting)
animRouter(setting)
})
})
const updateAnimationControllsDisplay = () => {
let isChecked = enableAnimCheckbox.checked;
let isPathAnim = animAlongPathCheckbox.checked;
// console.log(isChecked);
document.querySelectorAll(".anim-related").forEach((elem) => { elem.hidden = !isChecked });
document.querySelectorAll(".anim-related-inverse").forEach((elem) => { elem.hidden = isChecked });
document.querySelectorAll(".path-anim-related").forEach((elem) => { elem.hidden = !(isPathAnim && isChecked) });
document.querySelectorAll(".path-anim-related-inverse").forEach((elem) => { elem.hidden = (isPathAnim && isChecked) });
}
@@ -47,8 +52,23 @@ const draw = (dataForm) => {
}
const animRouter = (dataForm) => {
if (dataForm.animAlongPathCheckbox.checked) {
let path = drawPath(Number(dataForm.pathSelect.value));
const svg = d3.select("svg")
let pict = drawSmile(svg);
pict.transition()
.ease([d3.easeLinear, d3.easeElastic, d3.easeBounce][Number(animTypeSelect.value)])
.duration(6000)
.attrTween('transform', translateAlong(path.node()));
}
else {
runAnimation(dataForm)
}
}
const runAnimation = (dataForm) => {
const svg = d3.select("svg")
const svg = d3.select("svg")
let pict = drawSmile(svg);
pict.attr("transform", `
translate(${dataForm.cx.value},
@@ -56,10 +76,10 @@ const runAnimation = (dataForm) => {
scale(${dataForm.sx.value},
${dataForm.sy.value})
rotate(${dataForm.r.value})`)
.transition()
.duration(6000)
.ease([d3.easeLinear,d3.easeElastic, d3.easeBounce][Number(animTypeSelect.value)])
.attr("transform", `
.transition()
.duration(6000)
.ease([d3.easeLinear, d3.easeElastic, d3.easeBounce][Number(animTypeSelect.value)])
.attr("transform", `
translate(${dataForm.cx_finish.value},
${dataForm.cy_finish.value})
scale(${dataForm.sx_finish.value},

View File

@@ -0,0 +1,74 @@
/* массив точек пути будет иметь следующий вид:
[
{x: координата, y: координата},
{x: координата, y: координата},
...
]
*/
// создаем массив точек, расположенных буквой "Г"
function createPathG() {
const svg = d3.select("svg")
const width = svg.attr("width")
const height = svg.attr("height")
let data = [];
const padding = 100;
//начальное положение рисунка
let posX = padding;
let posY = height - padding;
const h = 5;
// координаты y - уменьшаются, x - постоянны
while (posY > padding) {
data.push( {x: posX, y: posY});
posY -= h;
}
// координаты y - постоянны, x - увеличиваются
while (posX < width - padding) {
data.push( {x: posX, y: posY});
posX += h;
}
return data
}
// создаем массив точек, расположенных по кругу
function createPathCircle() {
const svg = d3.select("svg")
const width = svg.attr("width")
const height = svg.attr("height")
let data = [];
// используем параметрическую форму описания круга
// центр расположен в центре svg-элемента, а радиус равен трети высоты/ширины
for (let t = 0 ; t <= Math.PI * 2; t += 0.1) {
data.push(
{x: width / 2 + width / 3 * Math.sin(t),
y: height / 2 + height / 3 * Math.cos(t)}
);
}
return data
}
const drawPath =(typePath) => {
// создаем массив точек
const dataPoints = (typePath == 0)? createPathG() : createPathCircle();
const line = d3.line()
.x((d) => d.x)
.y((d) => d.y);
const svg = d3.select("svg")
// создаем путь на основе массива точек
const path = svg.append('path')
.attr('d', line(dataPoints))
.attr('stroke', 'black')
.attr('fill', 'none');
return path;
}
function translateAlong(path) {
const length = path.getTotalLength();
return function() {
return function(t) {
const {x, y} = path.getPointAtLength(t * length);
return `translate(${x},${y})`;
}
}
}