B
B
Bersonazh2020-09-01 09:34:31
JavaScript
Bersonazh, 2020-09-01 09:34:31

Can anyone help me to catch the animation error?

Good afternoon! New to canvas. Based on a huge pile of examples, I'm trying to mold pictures by pixels using "shooting stars" into point coordinates. Actually, the problem, at the moment, is in the call to requestAnimationFrame. I call one for the animation of the fall of the star, and so I believe that it is necessary to call the second one, so that there are as many of these stars as there are pixels. I ask those who know to help figure out what the error is, I have been sitting in one place for more than a day.

Demo

Mount Function:

animate: function () {

            if (this.dataToDraw && this.dataToDraw[this.iterator]) {
                let xStart = this.dataToDraw[this.iterator].xStart
                let xFinish = this.dataToDraw[this.iterator].xFinish
                let yStart = this.dataToDraw[this.iterator].yStart
                let yFinish = this.dataToDraw[this.iterator].yFinish


                const drawStroke = () => {

                    xStart = xStart + (xFinish - xStart) * (this.iterator / 2)
                    yStart = yStart + (yFinish - yStart) * (this.iterator / 2)

                    let x2 = xStart + (xFinish - xStart) * ((this.iterator / 2) + 250)
                    let y2 = yStart + (yFinish - yStart) * ((this.iterator / 2) + 250)

                    const rab = Math.sqrt(Math.pow((x2 - xStart), 2) + Math.pow((y2 - yStart), 2))

                    const gradient = ctx.createLinearGradient(xStart, yStart, x2, y2)
                    gradient.addColorStop(1, this.dataToDraw[this.iterator].rgbaStart)
                    gradient.addColorStop(0, this.dataToDraw[this.iterator].rgbaStop)

                    ctx.strokeStyle = gradient

                    if (rab < 1) return
                    else {

                        ctx.clearRect(0, 0, width, height)
                        ctx.beginPath()
                        // ctx.strokeText('.', xFinish, yFinish)
                        ctx.moveTo(xStart, yStart);
                        ctx.lineTo(x2, y2);
                        ctx.closePath()
                        ctx.stroke();
                    }

                    requestAnimationFrame(drawStroke)

                }

                drawStroke()
            }

            this.iterator++

            requestAnimationFrame(this.animate)

        }


Whole snippet:
spoiler

