js打造线状足球3d模型效果可以下载为svg
代码语言:html
所属分类:三维
代码描述:js打造线状足球3d模型效果可以下载为svg
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <style> :root { --sq: 500px; } html { height: 100vh; } body { align-items: center; display: flex; height: 100%; justify-content: center; margin: 0; padding: 0; } canvas { height: auto; width: var(--sq); } .container { height: var(--sq); text-align: center; width: var(--sq); } </style> </head> <body translate="no"> <div class="container"></div> <script type="text/javascript" src="http://repo.bfw.wiki/bfwrepo/js/paper.js"></script> <script >const conversionFactor = 180 / Math.PI; var radianToDegrees = function(radian) { return radian * conversionFactor; } var degreesToRadian = function(degrees) { return degrees / conversionFactor; } let Vec2, Vec3, Vec4, Mat2, Mat3, Mat4, Quat; /** * A basic 2D Vector class that provides simple algebraic functionality in the form * of 2D Vectors. * * We use Getters/setters for both principle properties (x & y) as well as virtual * properties (rotation, length etc.). * * @class Vec2 * @author Liam Egan <liam@wethecollective.com> * @version 1.0.0 * @created Jan 07, 2020 */ Vec2 = class { /** * The Vector Class constructor * * @constructor * @param {number} x The x coord * @param {number} y The y coord */ constructor(x, y){ if(isNaN(x)) x = 0; if(isNaN(y)) y = 0; this.x = x; this.y = y; } /** * Resets the vector coordinates * * @public * @param {number|Array} x The x coord, OR the array to reset to * @param {number} y The y coord */ reset(x, y) { if(x instanceof Array && x.length >= 2) { this.x = x[0]; this.y = x[1]; } else { this.x = x; this.y = y; } } /** * Resets the vector coordinates to another vector object * * @public * @param {Vector} v The vector object to use to reset the coordinates */ resetToVector(v) { if(v instanceof Vec2) { this.x = v.x; this.y = v.y; } } /** * Clones the vector * * @public * @return {Vector} The cloned vector */ clone() { return new Vec2(this.x, this.y); } /** * Adds one vector to another. * * @public * @chainable * @param {Vec2} vector The vector to add to this one * @return {Vec2} Returns itself, modified */ add(vector) { this.x += vector.x; this.y += vector.y; return this; } /** * Clones the vector and adds the vector to it instead * * @public * @chainable * @param {Vec2} vector The vector to add to this one * @return {Vec2} Returns the clone of itself, modified */ addNew(vector) { return this.clone().add(vector); } /** * Adds a scalar to the vector, modifying both the x and y * * @public * @chainable * @param {number} scalar The scalar to add to the vector * @return {Vec2} Returns itself, modified */ addScalar(scalar) { return this.add(new Vec2(scalar, scalar)); } /** * Clones the vector and adds the scalar to it instead * * @public * @chainable * @param {number} scalar The scalar to add to the vector * @return {Vec2} Returns the clone of itself, modified */ addScalarNew(scalar) { return this.clone().addScalar(scalar); } /** * Subtracts one vector from another. * * @public * @chainable * @param {Vec2} vector The vector to subtract from this one * @return {Vec2} Returns itself, modified */ subtract(vector) { this.x -= vector.x; this.y -= vector.y; return this; } /** * Clones the vector and subtracts the vector from it instead * * @public * @chainable * @param {Vec2} vector The vector to subtract from this one * @return {Vec2} Returns the clone of itself, modified */ subtractNew(vector) { return this.clone().subtract(vector); } /** * Subtracts a scalar from the vector, modifying both the x and y * * @public * @chainable * @param {number} scalar The scalar to subtract from the vector * @return {Vec2} Returns itself, modified */ subtractScalar(scalar) { return this.subtract(new Vec2(scalar, scalar)); } /** * Clones the vector and subtracts the scalar from it instead * * @public * @chainable * @param {number} scalar The scalar to add to the vector * @return {Vec2} Returns the clone of itself, modified */ subtractScalarNew(scalar) { return this.clone().subtractScalar(scalar); } /** * Divides one vector by another. * * @public * @chainable * @param {Vec2} vector The vector to divide this by * @return {Vec2} Returns itself, modified */ divide(vector) { if(vector.x !== 0) { this.x /= vector.x } else { this.x = 0; } if(vector.y !== 0) { this.y /= vector.y } else { this.y = 0; } return this; } /** * Clones the vector and divides it by the vector instead * * @public * @chainable * @param {Vec2} vector The vector to divide the clone by * @return {Vec2} Returns the clone of itself, modified */ divideNew(vector) { return this.clone().divide(vector); } /** * Divides the vector by a scalar. * * @public * @chainable * @param {number} scalar The scalar to divide both x and y by * @return {Vec2} Returns itself, modified */ divideScalar(scalar) { var v = new Vec2(scalar, scalar); return this.divide(v); } /** * Clones the vector and divides it by the provided scalar. * * @public * @chainable * @param {number} scalar The scalar to divide both x and y by * @return {Vec2} Returns the clone of itself, modified */ divideScalarNew(scalar) { return this.clone().divideScalar(scalar); } /** * Multiplies one vector by another. * * @public * @chainable * @param {Vec2} vector The vector to multiply this by * @return {Vec2} Returns itself, modified */ multiply(vector) { this.x *= vector.x; this.y *= vector.y; return this; } /** * Clones the vector and multiplies it by the vector instead * * @public * @chainable * @param {Vec2} vector The vector to multiply the clone by * @return {Vec2} Returns the clone of itself, modified */ multiplyNew(vector) { return this.clone().multiply(vector); } /** * Multiplies the vector by a scalar. * * @public * @chainable * @param {number} scalar The scalar to multiply both x and y by * @return {Vec2} Returns itself, modified */ multiplyScalar(scalar) { var v = new Vec2(scalar, scalar); return this.multiply(v); } /** * Clones the vector and multiplies it by the provided scalar. * * @public * @chainable * @param {number} scalar The scalar to multiply both x and y by * @return {Vec2} Returns the clone of itself, modified */ multiplyScalarNew(scalar) { return this.clone().multiplyScalar(scalar); } /** * Alias of {@link Vector#multiplyScalar__anchor multiplyScalar} */ scale(scalar) { return this.multiplyScalar(scalar); } /** * Alias of {@link Vector#multiplyScalarNew__anchor multiplyScalarNew} */ scaleNew(scalar) { return this.multiplyScalarNew(scalar); } /** * Rotates a vecor by a given amount, provided in radians. * * @public * @chainable * @param {number} radian The angle, in radians, to rotate the vector by * @return {Vec2} Returns itself, modified */ rotate(radian) { var x = (this.x * Math.cos(radian)) - (this.y * Math.sin(radian)); var y = (this.x * Math.sin(radian)) + (this.y * Math.cos(radian)); this.x = x; this.y = y; return this; } /** * Clones the vector and rotates it by the supplied radian value * * @public * @chainable * @param {number} radian The angle, in radians, to rotate the vector by * @return {Vec2} Returns the clone of itself, modified */ rotateNew(radian) { return this.clone().rotate(radian); } /** * Rotates a vecor by a given amount, provided in degrees. Converts the degree * value to radians and runs the rotaet method. * * @public * @chainable * @param {number} degrees The angle, in degrees, to rotate the vector by * @return {Vec2} Returns itself, modified */ rotateDeg(degrees) { return this.rotate(degreesToRadian(degrees)); } /** * Clones the vector and rotates it by the supplied degree value * * @public * @chainable * @param {number} degrees The angle, in degrees, to rotate the vector by * @return {Vec2} Returns the clone of itself, modified */ rotateDegNew(degrees) { return this.rotateNew(degreesToRadian(degrees)); } /** * Alias of {@link Vector#rotate__anchor rotate} */ rotateBy(radian) { return this.rotate(radian); } /** * Alias of {@link Vector#rotateNew__anchor rotateNew} */ rotateByNew(radian) { return this.rotateNew(radian); } /** * Alias of {@link Vector#rotateDeg__anchor rotateDeg} */ rotateDegBy(degrees) { return this.rotateDeg(degrees); } /** * Alias of {@link Vector#rotateDegNew__anchor rotateDegNew} */ rotateDegByNew(radian) { return this.rotateDegNew(radian); } /** * Rotates a vector to a specific angle * * @public * @chainable * @param {number} radian The angle, in radians, to rotate the vector to * @return {Vec2} Returns itself, modified */ rotateTo(radian) { return this.rotate(radian-this.angle); }; /** * Clones the vector and rotates it to the supplied radian value * * @public * @chainable * @param {number} radian The angle, in radians, to rotate the vector to * @return {Vec2} Returns the clone of itself, modified */ rotateToNew(radian) { return this.clone().rotateTo(radian); }; /** * Rotates a vecor to a given amount, provided in degrees. Converts the degree * value to radians and runs the rotateTo method. * * @public * @chainable * @param {number} degrees The angle, in degrees, to rotate the vector to * @return {Vec2} Returns itself, modified */ rotateToDeg(degrees) { return this.rotateTo(degreesToRadian(degrees)); } /** * Clones the vector and rotates it to the supplied degree value * * @public * @chainable * @param {number} degrees The angle, in degrees, to rotate the vector to * @return {Vec2} Returns the clone of itself, modified */ rotateToDegNew(degrees) { return this.rotateToNew(degreesToRadian(degrees)); } /** * Negates the vector. * * @public * @chainable * @return {Vec2} Returns itself, modified */ negate() { return this.multiplyScalar(-1.); } /** * Clones the vector and negates it. * * @public * @chainable * @return {Vec2} Returns itself, modified */ negateNew() { return this.multiplyScalarNew(-1.); } /** * Inverses the vector. * * @public * @chainable * @return {Vec2} Returns itself, modified */ inverse() { this.x = 1./this.x; this.y = 1./this.y; return this; } /** * Clones the vector and then inverses it. * * @public * @chainable * @return {Vec2} Returns itself, modified */ inverseNew() { const c = new Vector(); c.x = 1./this.x; c.y = 1./this.y; return c; } /** * Normalises the vector down to a length of 1 unit * * @public * @chainable * @return {Vec2} Returns itself, modified */ normalise() { return this.divideScalar(this.length); } /** * Clones the vector and normalises it * * @public * @chainable * @return {Vec2} Returns a clone of itself, modified */ normaliseNew() { return this.divideScalarNew(this.length); } /** * Calculates the distance between this and the supplied vector * * @param {Vec2} vector The vector to calculate the distance from * @return {number} The distance between this and the supplied vector */ distance(vector) { return this.subtractNew(vector).length; } /** * Calculates the distance on the X axis between this and the supplied vector * * @param {Vec2} vector The vector to calculate the distance from * @return {number} The distance, along the x axis, between this and the supplied vector */ distanceX(vector) { return this.x - vector.x; } /** * Calculated the distance on the Y axis between this and the supplied vector * * @param {Vec2} vector The vector to calculate the distance from * @return {number} The distance, along the y axis, between this and the supplied vector */ distanceY(vector) { return this.y - vector.y; } /** * Calculates the dot product between this and a supplied vector * * @example * // returns -14 * new Vector(2, -3).dot(new Vector(-4, 2)) * new Vector(-4, 2).dot(new Vector(2, -3)) * new Vector(2, -4).dot(new Vector(-3, 2)) * * @param {Vec2} vector The vector object against which to calculate the dot product * @return {number} The dot product of the two vectors */ dot(vector) { return (this.x * vector.x) + (this.y * vector.y); } /** * Calculates the cross product between this and the supplied vector. * * @example * // returns -2 * new Vector(2, -3).cross(new Vector(-4, 2)) * new Vector(-4, 2).cross(new Vector(2, -3)) * // returns 2 * new Vector(2, -4).cross(new Vector(-3, 2)) * * @param {Vec2} vector The vector object against which to calculate the cross product * @return {number} The cross product of the two vectors */ cross(vector) { return (this.x * vector.x) - (this.y * vector.y); } ceil() { this.x = Math.ceil(this.x); this.y = Math.ceil(this.y); return this; } ceilNew() { return this.clone().ceil(); } floor() { this.x = Math.floor(this.x); this.y = Math.floor(this.y); return this; } floorNew() { return this.clone().floor(); } round() { this.x = Math.round(this.x); this.y = Math.round(this.y); return this; } roundNew() { return this.clone().round(); } fract() { this.x -= Math.floor(this.x); this.y -= Math.floor(this.y); return this; } fractNew() { return this.clone().fract(); } transformByMat2(m) { if(m.array) m = m.array; // This just transforms the matrix to an array. if(m instanceof Array && m.length >= 4) { const c = this.clone(); this.x = m[0] * c.x + m[2] * c.y; this.y = m[1] * c.x + m[3] * c.y; } return this; } transformByMat2New(m) { return this.clone().transformByMat2(m); } transformByMat3(m) { if(m.array) m = m.array; // This just transforms the matrix to an array. if(m instanceof Array && m.length >= 9) { const c = this.clone(); this.x = m[0] * c.x + m[3] * c.y + m[6]; this.y = m[1] * c.x + m[4] * c.y + m[7]; } return this; } transformByMat3New(m) { return this.clone().transformByMat3(m); } /** * Getters and setters */ /** * (getter/setter) The x value of the vector. * * @type {number} * @default 0 */ set x(x) { if(typeof x == 'number') { this._x = x; } else { throw new TypeError('X should be a number'); } } get x() { return this._x || 0; } /** * (getter/setter) The y value of the vector. * * @type {number} * @default 0 */ set y(y) { if(typeof y == 'number') { this._y = y; } else { throw new TypeError('Y should be a number'); } } get y() { return this._y || 0; } /** * (getter/setter) The length of the vector presented as a square. If you're using * length for comparison, this is quicker. * * @type {number} * @default 0 */ set lengthSquared(length) { var factor; if(typeof length == 'number') { factor = length / this.lengthSquared; this.multiplyScalar(factor); } else { throw new TypeError('length should be a number'); } } get lengthSquared() { return (this.x * this.x) + (this.y * this.y); } /** * (getter/setter) The length of the vector * * @type {number} * @default 0 */ set length(length) { var factor; if(typeof length == 'number') { factor = length / this.length; this.multiplyScalar(factor); } else { throw new TypeError('length should be a number'); } } get length() { return Math.sqrt(this.lengthSquared); } /** * (getter/setter) The angle of the vector, in radians * * @type {number} * @default 0 */ set angle(radian) { if(typeof radian == 'number') { this.rotateTo(radian); } else { throw new TypeError('angle should be a number'); } } get angle() { return Math.atan2(this.y, this.x); } /** * (getter/setter) The angle of the vector, in radians * * @type {number} * @default 0 */ set angleInDegrees(degrees) { if(typeof degrees == 'number') { this.rotateToDeg(degrees); } else { throw new TypeError('angle should be a number'); } } get angleInDegrees() { return radianToDegrees(Math.atan2(this.y, this.x)); } /** * (getter/setter) Vector width. * Alias of {@link Vector#x x} * * @type {number} */ set width(w) { this.x = w; } get width() { return this.x; } /** * (getter/setter) Vector height. * Alias of {@link Vector#x x} * * @type {number} */ set height(h) { this.y = h; } get height() { return this.y; } /** * (getter) Vector area. * @readonly * * @type {number} */ get area() { return this.x * this.y; } /** * (getter/setter) Vector slope. * * @type {number} */ set slope(value) { if(!isNaN(value)) { let angle = Math.atan(value); this.angle = angle; } } get slope() { return this.y / this.x; } /** * (getter) Returns the basic array representation of this vector. * @readonly * * @type {number} */ get array() { return [this.x, this.y]; } /** * (getter/sette) Swizzle XY * * @type {number} */ get xy() { return new Vec2(this.x, this.y); } set xy(v) { if(v instanceof Vec2) { this.resetToVector(v); } else if(v instanceof Array && v.length >= 2) { this.reset(v); } else { throw new Error('input should be of type Vector'); } } /** * (getter/sette) Swizzle YX * * @type {number} */ get yx() { return new Vec2(this.y, this.x); } set yx(v) { this.xy = Vec2.interpolate(v).yx; } /** * (getter/sette) Swizzle XX * * @type {number} */ get xx() { return new Vec2(this.x, this.x); } set xx(v) { v = Vec2.interpolate(v); this.x = v.y; } /** * (getter/sette) Swizzle YY * * @type {number} */ get yy() { return new Vec2(this.y, this.y); } set yy(v) { v = Vec2.interpolate(v); this.y = v.y; } /** * Static methods */ /** * Iterpolates a provided anonymous value into a vew Vec2 * * @param {Vec2|array|string|number} v The value to interpolate * @returns {Vec2} out */ static interpolate(v) { if(v instanceof Vec2) { return new Vec2(v.x, v.y); } else if(v instanceof Array && v.length >= 2) { return new Vec2(v[0], v[1]); } else if(!isNaN(v)) { return new Vec2(v, v); } else if(typeof v === 'string') { const nv = v.split(','); if(nv.length >= 2 && !isNaN(nv[0]) && !isNaN(nv[1])) { return new Vec2(Number(nv[0], nv[1])); } } else { throw new Error('The passed interpolant could not be parsed into a vec2'); } } /** * Performs a linear interpolation between two vec2's * * @param {vec2} v1 the first operand * @param {vec2} v2 the second operand * @param {Number} d interpolation amount in the range of 0 - 1 * @returns {Vec2} */ static lerp(v1, v2, d) { return new Vec2( v1.x + d * (v2.x - v1.x), v1.y + d * (v2.y - v1.y) ); } static getAngle(a, b) { a = a.clone(); b = b.clone(); a.normalise(); b.normalise(); const cosine = a.dot(b); if(cosine > 1.0) { return 0; } else if(cosine < -1.0) { return Math.PI; } else { return Math.acos(cosine); } } } /** * A basic 3D Vector class that provides simple algebraic functionality in the form * of 3D Vectors. * * We use Getters/setters for both principle properties (x & y) as well as virtual * properties (rotation, length etc.). * * @class Vec3 * @author Liam Egan <liam@wethecollective.com> * @version 1.0.0 * @created Jan 07, 2020 */ Vec3 = class { /** * The Vector Class constructor * * @constructor * @param {number} x The x coord * @param {number} y The y coord */ constructor(x, y, z){ if(x instanceof Array && x.length >= 3) { this.x = x[0]; this.y = x[1]; this.z = x[2]; } else { if(isNaN(x)) x = 0; if(isNaN(y)) y = 0; if(isNaN(z)) z = 0; this.x = x; this.y = y; this.z = z; } } /** * Resets the vector coordinates * * @public * @param {number|Array} x The x co.........完整代码请登录后点击上方下载按钮下载查看
网友评论0