精华 利用SVG生成路径/画线
发布于 3 年前 作者 xiaomingcscs 1967 次浏览 来自 分享

有时候我们需要一些曲线效果,比如,鱼的游泳路径,动态画出图案轮廓。 这个时候,我们需要设计大大们提供一个SVG文件给我们,就可以利用SVG里面 d 的值来生成游戏里面的XY坐标。 我们需要一个JS插件:snap.svg-min.js 中文API 这个插件可以很方便的做出一个SVG动画,我们现在利用它里面的Snap.path.toCubic 就可以喇~~

DEMO下载

index.html

<!doctype html>
<html lang="en">
<head>
	<title>SVG</title>
	<meta name="viewport" content="width=device-width; initial-scale=1; maximum-scale=1;" />
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <style type="text/css">
    *{margin: 0;padding:0;}html,body{width:100%;height:100%;overflow:hidden;font-family:'myFont'}canvas{position: absolute;left: 50%;top: 50%;transform: translate(-50%,-50%);-webkit-transform: translate(-50%,-50%);}
    </style>
</head>
<body>
<script type="text/javascript" src="js/snap.svg-min.js"></script>
<script type="text/javascript" src="js/path.js"></script>
<script type="text/javascript" src="js/phaser.min.js"></script>
<script type="text/javascript" src="js/main.js"></script>
</body>
</html>

main.js

var game = new Phaser.Game(1920, 1080, Phaser.CANVAS, 'game');
var PhaserSvg = function() {
  this.points = {
    'x': [],
    'y': []
  };
};

PhaserSvg.prototype = {
  create: function() {
    this.stage.backgroundColor = '#fcd4b1';
    this.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
    this.svg = this.add.group();
    this.bmd = new draw(this.svg,0.8,'#fff',40);
    this.setSvg('svg/'+ l(1, 13) +'.svg');
  },
  addLine: function(){
    var ii = 0,
     speed = 5,
     len = Math.ceil((this.points.x.length)/speed-1),
     dowLineData=this.time.create(false);
    dowLineData.loop(10,function(){
     ii+=speed;
     this.bmd.mx = this.points.x[(ii-speed)];
     this.bmd.my = this.points.y[(ii-speed)];
     this.bmd.lx = this.points.x[ii];
     this.bmd.ly = this.points.y[ii];
     this.bmd.onDraw();
     if(ii/speed == len){
         dowLineData.paused = true;
         dowLineData.destroy();
     };
    }, this);
    dowLineData.start();
  },
  setSvg: function(src){
    Snap.load(src, function(f) {
        //获取长度
        this.svgLength = f.select("path").getTotalLength();
        //获取SVG路径
        this.path = Snap.path.toCubic(f.select("path").attr("d"));
        //缓存
        this.temp = [];
        this.temp[0] = '';
        for(var i = 1;i < this.path.length;i++){
            //为什么要这么弄,我忘记
            this.temp[i] = {};
            this.temp[i].p0 = {x:this.path[(i-1)][(this.path[(i-1)].length-2)],y:this.path[(i-1)][(this.path[(i-1)].length-1)]};
            this.temp[i].p1 = {x:this.path[i][1],y:this.path[i][2]};
            this.temp[i].p2 = {x:this.path[i][3],y:this.path[i][4]};
            this.temp[i].p3 = {x:this.path[i][5],y:this.path[i][6]};
            this.temp[i].ball = {x:0,y:0,speed:0.02,t:0};
            for(var ii = 0; ii < 50; ii++){
                getPath(this.temp[i].p0,this.temp[i].p1,this.temp[i].p2,this.temp[i].p3,i,this);
            };
        };
        this.temp = null;
        console.log('生成出来的坐标:', this.points);
        this.addLine();
    },this);
  }
};
//随机数
function l(a, b) {
    a = Math.round(a);
    b = Math.round(b);
    return Math.round((b - a) * Math.random()) + a
}
window.onload = function() {
  game.state.add('Game', PhaserSvg, true);
}

path.js

/*
	*这个是什么意思?我不知道,网上找的算法
*/
var getPath=function(p0,p1,p2,p3,index,_this){
	this.p0=p0;
	this.p1=p1;
	this.p2=p2;
	this.p3=p3;
	this.t = _this.temp[index].ball.t;
	this.cx = 3*(this.p1.x-this.p0.x);
	this.bx = 3*(this.p2.x-this.p1.x)-this.cx;
	this.ax = this.p3.x-this.p0.x-this.cx-this.bx;

	this.cy = 3*(this.p1.y-this.p0.y);
	this.by = 3*(this.p2.y-this.p1.y)-this.cy;
	this.ay = this.p3.y-this.p0.y-this.cy-this.by;

	this.xt = this.ax*(this.t*this.t*this.t)+this.bx*(this.t*this.t)+this.cx*this.t+this.p0.x;
	this.yt = this.ay*(this.t*this.t*this.t)+this.by*(this.t*this.t)+this.cy*this.t+this.p0.y;

	_this.temp[index].ball.t +=_this.temp[index].ball.speed;

	if(_this.temp[index].ball.t>1){
		_this.temp[index].ball.t=1;
	}
	//console.log(this.xt,this.yt)
	_this.points.x.push(this.xt);
	_this.points.y.push(this.yt);
}
/**
画线
group=组
alpha=线条透明度
color=线条颜色
width=线条粗度
*/
var draw = function(group,alpha,color,width){
	this.mx = 0;
	this.my = 0;
	this.lx = 0;
	this.ly = 0;
	this.Line = game.add.bitmapData(1920, 1080);
	//this.Line.addToWorld();
	this.Line.ctx.beginPath();
	this.Line.ctx.strokeStyle = color;
	this.Line.ctx.lineWidth = width;
	this.Line.ctx.lineJoin = "round";

	this.sprite = game.add.sprite(0,0,this.Line);
	this.sprite.alpha = alpha;
	group.add(this.sprite)
	this.onDraw = function(){
		this.Line.ctx.moveTo(this.mx,this.my);
		this.Line.ctx.lineTo(this.lx,this.ly);
		this.Line.ctx.closePath();
		this.Line.ctx.stroke();
	};
	this.onRemove = function(){
		this.group.destroy(true,true);
		this.Line.ctx.setTransform(1, 0, 0, 1, 0, 0);
		this.Line.ctx.clearRect(0, 0, 1920, 1080);
	};
}

GIF.gif

1 回复

好棒,很实用的功能

回到顶部