Directorio de artículos
Objetivo
Implemente el movimiento en el diagrama.
preparación de código
un lienzo
estructura:
<div id="app">
<div id="rectangle"></div>
</div>
Actuación:
#app {
width: 600px;
height: 600px;
margin: 0 auto;
outline: solid pink 2px;
position: relative;
}
#rectangle {
position: absolute;
width: 100px;
height: 100px;
background-color: red;
}
Efecto:
algunos js
Clase que representa las coordenadas:
function Point2D(x = 0, y = 0) {
this.x = x
this.y = y
}
El estado de la animación:
//目标元素
let element = document.getElementById('rectangle')
//状态
let index = 0
let totalTime = 3000
let direction = true
elemento: El elemento de destino de la animación.
índice: el porcentaje de la animación actual, más o menos 0,01 cada vez. El rango es de cero a uno.
totalTime: el número total de milisegundos para la animación.
dirección: la dirección de movimiento actual.
Bézier de primer orden
Los movimientos de Bezier se pueden observar en este sitio web: https://www.jasondavies.com/animated-bezier/
El primer orden es el movimiento uniforme, las coordenadas de cada cuadro: las
coordenadas del punto inicial más el desplazamiento actual.
function BezierOne(from, to, step) {
let x = from.x + (to.x - from.x) * step
let y = from.y + (to.y - from.y) * step
return new Point2D(x, y)
}
Implementar movimiento de primer orden:
let fromP = new Point2D(0, 0)
let toP = new Point2D(250, 0)
setInterval(() => {
if (index > 1 || index < 0) {
direction = !direction
}
if (direction) {
index += 0.01
} else {
index -= 0.01
}
let point = BezierOne(fromP, toP, index)
element.style.left = point.x + "px"
element.style.top = point.y + "px"
}, 0.01 * totalTime)
Primero determine el límite y cambie la dirección del movimiento.
El índice del siguiente cuadro está determinado por la dirección del movimiento.
Calcular las coordenadas de Bézier. Asignación.
Efecto:
Bézier de segundo orden
Punto inicial A, punto de control B, punto final C.
Calcular el primer orden de AB y el primer orden de BC.
Luego calcule el primer orden a partir de estos dos primeros pedidos. (Matrioska)
function BezierTwo(from, to, control, step) {
let a = BezierOne(from, control, step)
let b = BezierOne(control, to, step)
return BezierOne(a, b, step)
}
Un punto más.
let fromP = new Point2D(0, 0)
let controlP = new Point2D(250, 0)
let toP = new Point2D(250, 500)
Cambiar la llamada a segundo orden:
BezierTwo(fromP, toP, controlP, index)
Efecto:
Bézier de tercer orden
Punto inicial A, punto de control B, punto de control C, punto final D.
Calcule el primer orden de AB, el primer orden de BC y el primer orden de CD.
Luego calcula el segundo orden a partir de estos tres primeros órdenes. (Matrioska)
function BezierThree(from, to, controlA, controlB, step) {
let a = BezierOne(from, controlA, step)
let b = BezierOne(controlA, controlB, step)
let c = BezierOne(controlB, to, step)
return BezierTwo(a, c, b, step)
}
Un punto más:
let fromP = new Point2D(0, 0)
let controlA = new Point2D(250, 0)
let controlB = new Point2D(250, 500)
let toP = new Point2D(0, 0)
Se cambia la llamada a tercer orden:
BezierThree(fromP, toP, controlA, controlB, index)
Efecto:
Bézier de cuarto orden
Punto inicial A, punto de control B, punto de control C, punto de control D, punto final E.
Calcule el primer orden de AB, el primer orden de BC, el primer orden de CD y el primer orden de DE.
Luego calcula el tercer orden de estos cuatro primeros órdenes. (Matrioska)
function BezierFour(from, to, controlA, controlB, controlC, step) {
let a = BezierOne(from, controlA, step)
let b = BezierOne(controlA, controlB, step)
let c = BezierOne(controlB, controlC, step)
let d = BezierOne(controlC, to, step)
return BezierThree(a, d, b, c, step)
}
Un punto más:
let fromP = new Point2D(0, 0)
let controlA = new Point2D(250, 0)
let controlB = new Point2D(250, 500)
let controlC = new Point2D(0, 0)
let toP = new Point2D(0, 500)
Se cambia la llamada a cuarto orden:
BezierFour(fromP, toP, controlA, controlB, controlC, index)
Efecto:
más orden bezier
Nadie realmente lo usa.
function BezierN(arr, step) {
if (arr.length === 2) {
return BezierOne(arr[0], arr[1], step)
} else {
let arr2 = []
for (let i = 0; i < arr.length - 1; i++) {
arr2.push(BezierOne(arr[i], arr[i + 1], step))
}
return BezierN(arr2, step)
}
}
Mira el cuarto orden, ¿verdad?
let point = BezierN([fromP, controlA, controlB, controlC, toP], index)
Efecto:
todo el código
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
#app {
width: 600px;
height: 600px;
margin: 0 auto;
outline: solid pink 2px;
position: relative;
}
#rectangle {
position: absolute;
width: 100px;
height: 100px;
background-color: red;
}
</style>
</head>
<body>
<div id="app">
<div id="rectangle"></div>
</div>
<script>
//目标元素
let element = document.getElementById('rectangle')
//状态
let index = 0
let totalTime = 3000
let direction = true
//起点,终点
let fromP = new Point2D(0, 0)
let controlA = new Point2D(250, 0)
let controlB = new Point2D(250, 500)
let controlC = new Point2D(0, 0)
let toP = new Point2D(0, 500)
setInterval(() => {
if (index > 1 || index < 0) {
direction = !direction
}
if (direction) {
index += 0.01
} else {
index -= 0.01
}
let point = BezierN([fromP, controlA, controlB, controlC, toP], index)
element.style.left = point.x + "px"
element.style.top = point.y + "px"
}, 0.01 * totalTime)
function Point2D(x = 0, y = 0) {
this.x = x
this.y = y
}
function BezierOne(from, to, step) {
let x = from.x + (to.x - from.x) * step
let y = from.y + (to.y - from.y) * step
return new Point2D(x, y)
}
function BezierTwo(from, to, control, step) {
let a = BezierOne(from, control, step)
let b = BezierOne(control, to, step)
return BezierOne(a, b, step)
}
function BezierThree(from, to, controlA, controlB, step) {
let a = BezierOne(from, controlA, step)
let b = BezierOne(controlA, controlB, step)
let c = BezierOne(controlB, to, step)
return BezierTwo(a, c, b, step)
}
function BezierFour(from, to, controlA, controlB, controlC, step) {
let a = BezierOne(from, controlA, step)
let b = BezierOne(controlA, controlB, step)
let c = BezierOne(controlB, controlC, step)
let d = BezierOne(controlC, to, step)
return BezierThree(a, d, b, c, step)
}
function BezierN(arr, step) {
if (arr.length === 2) {
return BezierOne(arr[0], arr[1], step)
} else {
let arr2 = []
for (let i = 0; i < arr.length - 1; i++) {
arr2.push(BezierOne(arr[i], arr[i + 1], step))
}
return BezierN(arr2, step)
}
}
</script>
</body>
</html>