const canvas = document.querySelector('canvas')
    const ctx = canvas.getContext('2d')

    const height = window.innerHeight
    const width = window.innerWidth

    function Builder() {
        this.dataToDraw = []
        this.radius = Math.sqrt(canvas.width * canvas.width + canvas.height * canvas.height) / 2
        this.iterator = 0
        this.init()
    }


    Builder.prototype = {
        init: function () {
            this.imageObj = new Image();
            this.imageObj.src = ' data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAkCAYAAAAHKVPcAAACd0lEQVRYhe2Xv2+jMBzF+/8ztRtbthxLMyBQGeqhXBQhobtESQcYggQZQpUqREIIwfBuSOGMsY2h6Kaz5CU/7I+f3/fZfsA3m6UZbZ/aHtgPwvUB7+S38gBb24OlGXh//TUPxCVO21Wdw5PSAEWWg+jmZIAeRF1WILoJSzNwS69KAzRKFFk+D0TTiiyHv3IH/1xkeatcso/mhQCAZB9hZ3uoy6o3ceQH2Nleq5qlGdja3vwQAPC2eAHRTVziFHVZYfclPa87T89IDtH8EMk+6kwiAqA70U1lPylB1GWlNDFPlTEgUggAnX0f092FMw8EvR1TumrFSCHchdMb+OgHKLIcdVkh2UdwHsVeUVVDCMHzAy9FiyyXgqh4QwhBR3jjehqQzo+tpHRV4l8aVvRgmyX5u/Kvcr3EKYD7oSeCCNeH+SCcp2cAXYUa4/krVwjhr372UlcZgt0OelVHP8DRD4S/4+WGTJFRxrQ0Azvbw2f8gc/4A+H6oJykTbXwVJGW6GZJvpUTqmkqhVCRWtSJbqLIcq5piW52FBmMbZnpVFd8S694W7z0DKsMMfXsYEHqsuqBNCUuhbilV4beRbg+9LyytT2cwxMucdpLTxnI5gcZhmD3syFnFaIPKvqeSlcFvTAadBCCXjF7o6a9wl7t2IlY0Ob75pkghaAzgJ2IVol35WcrS3aiSiHoQdjEYyfhHVTsdoqeBcoQvElY07KN9YcouicrAaBXcryVnsPTvUoexfdOuScoc/Hemkc/GAQF7kaUvdCkEHQF8MxXl1UHdOqbdNTZwTsBWfONfXMMQgB3yTdLIrym1WXV5onK+3USxL9o/yGa9gf+5N60Efba5wAAAABJRU5ErkJggg=='
            const imageWidth = this.imageObj.width;
            const imageHeight = this.imageObj.height;

            if (imageWidth > 0) this.drawImage(imageWidth, imageHeight)
            else setTimeout(() => this.init())

        },
        drawImage: function (imageWidth, imageHeight) {

            canvas.height = window.innerHeight
            canvas.width = window.innerWidth

            this.imageXOffset = canvas.width / 2 - this.imageObj.width / 2
            this.imageYOffset = canvas.height / 2 - this.imageObj.height / 2


            ctx.drawImage(this.imageObj, this.imageXOffset, this.imageYOffset);

            const imageData = ctx.getImageData(this.imageXOffset, this.imageYOffset, imageWidth, imageHeight);
            const data = imageData.data;

            ctx.clearRect(0, 0, canvas.width, canvas.height)

            for (let yFinish = 0; yFinish < imageHeight; yFinish++) {
                for (let xFinish = 0; xFinish < imageWidth; xFinish++) {
                    let r = data[((imageWidth * yFinish) + xFinish) * 4];
                    let g = data[((imageWidth * yFinish) + xFinish) * 4 + 1];
                    let b = data[((imageWidth * yFinish) + xFinish) * 4 + 2];

                    if (r !== 0) {
                        let angle = Math.ceil(Math.random() * 360) * (Math.PI / 180)
                        let xStart = Math.sin(angle * this.radius) * canvas.width * 5
                        let yStart = Math.cos(angle * this.radius) * canvas.height * 5
                        this.dataToDraw.push({
                            xStart,
                            yStart,
                            rgbaStart: 'rgba(' + r + ',' + g + ',' + b + ', 1)',
                            xFinish: xFinish + this.imageXOffset,
                            yFinish: yFinish + this.imageYOffset,
                            rgbaStop: 'rgba(' + r + ',' + g + ',' + b + ', 0)',
                        })
                    }
                }
            }
            this.animate()
        },
        animate: function () {

            if (this.dataToDraw && this.dataToDraw[this.iterator]) {
                let xStart = this.dataToDraw[this.iterator].xStart
                let xFinish = this.dataToDraw[this.iterator].xFinish
                let yStart = this.dataToDraw[this.iterator].yStart
                let yFinish = this.dataToDraw[this.iterator].yFinish


                const drawStroke = () => {

                    xStart = xStart + (xFinish - xStart) * (this.iterator / 2)
                    yStart = yStart + (yFinish - yStart) * (this.iterator / 2)

                    let x2 = xStart + (xFinish - xStart) * ((this.iterator / 2) + 250)
                    let y2 = yStart + (yFinish - yStart) * ((this.iterator / 2) + 250)

                    const rab = Math.sqrt(Math.pow((x2 - xStart), 2) + Math.pow((y2 - yStart), 2))

                    const gradient = ctx.createLinearGradient(xStart, yStart, x2, y2)
                    gradient.addColorStop(1, this.dataToDraw[this.iterator].rgbaStart)
                    gradient.addColorStop(0, this.dataToDraw[this.iterator].rgbaStop)

                    ctx.strokeStyle = gradient

                    if (rab < 1) return
                    else {

                        ctx.clearRect(0, 0, width, height)
                        ctx.beginPath()
                        // ctx.strokeText('.', xFinish, yFinish)
                        ctx.moveTo(xStart, yStart);
                        ctx.lineTo(x2, y2);
                        ctx.closePath()
                        ctx.stroke();
                    }

                    requestAnimationFrame(drawStroke)

                }

                drawStroke()
            }

            this.iterator++

            requestAnimationFrame(this.animate)

        }
    }

    new Builder()

Answer the question

In order to leave comments, you need to log in

1 answer(s)
T
twobomb, 2020-09-01
@Bersonazh

If I understand correctly, it should be something like this

PS You can adjust the speed through this.animationStep and this.iteratorStep

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question