# 介绍
插件基于Canvas渲染图形,用法简单,极易上手。内置了较为丰富的基础图形,能够极大提升开发效率,在此基础上,你也可以十分容易的扩展新图形。
点击以重新播放。
点击以展开或折叠
<template>
<div class="show-animation">
<canvas class="canvas" ref="canvas" @click="animation" />
</div>
</template>
<script>
import CRender, { GRAPHS, Graph } from '../../../es'
export default {
name: 'ShowAnimation',
data() {
return {
render: null,
playing: false,
fragment1Ring1: null,
fragment1Ring2: null,
fragment1Polyline1: null,
fragment1Polyline2: null,
fragment2Ring1: null,
fragment2Ring2: null,
fragment2Arc1: null,
fragment2Arc2: null,
fragment2Arc3: null,
fragment2Arc4: null,
fragment2Ring12: null,
fragment2Ring22: null,
fragment3Circle1: null,
fragment3Circle2: null,
fragment5Rings: [],
fragment5Text: null,
fragment5Polyline1: null,
color: ['#e86830', '#e83a30', '#e8308c', '#8930e8', '#30c9e8', '#30e8bd', '#e8e230'],
}
},
methods: {
init() {
const { $refs, animation } = this
this.render = new CRender($refs['canvas'])
animation()
},
async animation() {
const { render, playing } = this
if (playing) return
this.playing = true
render.delAllGraph()
await this.fragment1(render)
await this.fragment2(render)
await this.fragment3(render)
await this.fragment4(render)
await this.fragment5(render)
this.playing = false
},
fragment1(render) {
const [w, h] = render.area
const fragment1Ring1 = (this.fragment1Ring1 = new GRAPHS.Ring({
animationCurve: 'easeInOutBack',
shape: {
rx: 0,
ry: h / 2,
r: 6,
},
style: {
stroke: '#eeca54',
lineWidth: 10,
},
}))
const fragment1Ring2 = (this.fragment1Ring2 = new GRAPHS.Ring({
animationCurve: 'easeInOutBack',
shape: {
rx: w,
ry: h / 2,
r: 6,
},
style: {
stroke: '#eeca54',
lineWidth: 10,
},
}))
const fragment1Polyline1 = (this.fragment1Polyline1 = new GRAPHS.Polyline({
animationCurve: 'easeInOutBack',
shape: {
points: [
[-150, h / 2],
[0, h / 2],
],
},
style: {
stroke: '#eeca54',
lineWidth: 1,
},
}))
const fragment1Polyline2 = (this.fragment1Polyline2 = new GRAPHS.Polyline({
animationCurve: 'easeInOutBack',
shape: {
points: [
[w + 150, h / 2],
[w, h / 2],
],
},
style: {
stroke: '#eeca54',
lineWidth: 1,
},
}))
render.add([fragment1Ring1, fragment1Ring2, fragment1Polyline1, fragment1Polyline2])
fragment1Ring1.animation('shape', { rx: w / 2 - 80 }, true)
fragment1Ring2.animation('shape', { rx: w / 2 + 80 }, true)
fragment1Polyline1.animation(
'shape',
{
points: [
[w / 2 - 230, h / 2],
[w / 2 - 80, h / 2],
],
},
true
)
fragment1Polyline2.animation(
'shape',
{
points: [
[w / 2 + 230, h / 2],
[w / 2 + 80, h / 2],
],
},
true
)
return render.launchAnimation()
},
fragment2(render) {
const [w, h] = render.area
this.fragment1Polyline1.animation(
'shape',
{
points: [
[w / 2 - 80, h / 2],
[w / 2 - 80, h / 2],
],
},
true
)
this.fragment1Polyline2.animation(
'shape',
{
points: [
[w / 2 + 80, h / 2],
[w / 2 + 80, h / 2],
],
},
true
)
this.fragment1Ring1.animationFrame = 60
this.fragment1Ring1.animation('shape', { r: 20 }, true)
this.fragment1Ring1.animation(
'style',
{
opacity: 0,
lineWidth: 0.5,
},
true
)
this.fragment1Ring2.animationFrame = 60
this.fragment1Ring2.animation('shape', { r: 20 }, true)
this.fragment1Ring2.animation(
'style',
{
opacity: 0,
lineWidth: 0.5,
},
true
)
const fragment2Ring1 = (this.fragment2Ring1 = new GRAPHS.Ring({
animationCurve: 'easeOutCubic',
animationFrame: 60,
shape: {
rx: w / 2 - 80,
ry: h / 2,
r: 6,
},
style: {
stroke: '#ee66aa',
lineWidth: 1,
},
}))
const fragment2Ring2 = (this.fragment2Ring2 = new GRAPHS.Ring({
animationCurve: 'easeOutCubic',
animationFrame: 60,
shape: {
rx: w / 2 + 80,
ry: h / 2,
r: 6,
},
style: {
stroke: '#ee66aa',
lineWidth: 1,
},
}))
render.add([fragment2Ring1, fragment2Ring2])
fragment2Ring1.animation('shape', { r: 30 }, true)
fragment2Ring1.animation('style', { opacity: 0 }, true)
fragment2Ring2.animation('shape', { r: 30 }, true)
fragment2Ring2.animation('style', { opacity: 0 }, true)
const fragment2Arc1 = (this.fragment2Arc1 = new GRAPHS.Arc({
animationFrame: 90,
animationCurve: 'easeOutCubic',
shape: {
rx: w / 2,
ry: h / 2,
r: 60,
startAngle: -Math.PI,
endAngle: -Math.PI + 0.01,
},
style: {
stroke: '#30c9e8',
lineWidth: 2,
rotate: 0,
},
}))
const fragment2Arc2 = (this.fragment2Arc2 = new GRAPHS.Arc({
animationFrame: 90,
animationCurve: 'easeOutCubic',
shape: {
rx: w / 2,
ry: h / 2,
r: 60,
startAngle: 0,
endAngle: 0.01,
},
style: {
stroke: '#30c9e8',
lineWidth: 2,
rotate: 0,
},
}))
render.add([fragment2Arc1, fragment2Arc2])
const fragment2Arc3 = (this.fragment2Arc3 = new GRAPHS.Arc({
animationFrame: 90,
animationCurve: 'easeOutCubic',
shape: {
rx: w / 2,
ry: h / 2,
r: 100,
startAngle: -Math.PI,
endAngle: -Math.PI + 0.01,
},
style: {
stroke: '#eeca54',
lineWidth: 2,
lineCap: 'round',
rotate: 0,
},
}))
const fragment2Arc4 = (this.fragment2Arc4 = new GRAPHS.Arc({
animationFrame: 90,
animationCurve: 'easeOutCubic',
shape: {
rx: w / 2,
ry: h / 2,
r: 100,
startAngle: 0,
endAngle: 0.01,
},
style: {
stroke: '#eeca54',
lineWidth: 2,
lineCap: 'round',
rotate: 0,
},
}))
render.add([fragment2Arc3, fragment2Arc4])
fragment2Arc1.animation(
'shape',
{
startAngle: -Math.PI,
endAngle: 0,
},
true
)
fragment2Arc2.animation(
'shape',
{
startAngle: 0,
endAngle: Math.PI,
},
true
)
fragment2Arc1.animation('style', { rotate: 360 }, true)
fragment2Arc2.animation('style', { rotate: 360 }, true)
fragment2Arc3.animation(
'shape',
{
startAngle: -Math.PI,
endAngle: 0,
r: 20,
},
true
)
fragment2Arc4.animation(
'shape',
{
startAngle: 0,
endAngle: Math.PI,
r: 20,
},
true
)
fragment2Arc3.animation('style', { rotate: 360 }, true)
fragment2Arc4.animation('style', { rotate: 360 }, true)
return render.launchAnimation()
},
fragment3(render) {
const [w, h] = render.area
const fragment2Ring12 = (this.fragment2Ring12 = new GRAPHS.Ring({
animationCurve: 'easeOutCubic',
animationFrame: 60,
shape: {
rx: w / 2 - 60,
ry: h / 2,
r: 10,
},
style: {
stroke: '#c71f16',
lineWidth: 1,
},
}))
const fragment2Ring22 = (this.fragment2Ring22 = new GRAPHS.Ring({
animationCurve: 'easeOutCubic',
animationFrame: 60,
shape: {
rx: w / 2 + 60,
ry: h / 2,
r: 10,
},
style: {
stroke: '#c71f16',
lineWidth: 1,
},
}))
render.add([fragment2Ring12, fragment2Ring22])
fragment2Ring12.animation('shape', { r: 40 }, true)
fragment2Ring22.animation('shape', { r: 40 }, true)
fragment2Ring12.animation('style', { opacity: 0 }, true)
fragment2Ring22.animation('style', { opacity: 0 }, true)
this.fragment2Arc1.animation('shape', { r: 100 }, true)
this.fragment2Arc2.animation('shape', { r: 100 }, true)
this.fragment2Arc3.animation('shape', { r: 10 }, true)
this.fragment2Arc4.animation('shape', { r: 10 }, true)
this.fragment2Arc1.animation('style', { opacity: 0 }, true)
this.fragment2Arc2.animation('style', { opacity: 0 }, true)
this.fragment2Arc3.animation('style', { opacity: 0 }, true)
this.fragment2Arc4.animation('style', { opacity: 0 }, true)
const fragment3Circle1 = (this.fragment3Circle1 = new GRAPHS.Circle({
animationFrame: 90,
animationCurve: 'easeInOutBack',
shape: {
rx: 0,
ry: 0,
r: 10,
},
style: {
fill: '#e9c752',
graphCenter: [w / 2, h / 2],
rotate: 30,
},
setGraphCenter() {},
}))
const fragment3Circle2 = (this.fragment3Circle2 = new GRAPHS.Circle({
animationFrame: 90,
animationCurve: 'easeInOutBack',
shape: {
rx: w,
ry: h,
r: 10,
},
style: {
fill: '#e9c752',
graphCenter: [w / 2, h / 2],
rotate: -30,
},
setGraphCenter() {},
}))
render.add([fragment3Circle1, fragment3Circle2])
fragment3Circle1.animation('shape', { rx: w / 2, ry: h / 2 }, true)
fragment3Circle2.animation('shape', { rx: w / 2, ry: h / 2 }, true)
fragment3Circle1.animation('style', { rotate: 360 }, true)
fragment3Circle2.animation('style', { rotate: 360 }, true)
return render.launchAnimation()
},
fragment4(render) {
const [w, h] = render.area
const randomXArea = [w / 2 - 80, w / 2 + 80]
const randomYArea = [h / 2 - 80, h / 2 + 80]
this.fragment3Circle1.attr('style', {
fill: 'rgba(0, 0, 0, 0)',
stroke: '#e9c752',
})
this.fragment3Circle2.attr('style', {
fill: 'rgba(0, 0, 0, 0)',
stroke: '#e9c752',
})
this.fragment3Circle1.animation('shape', { r: 50 }, true)
this.fragment3Circle2.animation('shape', { r: 1 }, true)
this.fragment3Circle1.animation('style', { opacity: 0 }, true)
this.fragment3Circle2.animation('style', { opacity: 0 }, true)
return render.launchAnimation()
},
fragment5(render) {
const { randomNum, color } = this
const [w, h] = render.area
const randomXArea = [w / 2 - 80, w / 2 + 80]
const randomYArea = [h / 2 - 100, h / 2 + 100]
const fragment5Rings = (this.fragment5Rings = new Array(10).fill(0).map(_ => {
return new GRAPHS.Ring({
animationCurve: 'easeOutCubic',
animationFrame: 150,
shape: {
rx: randomNum(...randomXArea),
ry: randomNum(...randomYArea),
r: 1,
},
style: {
stroke: color[randomNum(0, 6)],
},
})
}))
render.add(fragment5Rings)
this.fragment5Rings.forEach(ring => {
ring.animation('shape', { r: randomNum(40, 50) }, true)
ring.animation('style', { opacity: 0 }, true)
})
const fragment5Text = (this.fragment5Text = new GRAPHS.Text({
animationCurve: 'easeOutBack',
shape: {
content: 'CRender',
position: [w / 2, h / 2],
maxWidth: 200,
},
style: {
fill: '#66d7ee',
fontSize: 50,
shadowBlur: 0,
shadowColor: '#66eece',
scale: [0.5, 0.5],
rotate: -90,
opacity: 0,
},
}))
render.add(fragment5Text)
fragment5Text.animation(
'style',
{
opacity: 1,
rotate: 0,
scale: [1.4, 1.4],
shadowBlur: 20,
},
true
)
const fragment5Polyline1 = (this.fragment1Polyline1 = new GRAPHS.Polyline({
animationCurve: 'easeOutBack',
shape: {
points: [
[w / 2, h / 2],
[w / 2, h / 2],
],
},
style: {
lineWidth: 7,
stroke: '#66d7ee',
shadowColor: '#66eece',
shadowBlur: 20,
},
}))
render.add(fragment5Polyline1)
fragment5Polyline1.animation(
'shape',
{
points: [
[w / 2 - 200, h / 2 + 40],
[w / 2 + 200, h / 2 + 40],
],
},
true
)
return render.launchAnimation()
},
randomNum(minNum, maxNum) {
switch (arguments.length) {
case 1:
return parseInt(Math.random() * minNum + 1, 10)
break
case 2:
return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10)
break
}
},
},
mounted() {
this.init()
},
}
</script>
<style lang="less">
.show-animation {
height: 300px;
box-shadow: 0 0 3px #46bd87;
.canvas {
width: 100%;
height: 100%;
cursor: pointer;
}
}
</style>
# 特点
- 动效
基于transition插件提供了动效支持,调用图形实例的animation方法去更改其状态,CRender将自动渲染图形状态过渡动画,动画——轻而易举
- 交互
内置的基础图形都提供了drag、onMouseEnter、onMouseOuter、onClick等功能及事件的支持
# 安装
- npm 安装
npm install @jiaminghi/c-render
- yarn 安装
yarn add @jiaminghi/c-render
# UMD 版
UMD
版可直接使用 script
标签引入,UMD
版文件下载请移步 UMD。
点击以展示/隐藏UMD版使用示例
<!DOCTYPE html>
<html>
<head>
<title>CRender</title>
<!--调试版-->
<script src="https://unpkg.com/@jiaminghi/c-render/dist/index.js"></script>
<!--压缩版 生产版本-->
<!-- <script src="https://unpkg.com/@jiaminghi/c-render/dist/index.min.js"></script> -->
<style>
html,
body,
canvas {
width: 100%;
height: 100%;
margin: 0px;
padding: 0px;
}
</style>
</head>
<body>
<canvas></canvas>
<script>
const { CRender, GRAPHS } = window.CRender
const canvas = document.querySelector('canvas')
const render = new CRender(canvas)
const [w, h] = render.area
const graph = new GRAPHS.Text({
animationCurve: 'easeOutBounce',
shape: {
content: 'Welcome to CRender',
position: [w / 2, h / 2],
},
style: {
fontSize: 80,
fill: '#34e4ab',
opacity: 0,
},
})
render.add(graph)
graph.animation('style', {
opacity: 1,
fontSize: 120,
})
</script>
</body>
</html>
# 扩展
要为CRender扩展新的图形请参阅扩展
CRender →