Skip to content

Commit

Permalink
chore: improve svg rendering
Browse files Browse the repository at this point in the history
  • Loading branch information
triniwiz committed Mar 26, 2024
1 parent 05f0c41 commit 156ada3
Show file tree
Hide file tree
Showing 100 changed files with 6,286 additions and 2,743 deletions.
2 changes: 1 addition & 1 deletion apps/demo/src/plugin-demos/canvas-svg.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<ActionBar title="canvas-svg" icon="" class="action-bar">
</ActionBar>
</Page.actionBar>
<GridLayout columns="*,*" rows="*,*">
<GridLayout columns="*,*" rows="*,*" loaded="{{ viewLoaded }}">
<ui:Svg id="1" width="100%" height="100%" src="{{src1}}" loaded="{{svgViewLoaded}}"/>
<!--<ui:Svg id="2" col="1" width="100%" height="100%" src="{{src2}}" loaded="{{svgViewLoaded}}"/>
<ui:Svg id="3" row="1" width="100%" height="100%" src="{{src3}}" loaded="{{svgViewLoaded}}"/>
Expand Down
15 changes: 12 additions & 3 deletions packages/canvas-polyfill/DOM/CharacterData.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
import { Node } from './Node';

export class CharacterData extends Node {
constructor(data) {
super(data);
private _data: string;
constructor(data: string) {
super('');
this._data = data;
}

get data() {
return this._data;
}
}

get length() {
return this._data.length;
}
}
57 changes: 43 additions & 14 deletions packages/canvas-polyfill/DOM/Document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import { Frame, StackLayout } from '@nativescript/core';
import { Node } from './Node';
import { Element } from './Element';
import { SVGSVGElement } from './svg/SVGSVGElement';
import { SVGElement } from './svg/SVGElement';
import { HTMLUnknownElement } from './HTMLUnknownElement';

