提交 5d159430 编写于 作者: M Mr.doob

Added basic functionality to SVGLoader.

上级 bf2118f8
......@@ -124,6 +124,7 @@ var files = {
"webgl_loader_sea3d_skinning",
"webgl_loader_sea3d_sound",
"webgl_loader_stl",
"webgl_loader_svg",
"webgl_loader_texture_dds",
"webgl_loader_texture_exr",
"webgl_loader_texture_hdr",
......
......@@ -17,17 +17,199 @@ THREE.SVGLoader.prototype = {
var scope = this;
var parser = new DOMParser();
var loader = new THREE.FileLoader( scope.manager );
loader.load( url, function ( svgString ) {
var doc = parser.parseFromString( svgString, 'image/svg+xml' ); // application/xml
loader.load( url, function ( text ) {
onLoad( doc.documentElement );
onLoad( scope.parse( text ) );
}, onProgress, onError );
},
parse: function ( text ) {
function parseNodes( nodes ) {
for ( var i = 0; i < nodes.length; i ++ ) {
parseNode( nodes[ i ] );
}
}
function parseNode( node ) {
if ( node.nodeType !== 1 ) return;
switch ( node.nodeName ) {
case 'svg':
break;
case 'g':
break;
case 'path':
paths.push( parsePathNode( node ) );
break;
case 'rect':
paths.push( parseRectNode( node ) );
break;
default:
console.log( node );
break;
}
parseNodes( node.childNodes );
}
function parsePathNode( node ) {
var path = new THREE.ShapePath();
var point = new THREE.Vector2();
var d = node.getAttribute( 'd' );
console.log( d );
var commands = d.match( /[a-df-z][^a-df-z]*/ig );
for ( var i = 0; i < commands.length; i ++ ) {
var command = commands[ i ];
var type = command.charAt( 0 );
var data = command.substr( 1 );
switch ( type ) {
case 'M':
var numbers = parseFloats( data );
point.fromArray( numbers );
path.moveTo( point.x, point.y );
break;
case 'H':
var numbers = parseFloats( data );
point.x = numbers[ 0 ];
path.lineTo( point.x, point.y );
break;
case 'V':
var numbers = parseFloats( data );
point.y = numbers[ 0 ];
path.lineTo( point.x, point.y );
break;
case 'L':
var numbers = parseFloats( data );
point.x = numbers[ 0 ];
point.y = numbers[ 1 ];
path.lineTo( point.x, point.y );
break;
case 'C':
var numbers = parseFloats( data );
path.bezierCurveTo(
numbers[ 0 ],
numbers[ 1 ],
numbers[ 2 ],
numbers[ 3 ],
numbers[ 4 ],
numbers[ 5 ],
);
point.x = numbers[ 4 ];
point.y = numbers[ 5 ];
break;
case 'h':
var numbers = parseFloats( data );
point.x += numbers[ 0 ];
path.lineTo( point.x, point.y );
break;
case 'v':
var numbers = parseFloats( data );
point.y += numbers[ 0 ];
path.lineTo( point.x, point.y );
break;
case 'l':
var numbers = parseFloats( data );
point.x += numbers[ 0 ];
point.y += numbers[ 1 ];
path.lineTo( point.x, point.y );
break;
case 'c':
var numbers = parseFloats( data );
path.bezierCurveTo(
point.x + numbers[ 0 ],
point.y + numbers[ 1 ],
point.x + numbers[ 2 ],
point.y + numbers[ 3 ],
point.x + numbers[ 4 ],
point.y + numbers[ 5 ],
);
point.x += numbers[ 4 ];
point.y += numbers[ 5 ];
break;
}
}
return path;
}
function parseRectNode( node ) {
var x = parseFloat( node.getAttribute( 'x' ) );
var y = parseFloat( node.getAttribute( 'y' ) );
var w = parseFloat( node.getAttribute( 'width' ) );
var h = parseFloat( node.getAttribute( 'height' ) );
var path = new THREE.ShapePath();
path.moveTo( x, y );
path.lineTo( x + w, y );
path.lineTo( x + w, y + h );
path.lineTo( x, y + h );
return path;
}
function parseFloats( string ) {
var array = string.split( /[\s,]+|(?=\s?[+\-])/ );
for ( var i = 0; i < array.length; i ++ ) {
array[ i ] = parseFloat( array[ i ] );
}
return array;
}
//
var xml = new DOMParser().parseFromString( text, 'image/svg+xml' ); // application/xml
var svg = xml.documentElement;
var paths = [];
parseNode( svg );
return paths;
}
};
此差异已折叠。
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
color: #ffffff;
font-family: Monospace;
font-size: 13px;
text-align: center;
font-weight: bold;
background-color: #000000;
margin: 0px;
overflow: hidden;
}
#info {
position: absolute;
top: 0px;
width: 100%;
padding: 5px;
}
a {
color: #ffffff;
}
</style>
</head>
<body>
<div id="container"></div>
<div id="info">
<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a>
</div>
<script type="text/javascript" src="../build/three.js"></script>
<script src="js/controls/OrbitControls.js"></script>
<script src="js/loaders/SVGLoader.js"></script>
<script src="js/libs/stats.min.js"></script>
<script>
var renderer, stats, scene, camera;
init();
animate();
//
function init() {
var container = document.getElementById( 'container' );
//
scene = new THREE.Scene();
scene.background = new THREE.Color( 0xb0b0b0 );
//
camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.set( 0, 0, 200 );
//
var helper = new THREE.GridHelper( 160, 10 );
helper.rotation.x = Math.PI / 2;
scene.add( helper );
//
var loader = new THREE.SVGLoader();
loader.load( 'models/svg/tiger.svg', function ( paths ) {
console.log( paths );
var group = new THREE.Group();
group.scale.multiplyScalar( 0.1 );
group.scale.y *= -1;
for ( var i = 0; i < paths.length; i ++ ) {
var path = paths[ i ];
var material = new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff } );
var shapes = path.toShapes( true );
for ( var j = 0; j < shapes.length; j ++ ) {
var shape = shapes[ j ];
var geometry = new THREE.ShapeBufferGeometry( shape );
var mesh = new THREE.Mesh( geometry, material );
group.add( mesh );
}
}
scene.add( group );
} );
//
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
//
var controls = new THREE.OrbitControls( camera, renderer.domElement );
//
stats = new Stats();
container.appendChild( stats.dom );
//
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate );
render();
stats.update();
}
function render() {
renderer.render( scene, camera );
}
</script>
</body>
</html>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册