| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 | <template>    <view>        <page-head :title="title"></page-head>        <view class="page-body">            <view class="page-body-wrapper">                <!-- #ifdef APP-PLUS || H5 -->                <canvas canvas-id="canvas" class="canvas" :start="startStatus" :change:start="animate.start"                    :data-width="canvasWidth" :data-height="canvasWidth"></canvas>                <!-- #endif -->                <!-- #ifndef APP-PLUS || H5 -->                <canvas canvas-id="canvas" id="canvas" class="canvas"></canvas>                <!-- #endif -->            </view>        </view>    </view></template><script module="animate" lang="renderjs">    function Ball({        x,        y,        vx,        vy,        canvasWidth,        canvasHeight,        ctx    }) {        this.canvasWidth = canvasWidth        this.canvasHeight = canvasHeight        this.ctx = ctx        this.x = x        this.y = y        this.vx = vx        this.vy = vy        this.radius = 5    }    Ball.prototype.draw = function() {        this.ctx.beginPath()        this.ctx.fillStyle = '#007AFF'        this.ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI)        this.ctx.closePath()        this.ctx.fill()    }    Ball.prototype.move = function() {        this.x += this.vx        this.y += this.vy        // 回到中心        // if (getDistance(this.x - this.canvasWidth / 2, this.y - this.canvasHeight / 2) >        // 	getDistance(this.canvasWidth / 2, this.canvasHeight / 2) + this.radius) {        // 	this.x = this.canvasWidth / 2        // 	this.y = this.canvasHeight / 2        // }        // 边框反弹        if (this.x < this.radius) {            this.vx = Math.abs(this.vx)            return        }        if (this.x > this.canvasWidth - this.radius) {            this.vx = -Math.abs(this.vx)        }        if (this.y < this.radius) {            this.vy = Math.abs(this.vy)            return        }        if (this.y > this.canvasWidth - this.radius) {            this.vy = -Math.abs(this.vy)        }    }    function getDistance(x, y) {        return Math.pow(Math.pow(x, 2) + Math.pow(y, 2), 0.5)    }    export default {        methods: {            start(newVal, oldVal, owner, ins) {                let canvasWidth = ins.getDataset().width,                    canvasHeight = ins.getDataset().height,                    canvasEle = document.querySelectorAll('.canvas>canvas')[0],                    ctx = canvasEle.getContext('2d'),                    speed = 3,                    ballList = [],                    layer = 3,                    ballInlayer = 20                for (let i = 0; i < layer; i++) {                    let radius = getDistance(canvasWidth / 2, canvasHeight / 2) / layer * i                    for (let j = 0; j < ballInlayer; j++) {                        let deg = j * 2 * Math.PI / ballInlayer,                            sin = Math.sin(deg),                            cos = Math.cos(deg),                            x = radius * cos + canvasWidth / 2,                            y = radius * sin + canvasHeight / 2,                            vx = speed * cos,                            vy = speed * sin                        ballList.push(new Ball({                            x,                            y,                            vx,                            vy,                            canvasWidth,                            canvasHeight,                            ctx,                            radius: 5                        }))                    }                }                function animate(ballList) {                    ctx.clearRect(0, 0, canvasEle.width, canvasEle.height)                    ballList.forEach(function(item) {                        item.move()                        item.draw()                    })                    requestAnimationFrame(function() {                        animate(ballList)                    })                }                animate(ballList)            }        }    }</script><script>    // #ifndef APP-PLUS || H5    let ctx = null,        interval = null;    function Ball(x, y, vx, vy, canvasWidth, canvasHeight, ctx) {        this.canvasWidth = canvasWidth        this.canvasHeight = canvasHeight        this.ctx = ctx        this.x = x        this.y = y        this.vx = vx        this.vy = vy        this.radius = 5    }    Ball.prototype.draw = function() {        this.ctx.setFillStyle('#007AFF')        this.ctx.beginPath()        this.ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI)        this.ctx.closePath()        this.ctx.fill()    }    Ball.prototype.move = function() {        this.x += this.vx        this.y += this.vy        // 回到中心        // if (getDistance(this.x - this.canvasWidth / 2, this.y - this.canvasHeight / 2) >        // 	getDistance(this.canvasWidth / 2, this.canvasHeight / 2) + this.radius) {        // 	this.x = this.canvasWidth / 2        // 	this.y = this.canvasHeight / 2        // }        // 边框反弹        if (this.x < this.radius) {            this.vx = Math.abs(this.vx)            return        }        if (this.x > this.canvasWidth - this.radius) {            this.vx = -Math.abs(this.vx)        }        if (this.y < this.radius) {            this.vy = Math.abs(this.vy)            return        }        if (this.y > this.canvasWidth - this.radius) {            this.vy = -Math.abs(this.vy)        }    }    function getDistance(x, y) {        return Math.pow(Math.pow(x, 2) + Math.pow(y, 2), 0.5)    }    // #endif    export default {        data() {            return {                title: 'canvas',                canvasWidth: 0,                startStatus: false,                ballList: []            }        },        onReady: function() {            this.$nextTick(() => {                uni.createSelectorQuery().select(".canvas").boundingClientRect(data => {                    this.canvasWidth = data.width                    // #ifdef APP-PLUS || H5                    this.startStatus = true                    // #endif                    // #ifndef APP-PLUS || H5                    ctx = uni.createCanvasContext('canvas')                    this.drawBall()                    // #endif                }).exec()            })        },        // #ifndef APP-PLUS || H5        onUnload: function() {            clearInterval(interval);        },        methods: {            drawBall: function() {                let canvasWidth = this.canvasWidth,                    canvasHeight = this.canvasWidth,                    speed = 3,                    ballList = [],                    layer = 3,                    ballInlayer = 20                for (let i = 0; i < layer; i++) {                    let radius = getDistance(canvasWidth / 2, canvasHeight / 2) / layer * i                    for (let j = 0; j < ballInlayer; j++) {                        let deg = j * 2 * Math.PI / ballInlayer,                            sin = Math.sin(deg),                            cos = Math.cos(deg),                            x = radius * cos + canvasWidth / 2,                            y = radius * sin + canvasHeight / 2,                            vx = speed * cos,                            vy = speed * sin                        ballList.push(new Ball(x, y, vx, vy, canvasWidth, canvasHeight, ctx))                    }                }                function animate(ballList) {                    // ctx.clearRect(0, 0, canvasWidth, canvasHeight)                    ballList.forEach(function(item) {                        item.move()                        item.draw()                    })                    ctx.draw()                }                interval = setInterval(function() {                    animate(ballList)                }, 17)            }        }        // #endif    }</script><style>    .page-body-wrapper {        text-align: center;    }    .canvas {        width: 610rpx;        height: 610rpx;        margin: auto;        background-color: #fff;    }</style>
 |