Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- function spline (points, delta, isLooped = true) {
- let p0, p1, p2, p3
- if (! isLooped) {
- p0 = Math.floor(delta)
- p1 = p0 + 1
- p2 = p1 + 1
- p3 = p2 + 1
- } else {
- p1 = Math.floor( delta )
- p2 = (p1 + 1) % points.length
- p3 = (p2 + 1) % points.length
- p0 = p1 >= 1 ? p1 - 1 : points.length - 1
- }
- delta = delta - Math.floor( delta )
- let delta_X2 = delta ** 2
- let delta_X3 = delta_X2 * delta
- let q1 = -delta_X3 + 2*delta_X2 - delta
- let q2 = 3*delta_X3 - 5*delta_X2 + 2
- let q3 = -3*delta_X3 + 4*delta_X2 + delta
- let q4 = delta_X3 - delta_X2
- let x = 0.5 * ((points[ p0 ].x * q1) + (points[ p1 ].x * q2) + (points[ p2 ].x * q3) + (points[ p3 ].x * q4))
- let y = 0.5 * ((points[ p0 ].y * q1) + (points[ p1 ].y * q2) + (points[ p2 ].y * q3) + (points[ p3 ].y * q4))
- return {x,y}
- }
- function setupCanvas(canvas) {
- // Get the device pixel ratio, falling back to 1.
- let dpr = window.devicePixelRatio || 1;
- // Get the size of the canvas in CSS pixels.
- let rect = canvas.getBoundingClientRect();
- // Give the canvas pixel dimensions of their CSS
- // size * the device pixel ratio.
- canvas.width = rect.width * dpr;
- canvas.height = rect.height * dpr;
- let ctx = canvas.getContext('2d');
- // Scale all drawing operations by the dpr, so you
- // don't have to worry about the difference.
- ctx.scale(dpr, dpr);
- return ctx;
- }
- function path() {
- for (let i=0; i < points.length; i+= 1/255) {
- let {x, y} = spline(points, i)
- draw(x,y, "#3d3d3d", 2 )
- }
- }
- function clean() {
- ctx.clearRect(0, 0, canvas.width, canvas.height);
- points.forEach( (point, index) => {
- draw(point.x,point.y)
- })
- }
- function reset() {
- points = []
- clean()
- }
- let canvas = document.getElementById("myCanvas");
- let ctx = setupCanvas(canvas)
- let points = []
- canvas.addEventListener("click", eventData => {
- let rect = canvas.getBoundingClientRect()
- let x = event.clientX - rect.left
- let y = event.clientY - rect.top
- points.push({x,y})
- clean()
- path()
- //callc()
- })
- let total = 0
- function callc () {
- total = 0
- for (let i = 0; i < points.length; i++) {
- let currentP = points[i]
- let nextP = points[(i+1)%points.length]
- let oldp = currentP
- currentP.length = 0
- for (let t = 0; t < 1; t += 1/ 2500) {
- let newp = spline(points, i + t)
- currentP.length += Math.sqrt(
- (newp.x - oldp.x) **2 +
- (newp.y - oldp.y) **2
- )
- oldp = newp
- }
- currentP.length += Math.sqrt(
- (nextP.x - oldp.x) **2 +
- (nextP.y - oldp.y) **2
- )
- total += currentP.length
- }
- document.getElementById("lenn").innerHTML = total
- }
- let mark = 0
- function markk() {
- mark = Number(document.getElementById("slider").value)
- let {x, y} = spline(points, mark)
- clean()
- draw(x,y, "#017db1", 2 )
- }
- function play() {
- calls.push((dt) => {
- document.getElementById("lenn").innerHTML = dt
- let t = 0
- let m = mark
- while (m > points[t].length) {
- m -= points[t].length
- t++
- }
- let tt = t + (m / points[t].length)
- let {x, y} = spline(points, tt * dt)
- //clean()
- draw(x,y, "#017db1", 2 )
- document.getElementById("slider").value = mark
- mark = (mark + 0.5) % total
- if(mark >= total) {
- clean()
- path()
- calls.pop()}
- })
- }
- let calls = []
- let last = new Date().getTime()
- setInterval(function() {
- let now = new Date().getTime()
- dt = (now - last) / 50
- last = now
- document.getElementById("point").textContent = points.length
- document.getElementById("slider").max = points.length
- calls.forEach(i => i(dt))
- }, 50)
Add Comment
Please, Sign In to add comment