From: Ulrich-Matthias Schäfer Date: Wed, 12 Dec 2018 22:21:10 +0000 (+0100) Subject: Release 3.0.5 X-Git-Tag: 3.0.5^0 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=33e82b796e7870a9523b6e9653877a2613f8f7a2;p=svg.js.git Release 3.0.5 --- diff --git a/.config/karma.es6.js b/.config/karma.es6.js index 7a7a875..81605cf 100644 --- a/.config/karma.es6.js +++ b/.config/karma.es6.js @@ -33,7 +33,7 @@ module.exports = function (config) { type: 'module' }, { - pattern: 'spec/spec/types/*.js', + pattern: 'spec/spec/*/*.js', included: true, type: 'module' } diff --git a/.config/rollup.tests.js b/.config/rollup.tests.js index 518be94..e524a79 100644 --- a/.config/rollup.tests.js +++ b/.config/rollup.tests.js @@ -2,7 +2,10 @@ import babel from 'rollup-plugin-babel' import multiEntry from 'rollup-plugin-multi-entry' export default { - input: ['spec/setupBrowser.js', 'spec/spec/types/*.js', 'spec/spec/utils/*.js'], + input: [ + 'spec/setupBrowser.js', + 'spec/spec/*/*.js' + ], output: { file: 'spec/es5TestBundle.js', name: 'SVGTests', diff --git a/CHANGELOG.md b/CHANGELOG.md index b53f179..ad3da1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,13 @@ The document follows the conventions described in [“Keep a CHANGELOG”](http: ==== +## [3.0.5] - 2018-12-12 + - fixed `parser` which didnt have all reqired css rules and not focusable=false + - group `x(), y(), width(), height(), dx(), dy()` now correctly change the bbox of the group by moving/resizing all children + - fixed timeline which fired `finished` to early + - fixed `Animator.frame()`. The passed callback gets the current time now (same as RAF) + - allow `loop(true)` which is the same as `loop()` + ## [3.0.4] - 2018-12-07 ### Fixed @@ -754,6 +761,7 @@ The document follows the conventions described in [“Keep a CHANGELOG”](http: +[3.0.5]: https://github.com/svgdotjs/svg.js/releases/tag/3.0.5 [3.0.4]: https://github.com/svgdotjs/svg.js/releases/tag/3.0.4 [3.0.3]: https://github.com/svgdotjs/svg.js/releases/tag/3.0.3 [3.0.2]: https://github.com/svgdotjs/svg.js/releases/tag/3.0.2 diff --git a/package.json b/package.json index 6485a38..1068ae9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@svgdotjs/svg.js", - "version": "3.0.4", + "version": "3.0.5", "description": "A lightweight library for manipulating and animating SVG.", "url": "https://svgdotjs.github.io/", "homepage": "https://svgdotjs.github.io/", @@ -64,7 +64,7 @@ "test:svgdom": "node -r esm ./spec/runSVGDomTest.js || true", "test:es6": "npx karma start .config/karma.es6.js --single-run", "zip": "zip -j dist/svg.js.zip -- LICENSE.txt README.md CHANGELOG.md dist/svg.js dist/svg.js.map dist/svg.min.js dist/svg.min.js.map dist/polyfills.js dist/polyfillsIE.js", - "prepublishOnly": "rm -r ./dist && npm run build && npm run build:polyfills && npm test", + "prepublishOnly": "rm -rf ./dist && npm run build && npm run build:polyfills && npm test", "postpublish": "npm run zip" }, "devDependencies": { diff --git a/spec/SpecRunner.html b/spec/SpecRunner.html index da55e82..a1c6249 100644 --- a/spec/SpecRunner.html +++ b/spec/SpecRunner.html @@ -56,7 +56,7 @@ - + diff --git a/spec/SpecRunnerEs6.html b/spec/SpecRunnerEs6.html index cca33c0..3f8f90a 100644 --- a/spec/SpecRunnerEs6.html +++ b/spec/SpecRunnerEs6.html @@ -25,6 +25,7 @@ + diff --git a/spec/runSVGDomTest.js b/spec/runSVGDomTest.js index 0db744d..57055f4 100644 --- a/spec/runSVGDomTest.js +++ b/spec/runSVGDomTest.js @@ -12,7 +12,8 @@ jasmine.loadConfig({ "spec_dir": "spec/", "spec_files": [ "spec/types/*.js", - "spec/utils/*.js" + "spec/utils/*.js", + "spec/elements/*.js" ], "helpers": [ "setupSVGDom.js" diff --git a/spec/spec/elements/G.js b/spec/spec/elements/G.js new file mode 100644 index 0000000..2c2efc8 --- /dev/null +++ b/spec/spec/elements/G.js @@ -0,0 +1,139 @@ +import { G, Rect, makeInstance } from '../../../src/main'; + +const { any, createSpy, objectContaining } = jasmine + + +describe('G.js', () => { + + describe('()', () => { + it('creates a new object of type G', () => { + expect(new G()).toEqual(any(G)) + }) + + it('sets passed attributes on the element', () => { + expect(new G({id:'foo'}).id()).toBe('foo') + }) + }) + + describe('x()', () => { + it('gets the x value of the bbox', () => { + const canvas = makeInstance().addTo('#canvas') + + const g = new G() + g.add(new Rect({width:100, height:120, x:10, y:20})) + g.add(new Rect({width:70, height:100, x:50, y:60})) + + g.addTo(canvas) + + expect(g.x()).toBe(g.bbox().x) + expect(g.x()).toBe(10) + }) + it('sets the x value of the bbox by moving all children', () => { + const canvas = makeInstance().addTo('#canvas') + + const g = new G() + g.add(new Rect({width:100, height:120, x:10, y:20})) + g.add(new Rect({width:70, height:100, x:50, y:60})) + + g.addTo(canvas) + + expect(g.x(0)).toBe(g) + expect(g.bbox().x).toBe(0) + expect(g.children()[0].x()).toBe(0) + expect(g.children()[1].x()).toBe(40) + }) + }) + + describe('y()', () => { + it('gets the y value of the bbox', () => { + const canvas = makeInstance().addTo('#canvas') + + const g = new G() + g.add(new Rect({width:100, height:120, x:10, y:20})) + g.add(new Rect({width:70, height:100, x:50, y:60})) + + g.addTo(canvas) + + expect(g.y()).toBe(g.bbox().y) + expect(g.y()).toBe(20) + }) + it('sets the y value of the bbox by moving all children', () => { + const canvas = makeInstance().addTo('#canvas') + + const g = new G() + g.add(new Rect({width:100, height:120, x:10, y:20})) + g.add(new Rect({width:70, height:100, x:50, y:60})) + + g.addTo(canvas) + + expect(g.y(0)).toBe(g) + expect(g.bbox().y).toBe(0) + expect(g.children()[0].y()).toBe(0) + expect(g.children()[1].y()).toBe(40) + }) + }) + + describe('width()', () => { + it('gets the width value of the bbox', () => { + const canvas = makeInstance().addTo('#canvas') + + const g = new G() + g.add(new Rect({width:100, height:120, x:10, y:20})) + g.add(new Rect({width:70, height:100, x:50, y:60})) + + g.addTo(canvas) + + expect(g.width()).toBe(g.bbox().width) + expect(g.width()).toBe(110) + }) + it('sets the width value of the bbox by moving all children', () => { + const canvas = makeInstance().addTo('#canvas') + + const g = new G() + g.add(new Rect({width:100, height:120, x:10, y:20})) + g.add(new Rect({width:70, height:100, x:50, y:60})) + + g.addTo(canvas) + + expect(g.width(100)).toBe(g) + expect(g.bbox().width).toBe(100) + expect(g.children()[0].width()).toBeCloseTo(90.909, 3) + expect(g.children()[1].width()).toBeCloseTo(63.636, 3) + + expect(g.children()[0].x()).toBeCloseTo(10, 3) + expect(g.children()[1].x()).toBeCloseTo(46.364, 3) + }) + }) + + describe('height()', () => { + it('gets the height value of the bbox', () => { + const canvas = makeInstance().addTo('#canvas') + + const g = new G() + g.add(new Rect({width:100, height:120, x:10, y:20})) + g.add(new Rect({width:70, height:100, x:50, y:60})) + + g.addTo(canvas) + + expect(g.height()).toBe(g.bbox().height) + expect(g.height()).toBe(140) + }) + it('sets the height value of the bbox by moving all children', () => { + const canvas = makeInstance().addTo('#canvas') + + const g = new G() + g.add(new Rect({width:100, height:120, x:10, y:20})) + g.add(new Rect({width:70, height:100, x:50, y:60})) + + g.addTo(canvas) + + expect(g.height(100)).toBe(g) + expect(g.bbox().height).toBe(100) + expect(g.children()[0].height()).toBeCloseTo(85.714, 3) + expect(g.children()[1].height()).toBeCloseTo(71.429, 3) + + expect(g.children()[0].y()).toBeCloseTo(20, 3) + expect(g.children()[1].y()).toBeCloseTo(48.571, 3) + }) + }) +}) diff --git a/src/animation/Animator.js b/src/animation/Animator.js index 390b200..21c735c 100644 --- a/src/animation/Animator.js +++ b/src/animation/Animator.js @@ -83,7 +83,7 @@ const Animator = { var nextFrame = null var lastFrame = Animator.frames.last() while ((nextFrame !== lastFrame) && (nextFrame = Animator.frames.shift())) { - nextFrame.run() + nextFrame.run(now) } var nextImmediate = null diff --git a/src/animation/Runner.js b/src/animation/Runner.js index 8c26578..eebfb75 100644 --- a/src/animation/Runner.js +++ b/src/animation/Runner.js @@ -136,6 +136,10 @@ export default class Runner extends EventTarget { this._times = times || Infinity this._swing = swing || false this._wait = wait || 0 + + // Allow true to be passed + if (this._times === true) { this._times = Infinity } + return this } diff --git a/src/animation/Timeline.js b/src/animation/Timeline.js index f5460b3..66ba61f 100644 --- a/src/animation/Timeline.js +++ b/src/animation/Timeline.js @@ -40,7 +40,8 @@ export default class Timeline extends EventTarget { this._lastStepTime = 0 // Make sure that step is always called in class context - this._step = this._step.bind(this) + this._step = this._stepFn.bind(this, false) + this._stepImmediate = this._stepFn.bind(this, true) } // schedules a runner on the timeline @@ -184,7 +185,7 @@ export default class Timeline extends EventTarget { return this } - _step (immediateStep = false) { + _stepFn (immediateStep = false) { // Get the time delta from the last time and update the time var time = this._timeSource() var dtSource = time - this._lastSourceTime @@ -278,8 +279,8 @@ export default class Timeline extends EventTarget { if ((runnersLeft && !(this._speed < 0 && this._time === 0)) || (this._runnerIds.length && this._speed < 0 && this._time > 0)) { this._continue() } else { - this.fire('finished') this.pause() + this.fire('finished') } return this @@ -290,7 +291,7 @@ export default class Timeline extends EventTarget { Animator.cancelFrame(this._nextFrame) this._nextFrame = null - if (immediateStep) return this._step(true) + if (immediateStep) return this._stepImmediate() if (this._paused) return this this._nextFrame = Animator.frame(this._step) diff --git a/src/elements/Element.js b/src/elements/Element.js index 594daa1..ba15f52 100644 --- a/src/elements/Element.js +++ b/src/elements/Element.js @@ -55,6 +55,16 @@ export default class Element extends Dom { return this.root().defs() } + // Relative move over x axis + dx (x) { + return this.x(new SVGNumber(x).plus(this.x())) + } + + // Relative move over y axis + dy (y) { + return this.y(new SVGNumber(y).plus(this.y())) + } + // Get parent document root () { let p = this.parent(Svg) diff --git a/src/elements/G.js b/src/elements/G.js index 0a11c1e..8171fed 100644 --- a/src/elements/G.js +++ b/src/elements/G.js @@ -1,44 +1,80 @@ import { nodeOrNew, register, wrapWithAttrCheck } from '../utils/adopter.js' +import { proportionalSize } from '../utils/utils.js' import { registerMethods } from '../utils/methods.js' import Container from './Container.js' +import SVGNumber from '../types/SVGNumber.js' export default class G extends Container { constructor (node) { super(nodeOrNew('g', node), node) } - x (x) { - if (x == null) return this.transform()['x'] - return this.move(x, 0) + x (x, box = this.bbox()) { + if (x == null) return box.x + + this.children().dx(x - box.x) + return this } - y (y) { - if (y == null) return this.transform()['y'] - return this.move(0, y) + y (y, box = this.bbox()) { + if (y == null) return box.y + + this.children().dy(y - box.y) + return this } move (x, y) { - return this.translate(x, y) + const box = this.bbox() + return this.x(x, box).y(y, box) } dx (dx) { - return this.transform({ dx }, true) + return this.children().dx(dx) } dy (dy) { - return this.transform({ dy }, true) + return this.children().dy(dy) } - dmove (dx, dy) { - return this.transform({ dx, dy }, true) + width (width, box = this.bbox()) { + if (width == null) return box.width + + const scale = width / box.width + + this.each(function () { + const _width = this.width() + const _x = this.x() + + this.width(_width * scale) + this.x((_x - box.x) * scale + box.x) + }) + + return this } - width () { - return this.bbox().width + height (height, box = this.bbox()) { + if (height == null) return box.height + + const scale = height / box.height + + this.each(function () { + const _height = this.height() + const _y = this.y() + + this.height(_height * scale) + this.y((_y - box.y) * scale + box.y) + }) + + return this } - height () { - return this.bbox().height + size (width, height) { + const box = this.bbox() + const p = proportionalSize(this, width, height, box) + + return this + .width(new SVGNumber(p.width), box) + .height(new SVGNumber(p.height), box) } } diff --git a/src/modules/core/parser.js b/src/modules/core/parser.js index 1ff2380..dfa7b7b 100644 --- a/src/modules/core/parser.js +++ b/src/modules/core/parser.js @@ -5,7 +5,7 @@ export default function parser () { // Reuse cached element if possible if (!parser.nodes) { let svg = makeInstance().size(2, 0) - svg.node.cssText = [ + svg.node.style.cssText = [ 'opacity: 0', 'position: absolute', 'left: -100%', @@ -13,6 +13,8 @@ export default function parser () { 'overflow: hidden' ].join(';') + svg.attr('focusable', 'false') + let path = svg.path().node parser.nodes = { svg, path } diff --git a/src/modules/optional/sugar.js b/src/modules/optional/sugar.js index d4255c3..c05512d 100644 --- a/src/modules/optional/sugar.js +++ b/src/modules/optional/sugar.js @@ -38,7 +38,7 @@ var sugar = { return this } - registerMethods([ 'Shape', 'Runner' ], extension) + registerMethods([ 'Element', 'Runner' ], extension) }) registerMethods([ 'Element', 'Runner' ], { @@ -110,18 +110,6 @@ registerMethods([ 'Element', 'Runner' ], { } }) -registerMethods('Element', { - // Relative move over x axis - dx: function (x) { - return this.x(new SVGNumber(x).plus(this.x())) - }, - - // Relative move over y axis - dy: function (y) { - return this.y(new SVGNumber(y).plus(this.y())) - } -}) - registerMethods('radius', { // Add x and y radius radius: function (x, y) { diff --git a/src/utils/utils.js b/src/utils/utils.js index 3bac0de..c2046a9 100644 --- a/src/utils/utils.js +++ b/src/utils/utils.js @@ -56,9 +56,9 @@ export function capitalize (s) { } // Calculate proportional width and height values when necessary -export function proportionalSize (element, width, height) { +export function proportionalSize (element, width, height, box) { if (width == null || height == null) { - var box = element.bbox() + box = box || element.bbox() if (width == null) { width = box.width / box.height * height