提交 973abaaa 编写于 作者: H hdx

canvas: 新增 使用浏览器内置 canvas 示例

上级 40eb8f02
...@@ -2,248 +2,42 @@ ...@@ -2,248 +2,42 @@
<view> <view>
<page-head :title="title"></page-head> <page-head :title="title"></page-head>
<view class="page-body"> <view class="page-body">
<!-- #ifdef APP-PLUS || H5 --> <!-- 如何使用浏览器内置 canvas -->
<canvas canvas-id="canvas" class="canvas" :start="startStatus" :change:start="animate.start" <view ref="drawing" class="drawing"></view>
: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> </view>
</template> </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> <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 1
}
// #endif
export default { export default {
data() { data() {
return { return {
title: 'canvas', title: 'Canvas',
canvasWidth: 0, drawing: null as any | null,
startStatus: false, canvasElement: null as any | null,
ballList: [] canvasContext: null as any | null,
} }
}, },
onReady: function () { onReady() {
this.$nextTick(() => { this.drawing = this.$refs['drawing'] as any;
uni.createSelectorQuery().select(".canvas").boundingClientRect(data => { // @ts-ignore
this.canvasWidth = data.width this.canvasElement = document.createElement('canvas')
// #ifdef APP-PLUS || H5 // @ts-ignore
this.startStatus = true this.canvasElement.className = 'canvas'
// #endif this.drawing!.appendChild(this.canvasElement)
// #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) { this.canvasContext = this.canvasElement!.getContext('2d')
ctx.clearRect(0, 0, canvasWidth, canvasHeight) this.canvasContext!.fillRect(100, 50, 100, 50)
ballList.forEach(function (item) {
item.move()
item.draw()
})
ctx.draw()
}
interval = setInterval(function () {
animate(ballList)
}, 17)
}
} }
// #endif
} }
</script> </script>
<style> <style>
.canvas { .drawing >>> .canvas {
width: 610rpx; width: 300px;
height: 610rpx; height: 150px;
background-color: #fff;
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
border: 1px dashed #000;
} }
</style> </style>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册