의 미러
https://github.com/svgdotjs/svg.js.git
synced 2024-07-31 20:21:32 +02:00
Made developing a little more enjoyable
This commit adds playgrounds and a build:dev mode. Now you can call npm run build:dev to make the linter warn you about errors without breaking. Also, we now have playgrounds, where you can use a built version of svg.js to run your own tests.
This commit is contained in:
부모
4b078f8732
커밋
1cb509f863
@ -1,56 +1,55 @@
|
||||
;( function() {
|
||||
/* global Snap */
|
||||
|
||||
;(function () {
|
||||
SVG.bench = {
|
||||
// Initalize test store
|
||||
_chain: []
|
||||
, _before: function() {}
|
||||
, _after: function() {}
|
||||
, draw: SVG().addTo('#draw')
|
||||
, snap: Snap(100, 100)
|
||||
, raw: document.getElementById('native')
|
||||
_chain: [],
|
||||
_before: function () {},
|
||||
_after: function () {},
|
||||
draw: SVG().addTo('#draw'),
|
||||
snap: Snap(100, 100),
|
||||
raw: document.getElementById('native'),
|
||||
|
||||
// Add descriptor
|
||||
, describe: function(name, closure) {
|
||||
describe: function (name, closure) {
|
||||
this._chain.push({
|
||||
name: name
|
||||
, run: closure
|
||||
name: name,
|
||||
run: closure
|
||||
})
|
||||
|
||||
return this
|
||||
}
|
||||
},
|
||||
|
||||
// Add test
|
||||
, test: function(name, run) {
|
||||
test: function (name, run) {
|
||||
// run test
|
||||
var start = ( new Date ).getTime()
|
||||
var start = (new Date()).getTime()
|
||||
run()
|
||||
this.write( name, ( new Date ).getTime() - start )
|
||||
this.write(name, (new Date()).getTime() - start)
|
||||
|
||||
// clear everything
|
||||
this.clear()
|
||||
}
|
||||
},
|
||||
|
||||
// Skip test
|
||||
, skip: function(name, run) {
|
||||
this.write( name, false )
|
||||
}
|
||||
skip: function (name, run) {
|
||||
this.write(name, false)
|
||||
},
|
||||
|
||||
// Run tests
|
||||
, run: function() {
|
||||
run: function () {
|
||||
this.pad()
|
||||
|
||||
|
||||
for (var h, i = 0, il = this._chain.length; i < il; i++) {
|
||||
var h = document.createElement('h1')
|
||||
h = document.createElement('h1')
|
||||
h.innerHTML = this._chain[i].name
|
||||
|
||||
this.pad().appendChild(h)
|
||||
|
||||
this._chain[i].run(this)
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
// Write result
|
||||
, write: function(name, ms) {
|
||||
write: function (name, ms) {
|
||||
var test = document.createElement('div')
|
||||
|
||||
if (typeof ms === 'number') {
|
||||
@ -60,14 +59,14 @@
|
||||
test.className = 'test skipped'
|
||||
test.innerHTML = name + ' (skipped)'
|
||||
}
|
||||
|
||||
|
||||
this.pad().appendChild(test)
|
||||
|
||||
return this
|
||||
}
|
||||
},
|
||||
|
||||
// Reference writable element
|
||||
, pad: function() {
|
||||
pad: function () {
|
||||
var pad = document.getElementById('pad')
|
||||
|
||||
if (!pad) {
|
||||
@ -76,15 +75,15 @@
|
||||
}
|
||||
|
||||
return pad
|
||||
}
|
||||
},
|
||||
|
||||
// Clear canvasses
|
||||
, clear: function() {
|
||||
while(this.raw.hasChildNodes())
|
||||
clear: function () {
|
||||
while (this.raw.hasChildNodes()) {
|
||||
this.raw.removeChild(this.raw.lastChild)
|
||||
}
|
||||
this.draw.clear()
|
||||
this.snap.clear()
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
||||
})()
|
||||
|
889
dist/svg.js
vendored
889
dist/svg.js
vendored
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
Load Diff
4
dist/svg.min.js
vendored
4
dist/svg.min.js
vendored
File diff suppressed because one or more lines are too long
@ -98,8 +98,8 @@ gulp.task('unify', ['clean'], function () {
|
||||
.pipe(standard())
|
||||
.pipe(standard.reporter('default', {
|
||||
showRuleNames: true,
|
||||
breakOnError: true,
|
||||
quiet: true
|
||||
breakOnError: process.argv[2] !== "--dont-break",
|
||||
quiet: true,
|
||||
}))
|
||||
.pipe(concat('svg.js', { newLine: '\n' }))
|
||||
// wrap the whole thing in an immediate function call
|
||||
@ -109,6 +109,7 @@ gulp.task('unify', ['clean'], function () {
|
||||
.pipe(chmod(0o644))
|
||||
.pipe(gulp.dest('dist'))
|
||||
.pipe(size({ showFiles: true, title: 'Full' }))
|
||||
return collection
|
||||
})
|
||||
|
||||
/**
|
||||
|
@ -56,6 +56,7 @@
|
||||
"scripts": {
|
||||
"build": "gulp",
|
||||
"build:test": "gulp unify",
|
||||
"build:dev": "gulp --dont-break",
|
||||
"test": "karma start .config/karma.conf.js --single-run",
|
||||
"test:quick": "karma start .config/karma.quick.js",
|
||||
"lint": "standard --verbose | snazzy"
|
||||
@ -88,6 +89,7 @@
|
||||
"standard": {
|
||||
"ignore": [
|
||||
"/dist",
|
||||
"/spec",
|
||||
"/src/umd.js"
|
||||
],
|
||||
"globals": [
|
||||
|
42
playgrounds/playground.css
Normal file
42
playgrounds/playground.css
Normal file
@ -0,0 +1,42 @@
|
||||
|
||||
html {
|
||||
background-color : #f5f6f7;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #f06;
|
||||
font-size: 6vh;
|
||||
margin: 4vh;
|
||||
font-family: Helvetica;
|
||||
}
|
||||
|
||||
svg {
|
||||
width: 70vw;
|
||||
height: 80vh;
|
||||
background-color: white;
|
||||
position: fixed;
|
||||
border-radius: 20px;
|
||||
border: #f065 1px solid;
|
||||
left: 15vw;
|
||||
}
|
||||
|
||||
.pink {
|
||||
fill: #FF0066;
|
||||
}
|
||||
|
||||
.green {
|
||||
fill: #00ff99;
|
||||
}
|
||||
|
||||
.dark-pink {
|
||||
fill: #660029;
|
||||
}
|
||||
|
||||
.light-pink {
|
||||
fill: #FF99C2;
|
||||
}
|
||||
|
||||
.off-white {
|
||||
fill: #FFCCE0;
|
||||
}
|
27
playgrounds/transforms/transforms.html
Normal file
27
playgrounds/transforms/transforms.html
Normal file
@ -0,0 +1,27 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>SVG Playground</title>
|
||||
<link rel="stylesheet" href="../playground.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<h1>SVG JS Playground</h1>
|
||||
|
||||
<svg viewBox="0 0 1000 1000">
|
||||
|
||||
<rect id="old" x=300 y=400 width=200 height=400 class="green"/>
|
||||
<rect id="new" x=300 y=400 width=200 height=400 class="pink"/>
|
||||
|
||||
</svg>
|
||||
|
||||
</body>
|
||||
|
||||
<script src="../../dist/svg.js" charset="utf-8"></script>
|
||||
<script src="transforms.js" charset="utf-8"></script>
|
||||
|
||||
</html>
|
7
playgrounds/transforms/transforms.js
Normal file
7
playgrounds/transforms/transforms.js
Normal file
@ -0,0 +1,7 @@
|
||||
|
||||
let mover = SVG.select("#new")[0]
|
||||
|
||||
console.log(mover.transform());
|
||||
mover.transform({
|
||||
position: [30, 50]
|
||||
})
|
@ -19,11 +19,11 @@ describe('Transformations:', function() {
|
||||
|
||||
describe('SVG.Translate', function() {
|
||||
var trans
|
||||
|
||||
|
||||
beforeEach(function(){
|
||||
trans = new SVG.Translate(translated.transform())
|
||||
})
|
||||
|
||||
|
||||
|
||||
it('creates an object of type SVG.Transformation', function() {
|
||||
expect(trans instanceof SVG.Transformation).toBeTruthy()
|
||||
@ -51,7 +51,7 @@ describe('Transformations:', function() {
|
||||
var extracted = (new SVG.Matrix(10,0,0,10,20,20)).extract()
|
||||
trans.undo(extracted)
|
||||
expect(trans._undo.toString()).toEqual('matrix(1,0,0,1,-2,-2)')
|
||||
|
||||
|
||||
var extracted = (new SVG.Matrix(10,50,50,30,20,20)).extract()
|
||||
trans.undo(extracted)
|
||||
expect(trans._undo.e).toBeCloseTo(-extracted.transformedX)
|
||||
@ -78,14 +78,14 @@ describe('Transformations:', function() {
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
describe('SVG.Rotate', function() {
|
||||
var trans
|
||||
|
||||
|
||||
beforeEach(function(){
|
||||
trans = new SVG.Rotate(45, 50, 50)
|
||||
})
|
||||
|
||||
|
||||
|
||||
it('creates an object of type SVG.Transformation', function() {
|
||||
expect(trans instanceof SVG.Transformation).toBeTruthy()
|
||||
@ -129,15 +129,15 @@ describe('Transformations:', function() {
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
|
||||
describe('SVG.Scale', function() {
|
||||
var trans
|
||||
|
||||
|
||||
beforeEach(function(){
|
||||
trans = new SVG.Scale(2,2,50,50)
|
||||
})
|
||||
|
||||
|
||||
|
||||
it('creates an object of type SVG.Transformation', function() {
|
||||
expect(trans instanceof SVG.Transformation).toBeTruthy()
|
||||
@ -170,7 +170,7 @@ describe('Transformations:', function() {
|
||||
expect(trans._undo.d).toBeCloseTo(1/extracted.scaleY)
|
||||
expect(trans._undo.e).toBeCloseTo(45)
|
||||
expect(trans._undo.f).toBeCloseTo(45)
|
||||
|
||||
|
||||
var extracted = (new SVG.Matrix(10,50,50,30,20,20)).extract()
|
||||
trans.undo(extracted)
|
||||
expect(trans._undo.a).toBeCloseTo(1/extracted.scaleX)
|
||||
@ -184,12 +184,12 @@ describe('Transformations:', function() {
|
||||
})
|
||||
it('returns the inversed matrix from a specific position when created with inverse flag', function() {
|
||||
var morphed = (new SVG.Scale(scaled.transform(2,2,50,50), true)).at(0.25)
|
||||
|
||||
|
||||
expect(morphed.a).toBeCloseTo(0.8)
|
||||
expect(morphed.d).toBeCloseTo(0.8)
|
||||
})
|
||||
it('returns the resulting transformation which has to be made to set an absolute translation', function() {
|
||||
|
||||
|
||||
var morphed = trans.undo((new SVG.Matrix(10,0,0,10,0,0)).extract()).at(0.5)
|
||||
|
||||
expect(morphed.a).toBeCloseTo(0.6)
|
||||
@ -200,15 +200,15 @@ describe('Transformations:', function() {
|
||||
expect(morphed.f).toBeCloseTo(20)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('SVG.Skew', function() {
|
||||
var trans
|
||||
|
||||
|
||||
beforeEach(function(){
|
||||
trans = new SVG.Skew(30,-30,50,50)
|
||||
})
|
||||
|
||||
|
||||
|
||||
it('creates an object of type SVG.Transformation', function() {
|
||||
expect(trans instanceof SVG.Transformation).toBeTruthy()
|
||||
@ -257,7 +257,7 @@ describe('Transformations:', function() {
|
||||
})
|
||||
it('returns the inversed matrix from a specific position when created with inverse flag', function() {
|
||||
var morphed = (new SVG.Scale(skewed.transform(20,-20,50,50), true)).at(0.25)
|
||||
|
||||
|
||||
expect(morphed.a).toBeCloseTo(0.963)
|
||||
expect(morphed.b).toBeCloseTo(0)
|
||||
expect(morphed.c).toBeCloseTo(0)
|
||||
@ -266,7 +266,7 @@ describe('Transformations:', function() {
|
||||
expect(morphed.f).toBeCloseTo(0)
|
||||
})
|
||||
it('returns the resulting transformation which has to be made to set an absolute translation', function() {
|
||||
|
||||
|
||||
var morphed = trans.undo((new SVG.Matrix(10,0,0,10,0,0)).skew(20, 30, 20, 10).extract()).at(0.5)
|
||||
|
||||
expect(morphed.a).toBeCloseTo(1.266)
|
||||
@ -278,5 +278,4 @@ describe('Transformations:', function() {
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
|
218
src/matrix.js
218
src/matrix.js
@ -1,4 +1,4 @@
|
||||
/* global abcdef, arrayToMatrix, deltaTransformPoint, parseMatrix */
|
||||
/* global abcdef, arrayToMatrix, parseMatrix, unitCircle, mag */
|
||||
|
||||
SVG.Matrix = SVG.invent({
|
||||
// Initialize
|
||||
@ -23,159 +23,130 @@ SVG.Matrix = SVG.invent({
|
||||
},
|
||||
|
||||
// Add methods
|
||||
, extend: {
|
||||
extend: {
|
||||
|
||||
// Convert an object of affine parameters into a matrix
|
||||
compose: function (o, cx, cy) {
|
||||
|
||||
// Set the defaults
|
||||
var tx = o.translateX || 0
|
||||
, ty = o.translateY || 0
|
||||
, theta = o.theta || 0
|
||||
, sx = o.scaleX || 1
|
||||
, sy = o.scaleY || 1
|
||||
, lam = o.shear || 0
|
||||
, cx = cx || 0
|
||||
, cy = cy || 0
|
||||
var ty = o.translateY || 0
|
||||
var theta = o.theta || 0
|
||||
var sx = o.scaleX || 1
|
||||
var sy = o.scaleY || 1
|
||||
var lam = o.shear || 0
|
||||
cx = cx || 0
|
||||
cy = cy || 0
|
||||
|
||||
// Calculate the trigonometric values
|
||||
var ct = Math.cos(theta * Math.PI / 180)
|
||||
, st Math.sin(theta * Math.PI / 180)
|
||||
var st = Math.sin(theta * Math.PI / 180)
|
||||
|
||||
// Calculate the matrix components directly
|
||||
var a = sx * ct
|
||||
, b = sx * st
|
||||
, c = lam * sx * ct - sy * st
|
||||
, d = lam * sx * st + sy * ct
|
||||
, e = - sx * ct * (cx + cy * lam) + sy * st * cy + tx + cx
|
||||
, f = - sx * st * (cx + cy * lam) - sy * ct * cy + ty + cy
|
||||
var b = sx * st
|
||||
var c = lam * sx * ct - sy * st
|
||||
var d = lam * sx * st + sy * ct
|
||||
var e = -sx * ct * (cx + cy * lam) + sy * st * cy + tx + cx
|
||||
var f = -sx * st * (cx + cy * lam) - sy * ct * cy + ty + cy
|
||||
|
||||
// Construct a new matrix and return it
|
||||
var matrix = new SVG.Matrix([a, b, c, d, e, f])
|
||||
return matrix
|
||||
}
|
||||
},
|
||||
// Decompose a matrix into the affine parameters needed to form it
|
||||
, decompose: function (matrix, cx, cy) {
|
||||
|
||||
decompose: function (matrix, cx, cy) {
|
||||
// Get the paramaters of the current matrix
|
||||
var a = matrix.a
|
||||
, b = matrix.b
|
||||
, c = matrix.c
|
||||
, d = matrix.d
|
||||
, e = matrix.e
|
||||
, f = matrix.f
|
||||
var b = matrix.b
|
||||
var c = matrix.c
|
||||
var d = matrix.d
|
||||
var e = matrix.e
|
||||
var f = matrix.f
|
||||
|
||||
// Project the first basis vector onto the unit circle
|
||||
var circle = unitCircle (a, b)
|
||||
, theta = circle.theta
|
||||
, ct = circle.cos
|
||||
, st = circle.sin
|
||||
var circle = unitCircle(a, b)
|
||||
var theta = circle.theta
|
||||
var ct = circle.cos
|
||||
var st = circle.sin
|
||||
|
||||
// Work out the transformation parameters
|
||||
var signX = Math.sign(a * ct + b * st)
|
||||
, sx = signX * mag (a, b)
|
||||
, lam = (st * d + ct * c) / (ct * a + st * b)
|
||||
, signY = Math.sign(- c * st + d * ct)
|
||||
, sy = mag (lam * a - c, d - lam * b)
|
||||
, tx = e - cx + cx * ct * sx + cy * (lam * ct * sx - st * sy)
|
||||
, ty = f - cy + cx * st * sx + cy * (lam * st * sx + ct * sy)
|
||||
var sx = signX * mag(a, b)
|
||||
var lam = (st * d + ct * c) / (ct * a + st * b)
|
||||
var sy = mag(lam * a - c, d - lam * b)
|
||||
var tx = e - cx + cx * ct * sx + cy * (lam * ct * sx - st * sy)
|
||||
var ty = f - cy + cx * st * sx + cy * (lam * st * sx + ct * sy)
|
||||
|
||||
// Package and return the parameters
|
||||
return {
|
||||
|
||||
// Bundle the affine parameters
|
||||
translateX: tx
|
||||
, translateY: ty
|
||||
, theta: theta
|
||||
, scaleX: sx
|
||||
, scaleY: sy
|
||||
, shear: lam
|
||||
translateX: tx,
|
||||
translateY: ty,
|
||||
theta: theta,
|
||||
scaleX: sx,
|
||||
scaleY: sy,
|
||||
shear: lam,
|
||||
|
||||
// Bundle the matrix parameters
|
||||
, a: this.a
|
||||
, b: this.b
|
||||
, c: this.c
|
||||
, d: this.d
|
||||
, e: this.e
|
||||
, f: this.f
|
||||
|
||||
// Return the new origin point
|
||||
, x: this.e
|
||||
, y: this.f
|
||||
|
||||
// Store the matrix
|
||||
, matrix: new SVG.Matrix(this)
|
||||
// translation
|
||||
x: this.e,
|
||||
y: this.f,
|
||||
transformedX: (this.e * Math.cos(skewX * Math.PI / 180) + this.f * Math.sin(skewX * Math.PI / 180)) / Math.sqrt(this.a * this.a + this.b * this.b),
|
||||
transformedY: (this.f * Math.cos(skewX * Math.PI / 180) + this.e * Math.sin(-skewX * Math.PI / 180)) / Math.sqrt(this.c * this.c + this.d * this.d),
|
||||
// skew
|
||||
skewX: -skewX,
|
||||
skewY: 180 / Math.PI * Math.atan2(py.y, py.x),
|
||||
// scale
|
||||
scaleX: Math.sqrt(this.a * this.a + this.b * this.b),
|
||||
scaleY: Math.sqrt(this.c * this.c + this.d * this.d),
|
||||
// rotation
|
||||
rotation: skewX,
|
||||
a: this.a,
|
||||
b: this.b,
|
||||
c: this.c,
|
||||
d: this.d,
|
||||
e: this.e,
|
||||
f: this.f,
|
||||
|
||||
// Return the new origin point
|
||||
x: this.e,
|
||||
y: this.f,
|
||||
matrix: new SVG.Matrix(this)
|
||||
>>>>>>> 3.0.0
|
||||
}
|
||||
},
|
||||
// Clone matrix
|
||||
, form: function (o) {
|
||||
|
||||
// Get all of the parameters required to form the matrix
|
||||
var flipX = o.flip && (o.flip == "x" || o.flip == "both") ? -1 : 1
|
||||
, flipY = o.flip && (o.flip == "y" || o.flip == "both") ? -1 : 1
|
||||
, kX = o.skew.length ? o.skew[0]
|
||||
form: function (o) {
|
||||
// Get all of the parameters required to form the matrix
|
||||
var flipX = o.flip && (o.flip === 'x' || o.flip === 'both') ? -1 : 1
|
||||
var flipY = o.flip && (o.flip === 'y' || o.flip === 'both') ? -1 : 1
|
||||
var skewX = o.skew.length ? o.skew[0]
|
||||
: isFinite(o.skew) ? o.skew
|
||||
: isFinite(o.skewX) ? o.skewX
|
||||
: 0
|
||||
, kY = o.skew.length ? o.skew[1]
|
||||
var skewY = o.skew.length ? o.skew[1]
|
||||
: isFinite(o.skew) ? o.skew
|
||||
: isFinite(o.skewY) ? o.skewY
|
||||
: 0
|
||||
, skewX = o.scale.length ? o.scale[0] * flipX
|
||||
var sx = o.scale.length ? o.scale[0] * flipX
|
||||
: isFinite(o.scale) ? o.scale * flipX
|
||||
: isFinite(o.scaleX) ? o.scaleX * flipX
|
||||
: flipX
|
||||
, skewY = o.scale.length ? o.scale[1] * flipY
|
||||
var sy = o.scale.length ? o.scale[1] * flipY
|
||||
: isFinite(o.scale) ? o.scale * flipY
|
||||
: isFinite(o.scaleY) ? o.scaleY * flipY
|
||||
: flipY
|
||||
, kx = Math.tan(SVG.utils.radians(skewX))
|
||||
, ky = Math.tan(SVG.utils.radians(skewY))
|
||||
, lam = o.shear || 0
|
||||
, theta = SVG.utils.radians(o.rotate || 0)
|
||||
, st = Math.sin(theta)
|
||||
, ct = Math.cos(theta)
|
||||
, ox = o.origin.length ? o.origin[0] : o.ox || 0
|
||||
, oy = o.origin.length ? o.origin[1] : o.oy || 0
|
||||
, px = o.position.length ? o.position[0] : o.px || ox
|
||||
, py = o.position.length ? o.position[1] : o.py || oy
|
||||
, tx = o.translate.length ? o.translate[0] : o.tx || 0
|
||||
, ty = o.translate.length ? o.translate[1] : o.ty || 0
|
||||
var kx = Math.tan(SVG.utils.radians(skewX))
|
||||
var ky = Math.tan(SVG.utils.radians(skewY))
|
||||
var lam = o.shear || 0
|
||||
var theta = SVG.utils.radians(o.rotate || 0)
|
||||
var st = Math.sin(theta)
|
||||
var ct = Math.cos(theta)
|
||||
var ox = o.origin.length ? o.origin[0] : o.ox || 0
|
||||
var oy = o.origin.length ? o.origin[1] : o.oy || 0
|
||||
var px = o.position.length ? o.position[0] : o.px || ox
|
||||
var py = o.position.length ? o.position[1] : o.py || oy
|
||||
var tx = o.translate.length ? o.translate[0] : o.tx || 0
|
||||
var ty = o.translate.length ? o.translate[1] : o.ty || 0
|
||||
|
||||
// Form the matrix parameters... aka. welcome to wonderland! (used wolfram)
|
||||
var a = ct*sx + ky*st*sy
|
||||
, b = ct*ky*sy - st*sx
|
||||
, c = ct*kx*sx + st*sy + lam*(ct*sx+ky*st*sy)
|
||||
, d = -kx*st*sx + ct*sy + lam*(-st*sx + ct*ky*sy)
|
||||
, e = px + tx + cx*(ct*sx+ky*st*sy) + cy*(ct*kx*sx+st*sy+lam*(ct*sx+ky*st*sy))
|
||||
, f = py + ty + cx*(-st*sx + ct*ky*sy) + cy*(-kx*st*sx + ct*sy + lam*(-st*sx + ct*ky*sy))
|
||||
, result = new Matrix(a, b, c, d, e, f)
|
||||
return result
|
||||
}
|
||||
, clone: function() {
|
||||
var a = ct * sx + ky * st * sy
|
||||
var b = ct * ky * sy - st * sx
|
||||
var c = ct * kx * sx + st * sy + lam * (ct * sx + ky * st * sy)
|
||||
var d = -kx * st * sx + ct * sy + lam * (-st * sx + ct * ky * sy)
|
||||
var e = px + tx + ox * (ct * sx + ky * st * sy) + oy * (ct * kx * sx + st * sy + lam * (ct * sx + ky * st * sy))
|
||||
var f = py + ty + ox * (-st * sx + ct * ky * sy) + oy * (-kx * st * sx + ct * sy + lam * (-st * sx + ct * ky * sy))
|
||||
var result = new SVG.Matrix(a, b, c, d, e, f)
|
||||
return result
|
||||
},
|
||||
clone: function () {
|
||||
>>>>>>> 3.0.0
|
||||
return new SVG.Matrix(this)
|
||||
},
|
||||
// Morph one matrix into another
|
||||
@ -211,15 +182,15 @@ SVG.Matrix = SVG.invent({
|
||||
return new SVG.Matrix(this.native().inverse())
|
||||
},
|
||||
// Translate matrix
|
||||
, translate: function(x, y) {
|
||||
var translation = new SVG.Matrix(this.native().translate(x || 0, y || 0))
|
||||
, matrix = this.multiply(translation)
|
||||
translate: function (x, y) {
|
||||
var translation = new SVG.Matrix(this.native().translate(x || 0, y || 0))
|
||||
var matrix = this.multiply(translation)
|
||||
return matrix
|
||||
}
|
||||
},
|
||||
// Scale matrix
|
||||
, scale: function(x, y, cx, cy) {
|
||||
scale: function (x, y, cx, cy) {
|
||||
// Support uniform scaling
|
||||
if (arguments.length == 1) {
|
||||
if (arguments.length === 1) {
|
||||
y = x
|
||||
} else if (arguments.length === 3) {
|
||||
cy = cx
|
||||
@ -229,22 +200,21 @@ SVG.Matrix = SVG.invent({
|
||||
|
||||
// Rotate the current matrix
|
||||
var scale = new SVG.Matrix(x, 0, 0, y, 0, 0)
|
||||
, centered = this.around(cx, cy, rotation)
|
||||
, matrix = this.multiply(centered)
|
||||
return scale
|
||||
}
|
||||
var centered = this.around(cx, cy, scale)
|
||||
var matrix = this.multiply(centered)
|
||||
return matrix
|
||||
},
|
||||
// Rotate matrix
|
||||
, rotate: function(r, cx, cy) {
|
||||
|
||||
rotate: function (r, cx, cy) {
|
||||
// Convert degrees to radians
|
||||
r = SVG.utils.radians(r)
|
||||
|
||||
// Construct the rotation matrix
|
||||
var rotation = new SVG.Matrix(Math.cos(r), Math.sin(r), -Math.sin(r), Math.cos(r), 0, 0)
|
||||
, centered = this.around(cx, cy, rotation)
|
||||
, matrix = this.multiply(centered)
|
||||
var centered = this.around(cx, cy, rotation)
|
||||
var matrix = this.multiply(centered)
|
||||
return matrix
|
||||
}
|
||||
},
|
||||
// Flip matrix on x or y, at a given offset
|
||||
flip: function (a, o) {
|
||||
return a === 'x' ? this.scale(-1, 1, o, 0)
|
||||
@ -252,13 +222,13 @@ SVG.Matrix = SVG.invent({
|
||||
: this.scale(-1, -1, a, o != null ? o : a)
|
||||
},
|
||||
// Skew
|
||||
, shear: function(a, cx, cy) {
|
||||
var shear = new SVG.Matrix(1, a, 0, 1, 0, 0)
|
||||
, centered = this.around(cx, cy, shear)
|
||||
, matrix = this.multiply(centered)
|
||||
return matrix
|
||||
}
|
||||
, skew: function(x, y, cx, cy) {
|
||||
shear: function (a, cx, cy) {
|
||||
var shear = new SVG.Matrix(1, a, 0, 1, 0, 0)
|
||||
var centered = this.around(cx, cy, shear)
|
||||
var matrix = this.multiply(centered)
|
||||
return matrix
|
||||
},
|
||||
skew: function (x, y, cx, cy) {
|
||||
// support uniformal skew
|
||||
if (arguments.length === 1) {
|
||||
y = x
|
||||
@ -274,10 +244,10 @@ SVG.Matrix = SVG.invent({
|
||||
|
||||
// Construct the matrix
|
||||
var skew = new SVG.Matrix(1, Math.tan(y), Math.tan(x), 1, 0, 0)
|
||||
, centered = this.around(cx, cy, skew)
|
||||
, matrix = this.multiply(centered)
|
||||
var centered = this.around(cx, cy, skew)
|
||||
var matrix = this.multiply(centered)
|
||||
return matrix
|
||||
}
|
||||
},
|
||||
// SkewX
|
||||
skewX: function (x, cx, cy) {
|
||||
return this.skew(x, 0, cx, cy)
|
||||
|
18
src/sugar.js
18
src/sugar.js
@ -35,17 +35,17 @@ var sugar = {
|
||||
|
||||
SVG.extend([SVG.Element, SVG.FX], {
|
||||
// Map rotation to transform
|
||||
, rotate: function(angle, cx, cy) {
|
||||
rotate: function (angle, cx, cy) {
|
||||
var matrix = new SVG.Matrix().rotate(angle, cx, cy)
|
||||
|
||||
return this.transform({ rotation: d, cx: cx, cy: cy })
|
||||
return this.matrix(matrix, true)
|
||||
},
|
||||
// Map skew to transform
|
||||
, skew: function(x, y, cx, cy) {
|
||||
return arguments.length == 1 || arguments.length == 3 ?
|
||||
this.transform({ skew: x, cx: y, cy: cx }) :
|
||||
this.transform({ skewX: x, skewY: y, cx: cx, cy: cy })
|
||||
}
|
||||
skew: function (x, y, cx, cy) {
|
||||
var matrix = arguments.length === 1 || arguments.length === 3
|
||||
? new SVG.Matrix().skew(x, x, cx, cy)
|
||||
: new SVG.Matrix().skew(x, y, cx, cy)
|
||||
return this.matrix(matrix, true)
|
||||
},
|
||||
// Map scale to transform
|
||||
scale: function (x, y, cx, cy) {
|
||||
return arguments.length === 1 || arguments.length === 3
|
||||
@ -60,7 +60,7 @@ SVG.extend([SVG.Element, SVG.FX], {
|
||||
flip: function (a, o) {
|
||||
o = typeof a === 'number' ? a : o
|
||||
return this.transform({ flip: a || 'both', offset: o })
|
||||
}
|
||||
},
|
||||
// Opacity
|
||||
opacity: function (value) {
|
||||
return this.attr('opacity', value)
|
||||
|
404
src/transform.js
404
src/transform.js
@ -1,37 +1,72 @@
|
||||
/* global ensureCentre, capitalize, arrayToMatrix */
|
||||
/* global arrayToMatrix */
|
||||
|
||||
SVG.extend(SVG.Element, {
|
||||
// Reset all transformations
|
||||
untransform: function () {
|
||||
return this.attr('transform', null)
|
||||
},
|
||||
|
||||
// merge the whole transformation chain into one matrix and returns it
|
||||
matrixify: function () {
|
||||
var matrix = (this.attr('transform') || '')
|
||||
// split transformations
|
||||
.split(SVG.regex.transforms).slice(0, -1).map(function (str) {
|
||||
// generate key => value pairs
|
||||
var kv = str.trim().split('(')
|
||||
return [kv[0], kv[1].split(SVG.regex.delimiter).map(function (str) { return parseFloat(str) })]
|
||||
})
|
||||
// merge every transformation into one matrix
|
||||
.reduce(function (matrix, transform) {
|
||||
if (transform[0] === 'matrix') return matrix.multiply(arrayToMatrix(transform[1]))
|
||||
return matrix[transform[0]].apply(matrix, transform[1])
|
||||
}, new SVG.Matrix())
|
||||
|
||||
return matrix
|
||||
},
|
||||
|
||||
// add an element to another parent without changing the visual representation on the screen
|
||||
toParent: function (parent) {
|
||||
if (this === parent) return this
|
||||
var ctm = this.screenCTM()
|
||||
var pCtm = parent.screenCTM().inverse()
|
||||
|
||||
this.addTo(parent).untransform().transform(pCtm.multiply(ctm))
|
||||
|
||||
return this
|
||||
},
|
||||
|
||||
// same as above with parent equals root-svg
|
||||
toDoc: function () {
|
||||
return this.toParent(this.doc())
|
||||
}
|
||||
})
|
||||
|
||||
SVG.extend(SVG.Element, {
|
||||
|
||||
// Add transformations
|
||||
transform: function (o) {
|
||||
|
||||
/**
|
||||
* EXTRACTING PARAMETERS
|
||||
*/
|
||||
|
||||
// Act as a getter if no object was passed
|
||||
if (typeof o !== 'object') {
|
||||
matrix = new SVG.Matrix(this).extract()
|
||||
var matrix = new SVG.Matrix(this).decompose()
|
||||
return typeof o === 'string' ? matrix[o] : matrix
|
||||
}
|
||||
|
||||
// Allow the user to define the origin with a string
|
||||
if (typeof o.origin === "string") {
|
||||
|
||||
if (typeof o.origin === 'string') {
|
||||
// Get the bounding box and string to use in our calculations
|
||||
var string = o.origin.toLowerCase().trim()
|
||||
, bbox = this.bbox()
|
||||
, x = bbox.x
|
||||
, y = bbox.y
|
||||
, width = bbox.width
|
||||
, height = bbox.height
|
||||
var bbox = this.bbox()
|
||||
var x = bbox.x
|
||||
var y = bbox.y
|
||||
var width = bbox.width
|
||||
var height = bbox.height
|
||||
|
||||
// Set the bounds eg : "bottom-left", "Top right", "middle" etc...
|
||||
o.ox = string.includes("left") ? x
|
||||
: string.includes("right") ? x + width
|
||||
o.ox = string.includes('left') ? x
|
||||
: string.includes('right') ? x + width
|
||||
: x + width / 2
|
||||
o.oy = string.includes("top") ? y
|
||||
: string.includes("bottom") ? y + height
|
||||
o.oy = string.includes('top') ? y
|
||||
: string.includes('bottom') ? y + height
|
||||
: y + height / 2
|
||||
|
||||
// Make sure we only pass ox and oy
|
||||
@ -40,71 +75,14 @@ SVG.extend(SVG.Element, {
|
||||
|
||||
// Get the resulting matrix and apply it to the element
|
||||
var result = new SVG.Matrix().form(o)
|
||||
, matrixString = result.toString()
|
||||
// get current matrix
|
||||
matrix = new SVG.Matrix(target)
|
||||
|
||||
// ensure relative flag
|
||||
relative = !!relative || !!o.relative
|
||||
|
||||
// act on matrix
|
||||
if (o.a != null) {
|
||||
matrix = relative
|
||||
? matrix.multiply(new SVG.Matrix(o))
|
||||
: new SVG.Matrix(o)
|
||||
|
||||
// act on rotation
|
||||
} else if (o.rotation != null) {
|
||||
// ensure centre point
|
||||
ensureCentre(o, target)
|
||||
|
||||
// apply transformation
|
||||
matrix = relative
|
||||
? matrix.rotate(o.rotation, o.cx, o.cy)
|
||||
: matrix.rotate(o.rotation - matrix.extract().rotation, o.cx, o.cy)
|
||||
|
||||
// act on scale
|
||||
} else if (o.scale != null || o.scaleX != null || o.scaleY != null) {
|
||||
// ensure centre point
|
||||
ensureCentre(o, target)
|
||||
|
||||
// ensure scale values on both axes
|
||||
o.scaleX = o.scale != null ? o.scale : o.scaleX != null ? o.scaleX : 1
|
||||
o.scaleY = o.scale != null ? o.scale : o.scaleY != null ? o.scaleY : 1
|
||||
|
||||
if (!relative) {
|
||||
// absolute; multiply inversed values
|
||||
var e = matrix.extract()
|
||||
o.scaleX = o.scaleX * 1 / e.scaleX
|
||||
o.scaleY = o.scaleY * 1 / e.scaleY
|
||||
}
|
||||
|
||||
matrix = matrix.scale(o.scaleX, o.scaleY, o.cx, o.cy)
|
||||
|
||||
// act on skew
|
||||
} else if (o.skew != null || o.skewX != null || o.skewY != null) {
|
||||
// ensure centre point
|
||||
ensureCentre(o, target)
|
||||
|
||||
// ensure skew values on both axes
|
||||
o.skewX = o.skew != null ? o.skew : o.skewX != null ? o.skewX : 0
|
||||
o.skewY = o.skew != null ? o.skew : o.skewY != null ? o.skewY : 0
|
||||
|
||||
if (!relative) {
|
||||
// absolute; reset skew values
|
||||
var el = matrix.extract()
|
||||
matrix = matrix.multiply(new SVG.Matrix().skew(el.skewX, el.skewY, el.cx, el.cy).inverse())
|
||||
}
|
||||
>>>>>>> 3.0.0
|
||||
var matrixString = result.toString()
|
||||
|
||||
// Apply the result
|
||||
return this.attr('transform', matrix)
|
||||
}
|
||||
}
|
||||
return this.attr('transform', matrixString)
|
||||
},
|
||||
|
||||
// Map matrix to transform
|
||||
, matrix: function(m, relative) {
|
||||
|
||||
matrix: function (m, relative) {
|
||||
// Construct a matrix from the first parameter
|
||||
var matrix = new SVG.Matrix(m)
|
||||
|
||||
@ -120,10 +98,7 @@ SVG.extend(SVG.Element, {
|
||||
})
|
||||
|
||||
SVG.extend(SVG.FX, {
|
||||
transform: function(o, relative) {
|
||||
|
||||
|
||||
|
||||
transform: function (o, relative) {
|
||||
|
||||
// // get target in case of the fx module, otherwise reference this
|
||||
// var target = this.target()
|
||||
@ -203,90 +178,51 @@ SVG.extend(SVG.FX, {
|
||||
//
|
||||
// return this._callStart()
|
||||
// }
|
||||
// ensure scale values on both axes
|
||||
o.scaleX = o.scale != null ? o.scale : o.scaleX != null ? o.scaleX : 1
|
||||
o.scaleY = o.scale != null ? o.scale : o.scaleY != null ? o.scaleY : 1
|
||||
|
||||
matrix = new SVG.Scale(o.scaleX, o.scaleY, o.cx, o.cy)
|
||||
|
||||
// act on skew
|
||||
} else if (o.skewX != null || o.skewY != null) {
|
||||
// ensure centre point
|
||||
ensureCentre(o, target)
|
||||
|
||||
// ensure skew values on both axes
|
||||
o.skewX = o.skewX != null ? o.skewX : 0
|
||||
o.skewY = o.skewY != null ? o.skewY : 0
|
||||
|
||||
matrix = new SVG.Skew(o.skewX, o.skewY, o.cx, o.cy)
|
||||
|
||||
// act on flip
|
||||
} else if (o.flip) {
|
||||
if (o.flip === 'x' || o.flip === 'y') {
|
||||
o.offset = o.offset == null ? target.bbox()['c' + o.flip] : o.offset
|
||||
} else {
|
||||
if (o.offset == null) {
|
||||
bbox = target.bbox()
|
||||
o.flip = bbox.cx
|
||||
o.offset = bbox.cy
|
||||
} else {
|
||||
o.flip = o.offset
|
||||
}
|
||||
}
|
||||
|
||||
matrix = new SVG.Matrix().flip(o.flip, o.offset)
|
||||
|
||||
// act on translate
|
||||
} else if (o.x != null || o.y != null) {
|
||||
matrix = new SVG.Translate(o.x, o.y)
|
||||
}
|
||||
|
||||
if (!matrix) return this
|
||||
|
||||
matrix.relative = relative
|
||||
|
||||
this.last().transforms.push(matrix)
|
||||
|
||||
return this._callStart()
|
||||
}
|
||||
>>>>>>> 3.0.0
|
||||
})
|
||||
|
||||
SVG.extend(SVG.Element, {
|
||||
// Reset all transformations
|
||||
untransform: function () {
|
||||
return this.attr('transform', null)
|
||||
},
|
||||
// merge the whole transformation chain into one matrix and returns it
|
||||
matrixify: function () {
|
||||
var matrix = (this.attr('transform') || '')
|
||||
// split transformations
|
||||
.split(SVG.regex.transforms).slice(0, -1).map(function (str) {
|
||||
// generate key => value pairs
|
||||
var kv = str.trim().split('(')
|
||||
return [kv[0], kv[1].split(SVG.regex.delimiter).map(function (str) { return parseFloat(str) })]
|
||||
})
|
||||
// merge every transformation into one matrix
|
||||
.reduce(function (matrix, transform) {
|
||||
if (transform[0] === 'matrix') return matrix.multiply(arrayToMatrix(transform[1]))
|
||||
return matrix[transform[0]].apply(matrix, transform[1])
|
||||
}, new SVG.Matrix())
|
||||
|
||||
return matrix
|
||||
},
|
||||
// add an element to another parent without changing the visual representation on the screen
|
||||
toParent: function (parent) {
|
||||
if (this === parent) return this
|
||||
var ctm = this.screenCTM()
|
||||
var pCtm = parent.screenCTM().inverse()
|
||||
|
||||
this.addTo(parent).untransform().transform(pCtm.multiply(ctm))
|
||||
|
||||
return this
|
||||
},
|
||||
// same as above with parent equals root-svg
|
||||
toDoc: function () {
|
||||
return this.toParent(this.doc())
|
||||
// // ensure scale values on both axes
|
||||
// o.scaleX = o.scale != null ? o.scale : o.scaleX != null ? o.scaleX : 1
|
||||
// o.scaleY = o.scale != null ? o.scale : o.scaleY != null ? o.scaleY : 1
|
||||
//
|
||||
// matrix = new SVG.Scale(o.scaleX, o.scaleY, o.cx, o.cy)
|
||||
//
|
||||
// // act on skew
|
||||
// } else if (o.skewX != null || o.skewY != null) {
|
||||
// // ensure centre point
|
||||
// ensureCentre(o, target)
|
||||
//
|
||||
// // ensure skew values on both axes
|
||||
// o.skewX = o.skewX != null ? o.skewX : 0
|
||||
// o.skewY = o.skewY != null ? o.skewY : 0
|
||||
//
|
||||
// matrix = new SVG.Skew(o.skewX, o.skewY, o.cx, o.cy)
|
||||
//
|
||||
// // act on flip
|
||||
// } else if (o.flip) {
|
||||
// if (o.flip === 'x' || o.flip === 'y') {
|
||||
// o.offset = o.offset == null ? target.bbox()['c' + o.flip] : o.offset
|
||||
// } else {
|
||||
// if (o.offset == null) {
|
||||
// bbox = target.bbox()
|
||||
// o.flip = bbox.cx
|
||||
// o.offset = bbox.cy
|
||||
// } else {
|
||||
// o.flip = o.offset
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// matrix = new SVG.Matrix().flip(o.flip, o.offset)
|
||||
//
|
||||
// // act on translate
|
||||
// } else if (o.x != null || o.y != null) {
|
||||
// matrix = new SVG.Translate(o.x, o.y)
|
||||
// }
|
||||
//
|
||||
// if (!matrix) return this
|
||||
//
|
||||
// matrix.relative = relative
|
||||
//
|
||||
// this.last().transforms.push(matrix)
|
||||
//
|
||||
// return this._callStart()
|
||||
}
|
||||
})
|
||||
|
||||
@ -432,137 +368,3 @@ SVG.extend(SVG.Element, {
|
||||
// }
|
||||
//
|
||||
// })
|
||||
SVG.Transformation = SVG.invent({
|
||||
|
||||
create: function (source, inversed) {
|
||||
if (arguments.length > 1 && typeof inversed !== 'boolean') {
|
||||
return this.constructor.bind(this)([].slice.call(arguments))
|
||||
}
|
||||
|
||||
var i, len
|
||||
if (Array.isArray(source)) {
|
||||
for (i = 0, len = this.arguments.length; i < len; ++i) {
|
||||
this[this.arguments[i]] = source[i]
|
||||
}
|
||||
} else if (typeof source === 'object') {
|
||||
for (i = 0, len = this.arguments.length; i < len; ++i) {
|
||||
this[this.arguments[i]] = source[this.arguments[i]]
|
||||
}
|
||||
}
|
||||
|
||||
this.inversed = false
|
||||
|
||||
if (inversed === true) {
|
||||
this.inversed = true
|
||||
}
|
||||
},
|
||||
|
||||
extend: {
|
||||
|
||||
arguments: [],
|
||||
method: '',
|
||||
|
||||
at: function (pos) {
|
||||
var params = []
|
||||
|
||||
for (var i = 0, len = this.arguments.length; i < len; ++i) {
|
||||
params.push(this[this.arguments[i]])
|
||||
}
|
||||
|
||||
var m = this._undo || new SVG.Matrix()
|
||||
|
||||
m = new SVG.Matrix().morph(SVG.Matrix.prototype[this.method].apply(m, params)).at(pos)
|
||||
|
||||
return this.inversed ? m.inverse() : m
|
||||
},
|
||||
|
||||
undo: function (o) {
|
||||
for (var i = 0, len = this.arguments.length; i < len; ++i) {
|
||||
o[this.arguments[i]] = typeof this[this.arguments[i]] === 'undefined' ? 0 : o[this.arguments[i]]
|
||||
}
|
||||
|
||||
// The method SVG.Matrix.extract which was used before calling this
|
||||
// method to obtain a value for the parameter o doesn't return a cx and
|
||||
// a cy so we use the ones that were provided to this object at its creation
|
||||
o.cx = this.cx
|
||||
o.cy = this.cy
|
||||
|
||||
this._undo = new SVG[capitalize(this.method)](o, true).at(1)
|
||||
return this
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
SVG.Translate = SVG.invent({
|
||||
|
||||
parent: SVG.Matrix,
|
||||
inherit: SVG.Transformation,
|
||||
|
||||
create: function (source, inversed) {
|
||||
this.constructor.apply(this, [].slice.call(arguments))
|
||||
},
|
||||
|
||||
extend: {
|
||||
arguments: ['transformedX', 'transformedY'],
|
||||
method: 'translate'
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
SVG.Rotate = SVG.invent({
|
||||
|
||||
parent: SVG.Matrix,
|
||||
inherit: SVG.Transformation,
|
||||
|
||||
create: function (source, inversed) {
|
||||
this.constructor.apply(this, [].slice.call(arguments))
|
||||
},
|
||||
|
||||
extend: {
|
||||
arguments: ['rotation', 'cx', 'cy'],
|
||||
method: 'rotate',
|
||||
at: function (pos) {
|
||||
var m = new SVG.Matrix().rotate(new SVG.Number().morph(this.rotation - (this._undo ? this._undo.rotation : 0)).at(pos), this.cx, this.cy)
|
||||
return this.inversed ? m.inverse() : m
|
||||
},
|
||||
undo: function (o) {
|
||||
this._undo = o
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
SVG.Scale = SVG.invent({
|
||||
|
||||
parent: SVG.Matrix,
|
||||
inherit: SVG.Transformation,
|
||||
|
||||
create: function (source, inversed) {
|
||||
this.constructor.apply(this, [].slice.call(arguments))
|
||||
},
|
||||
|
||||
extend: {
|
||||
arguments: ['scaleX', 'scaleY', 'cx', 'cy'],
|
||||
method: 'scale'
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
SVG.Skew = SVG.invent({
|
||||
|
||||
parent: SVG.Matrix,
|
||||
inherit: SVG.Transformation,
|
||||
|
||||
create: function (source, inversed) {
|
||||
this.constructor.apply(this, [].slice.call(arguments))
|
||||
},
|
||||
|
||||
extend: {
|
||||
arguments: ['skewX', 'skewY', 'cx', 'cy'],
|
||||
method: 'skew'
|
||||
}
|
||||
})
|
||||
>>>>>>> 3.0.0
|
||||
|
@ -1,3 +1,4 @@
|
||||
|
||||
SVG.utils = {
|
||||
// Map function
|
||||
map: function (array, block) {
|
||||
|
불러오는 중...
Reference in New Issue
Block a user