export class Document extends Node {
readonly body: Element;
private _documentElement: Element;
Expand All @@ -27,7 +30,39 @@ export class Document extends Node {
this.head = new Element('HEAD');
}

createElement(tagName: string) {
_createElement(namespaceURI: string | null, tagName: string, options?: {}) {
if (namespaceURI === 'http://www.w3.org/2000/svg') {
switch ((tagName || '').toLowerCase()) {
case 'svg':
return new SVGSVGElement();
case 'rect':
return new SVGRectElement();
case 'circle':
return new SVGCircleElement();
case 'g':
return new SVGGElement();
case 'path':
return new SVGPathElement();
case 'image':
return new SVGImageElement();
case 'polyline':
return new SVGPolylineElement();
case 'polygon':
return new SVGPolygonElement();
case 'ellipse':
return new SVGEllipseElement();
case 'line':
return new SVGLineElement();
case 'text':
return new SVGTextElement();
case 'radialGradient':
return new SVGRadialGradientElement();
case 'linearGradient':
return new SVGLinearGradientElement();
default:
return new SVGElement(tagName ?? `${tagName}`);
}
}
switch ((tagName || '').toLowerCase()) {
case 'div':
return new HTMLDivElement();
Expand All @@ -40,23 +75,17 @@ export class Document extends Node {
case 'iframe':
// Return nothing to keep firebase working.
return null;
case 'svg':
return new SVGSVGElement('svg');
case 'rect':
return new SVGRectElement();
case 'circle':
return new SVGCircleElement();
case 'g':
return new SVGGElement();
case 'path':
return new SVGPathElement();
default:
return new Element(tagName);
return new HTMLUnknownElement(tagName ?? 'null');
}
}

createElementNS(namespaceURI: string, qualifiedName?: string, options?: {}) {
const element = this.createElement(qualifiedName) as any;
createElement(tagName: string, options?: {}) {
return this._createElement(null, tagName, options);
}

createElementNS(namespaceURI: string | null, qualifiedName?: string, options?: {}) {
const element = this._createElement(namespaceURI, qualifiedName, options) as any;
element.namespaceURI = namespaceURI;
if (qualifiedName?.toLowerCase?.() !== 'canvas') {
element.toDataURL = () => ({});
Expand Down
48 changes: 38 additions & 10 deletions packages/canvas-polyfill/DOM/Element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,42 +74,50 @@ export class Element extends Node {
return this.nodeName;
}

_children = new HTMLCollection();
get children() {
if (this._children.length) {
return this._children;
}
const element = (<any>this)._xmlDom?.documentElement ?? (<any>this)._xmlDom;
if (element) {
const ret = new HTMLCollection();
const length = element?.childNodes?.length ?? 0;

for (let i = 0; i < length; i++) {
const node = element.childNodes.item(i);
if (node) {
switch (node.nodeName) {
case 'image': {
const image = new SVGImageElement() as any;
image.__instance = node;
this._children.push(image);
}
case 'line':
{
const line = new SVGLineElement() as any;
line.__instance = node;
ret.push(line);
this._children.push(line);
}
break;
case 'polyline':
{
const polyline = new SVGPolylineElement() as any;
polyline.__instance = node;
ret.push(polyline);
this._children.push(polyline);
}
break;
case 'g':
{
const g = new SVGGElement() as any;
g.__instance = node;
ret.push(g);
this._children.push(g);
}
break;
case 'path':
{
const path = new SVGPathElement() as any;
path.__instance = node;
ret.push(path);
this._children.push(path);
}
break;
case 'rect':
Expand All @@ -119,21 +127,31 @@ export class Element extends Node {
ret.push(rect);
}
break;
case 'stop':
{
const stop = new SVGStopElement() as any;
stop.__instance = node;
ret.push(stop);
}
break;
default:
// ret.push(node);
break;
}
}
}

return ret;
return this._children;
}

return [];
}

getAttribute(key: string): unknown {
if (this.nativeElement) {
return this.nativeElement[key];
return this.nativeElement[key] ?? null;
}
return this._attrs.get(key);
return this._attrs.get(key) ?? null;
}

setAttribute(key: string, value: unknown) {
Expand Down Expand Up @@ -166,9 +184,19 @@ export class Element extends Node {
removeAttributeNS() {}

querySelector(selector: string) {
const selection = querySelector(selector, this);
const context = (<any>this)._xmlDom?.documentElement ?? (<any>this)._xmlDom;
const selection = querySelector(selector, context);
if (Array.isArray(selection)) {
return selection[0];
const item = selection[0];
if (item) {
switch (item.nodeName) {
case 'linearGradient': {
const ret = new SVGLinearGradientElement() as any;
ret.__instance = item;
return ret;
}
}
}
}
return null;
}
Expand Down
7 changes: 7 additions & 0 deletions packages/canvas-polyfill/DOM/HTMLUnknownElement.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { HTMLElement } from './HTMLElement';

export class HTMLUnknownElement extends HTMLElement {
constructor(tagName: string) {
super(tagName);
}
}
25 changes: 15 additions & 10 deletions packages/canvas-polyfill/DOM/Node.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { EventTarget } from './EventTarget';
import setValue from 'set-value';


let id = 0;
const DOCUMENT_POSITION_DISCONNECTED = 1;
const DOCUMENT_POSITION_CONTAINS = 8;

export class Node extends EventTarget {
className: any;
Expand All @@ -14,7 +14,7 @@ export class Node extends EventTarget {
super();

this.className = {
baseVal: ''
baseVal: '',
};
this.nodeName = nodeName;
}
Expand All @@ -35,15 +35,20 @@ export class Node extends EventTarget {
return window.document;
}

appendChild(view) {
}
appendChild(view) {}

insertBefore(view) {
}
insertBefore(view) {}

removeChild(view) {
}
removeChild(view) {}

setAttributeNS() {}

compareDocumentPosition(otherNode) {
const element = (<any>this)._xmlDom?.documentElement ?? (<any>this)._xmlDom;
if (this.nodeName === '#document') {
return DOCUMENT_POSITION_CONTAINS;
}

setAttributeNS() {
return DOCUMENT_POSITION_DISCONNECTED;
}
}
10 changes: 5 additions & 5 deletions packages/canvas-polyfill/DOM/Text.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {CharacterData} from './CharacterData';

import { CharacterData } from './CharacterData';
export class Text extends CharacterData {
constructor(data) {
super(data);
}
__instance;
constructor(data) {
super(data);
}
}
4 changes: 2 additions & 2 deletions packages/canvas-polyfill/DOM/XMLDocument.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ export class XMLDocument extends Doc {
documentPrototype.querySelectorAll = function (selector: string) {
return querySelector(selector, this);
};

const doc = new XMLDocument();
doc.__instance = instance;
const documentElement = instance?.documentElement;

if (documentElement?.nodeName === 'svg' && documentElement?.namespaceURI === 'http://www.w3.org/2000/svg') {
const svg = new SVGSVGElement('svg') as any;
const svg = new SVGSVGElement() as any;
svg.__instance = instance.documentElement;
(<any>doc)._documentElement = svg;
}
Expand Down
54 changes: 54 additions & 0 deletions packages/canvas-polyfill/DOM/svg/SVGAnimatedNumber.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { getValueAndUnit } from './SVGUnits';

export class SVGAnimatedNumber {
_baseVal: number;
_animVal: number;
_element;
_key: string;
constructor(element?, key?) {
this._baseVal = 0;
this._animVal = 0;
this._element = element;
this._key = key;
}

get baseVal() {
const value = this._element?.getAttribute?.(this._key);
if (typeof value === 'string') {
const ret = getValueAndUnit(value);
if (ret.unit === '%') {
const retValue = Number(ret.value);
if (!isNaN(retValue)) {
return retValue / 100;
}
} else {
const retValue = Number(ret.value);
if (!isNaN(retValue)) {
return retValue;
}
}
}

return this._baseVal;
}

get animVal() {
// todo
const value = this._element?.getAttribute?.(this._key);
if (typeof value === 'string') {
const ret = getValueAndUnit(value);
if (ret.unit === '%') {
const retValue = Number(ret.value);
if (!isNaN(retValue)) {
return retValue / 100;
}
} else {
const retValue = Number(ret.value);
if (!isNaN(retValue)) {
return retValue;
}
}
}
return this._animVal;
}
}
Loading

0 comments on commit 156ada3

Please sign in to comment.