Skip to content

Commit 11bad47

Browse files
committed
chore: add ko-fi funding link
1 parent 53b02a4 commit 11bad47

File tree

9 files changed

+110
-5
lines changed

9 files changed

+110
-5
lines changed

.github/FUNDING.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
github: xiaoiver
44
patreon: # Replace with a single Patreon username
5-
open_collective: infinite-canvas-tutorial
6-
ko_fi: # Replace with a single Ko-fi username
5+
open_collective: # Replace with a single Open Collective username
6+
ko_fi: yuqipan
77
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
88
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
99
liberapay: # Replace with a single Liberapay username
1010
issuehunt: # Replace with a single IssueHunt username
1111
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
1212
polar: # Replace with a single Polar username
13-
buy_me_a_coffee: pyqiverson0
13+
buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
1414
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
> [My free course in Gumroad]. Feel free to rate!
99
10+
[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/U7U71DK7IM)
11+
1012
[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/edit/vite-tvhpcpvl?file=main.js)
1113

1214
What is an Infinite Canvas? The term "infinite" in [infinitecanvas] is described as follows:

README.zh_CN.md

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
> [我在 Gumroad 上的免费课程],欢迎评分!
99
10+
[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/U7U71DK7IM)
11+
1012
[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/edit/vite-tvhpcpvl?file=main.js)
1113

1214
什么是无限画布?[infinitecanvas] 对“无限”的描述如下:

packages/webcomponents/src/API.ts

+29
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,35 @@ export class API {
337337
);
338338
}
339339

340+
deleteNodesById(ids: SerializedNode['id'][]) {
341+
const nodes = this.getNodes();
342+
const index = nodes.findIndex((n) => ids.includes(n.id));
343+
if (index !== -1) {
344+
nodes.splice(index, 1);
345+
}
346+
347+
ids.forEach((id) => {
348+
const entity = this.#idEntityMap.get(id);
349+
if (entity) {
350+
entity.id().delete();
351+
}
352+
this.#idEntityMap.delete(id);
353+
});
354+
355+
this.setNodes(nodes);
356+
357+
this.#store.shouldUpdateSnapshot();
358+
this.#store.commit(arrayToMap(this.getNodes()), this.getAppState());
359+
360+
this.element.dispatchEvent(
361+
new CustomEvent(Event.NODE_DELETED, {
362+
detail: {
363+
nodes,
364+
},
365+
}),
366+
);
367+
}
368+
340369
undo() {
341370
const result = this.#history.undo(
342371
arrayToMap(this.getNodes()),

packages/webcomponents/src/event.ts

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export enum Event {
2222
TASK_CHANGED = 'ic-task-changed',
2323
NODES_UPDATED = 'ic-nodes-updated',
2424
NODE_UPDATED = 'ic-node-updated',
25+
NODE_DELETED = 'ic-node-deleted',
2526
VISIBILITY_CHANGED = 'ic-visibility-changed',
2627
SELECTED_NODES_CHANGED = 'ic-selected-nodes-changed',
2728
}
@@ -43,6 +44,7 @@ declare global {
4344
[Event.SCREENSHOT_DOWNLOADED]: CustomEvent<Screenshot>;
4445
[Event.NODES_UPDATED]: CustomEvent<{ nodes: SerializedNode[] }>;
4546
[Event.NODE_UPDATED]: CustomEvent<{ node: SerializedNode }>;
47+
[Event.NODE_DELETED]: CustomEvent<{ nodes: SerializedNode[] }>;
4648
[Event.SELECTED_NODES_CHANGED]: CustomEvent<{
4749
selected: SerializedNode['id'][];
4850
preserveSelection: boolean;

packages/webcomponents/src/spectrum/infinite-canvas.ts

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import '@spectrum-web-components/tooltip/sp-tooltip.js';
3939
import '@spectrum-web-components/picker/sp-picker.js';
4040

4141
import '@spectrum-web-components/icons-workflow/icons/sp-icon-add.js';
42+
import '@spectrum-web-components/icons-workflow/icons/sp-icon-delete.js';
4243
import '@spectrum-web-components/icons-workflow/icons/sp-icon-remove.js';
4344
import '@spectrum-web-components/icons-workflow/icons/sp-icon-text.js';
4445
import '@spectrum-web-components/icons-workflow/icons/sp-icon-visibility.js';

packages/webcomponents/src/spectrum/layer-thumbnail.ts

+26-2
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,17 @@ export class LayerThumbnail extends LitElement {
6161

6262
let $el: SVGElement;
6363

64-
const { type, fill, stroke, strokeWidth } = this
65-
.node as CircleSerializedNode;
64+
const {
65+
type,
66+
fill,
67+
stroke,
68+
strokeWidth,
69+
strokeLinecap,
70+
strokeLinejoin,
71+
strokeMiterlimit,
72+
strokeDasharray,
73+
strokeDashoffset,
74+
} = this.node as CircleSerializedNode;
6675
if (type === 'circle') {
6776
$el = createSVGElement('circle') as SVGElement;
6877
$el.setAttribute('cx', `${minX + width / 2}`);
@@ -99,6 +108,21 @@ export class LayerThumbnail extends LitElement {
99108
if (strokeWidth) {
100109
$el.setAttribute('stroke-width', strokeWidth.toString());
101110
}
111+
if (strokeLinecap) {
112+
$el.setAttribute('stroke-linecap', strokeLinecap);
113+
}
114+
if (strokeLinejoin) {
115+
$el.setAttribute('stroke-linejoin', strokeLinejoin);
116+
}
117+
if (strokeMiterlimit) {
118+
$el.setAttribute('stroke-miterlimit', strokeMiterlimit.toString());
119+
}
120+
if (strokeDasharray) {
121+
$el.setAttribute('stroke-dasharray', strokeDasharray);
122+
}
123+
if (strokeDashoffset) {
124+
$el.setAttribute('stroke-dashoffset', strokeDashoffset.toString());
125+
}
102126
}
103127

104128
const isGradientOrPattern = isGradient(fill) || isPattern(fill);

packages/webcomponents/src/spectrum/layers-panel.ts

+41
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ export class LayersPanel extends LitElement {
3636
margin: 0;
3737
}
3838
39+
.actions {
40+
padding: 4px;
41+
padding-top: 0;
42+
}
43+
3944
.container {
4045
height: 300px;
4146
overflow: hidden;
@@ -60,6 +65,25 @@ export class LayersPanel extends LitElement {
6065
);
6166
}
6267

68+
private handleDelete() {
69+
const { layersSelected } = this.api.getAppState();
70+
this.api.deleteNodesById(layersSelected);
71+
72+
// Try to select the next layer
73+
const nextLayer = this.nodes.find(
74+
(node) => !layersSelected.includes(node.id),
75+
);
76+
if (nextLayer) {
77+
this.api.selectNodes([nextLayer.id]);
78+
}
79+
80+
// TODO: scroll to the selected layer
81+
}
82+
83+
private handleAdd() {
84+
// this.api.addNodes(this.nodes);
85+
}
86+
6387
private handleSelect(e: MouseEvent, id: SerializedNode['id']) {
6488
const { layersSelected } = this.api.getAppState();
6589

@@ -81,6 +105,23 @@ export class LayersPanel extends LitElement {
81105
<sp-icon-close slot="icon"></sp-icon-close>
82106
</sp-action-button>
83107
</h4>
108+
<sp-action-group class="actions">
109+
<sp-action-button quiet size="s" @click=${this.handleAdd}>
110+
<sp-tooltip self-managed placement="bottom">
111+
Add new layer
112+
</sp-tooltip>
113+
<sp-icon-add slot="icon"></sp-icon-add>
114+
</sp-action-button>
115+
<sp-action-button
116+
quiet
117+
size="s"
118+
@click=${this.handleDelete}
119+
.disabled=${layersSelected.length === 0}
120+
>
121+
<sp-tooltip self-managed placement="bottom"> Delete </sp-tooltip>
122+
<sp-icon-delete slot="icon"></sp-icon-delete>
123+
</sp-action-button>
124+
</sp-action-group>
84125
<div class="container">
85126
${map(this.nodes, (node) => {
86127
// TODO: hierarchy

packages/webcomponents/src/spectrum/properties-panel-content.ts

+4
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,10 @@ export class PropertiesPanelContent extends LitElement {
446446
}
447447

448448
render() {
449+
if (!this.node) {
450+
return;
451+
}
452+
449453
const { type } = this.node;
450454
const isGroup = type === 'g';
451455
const isText = type === 'text';

0 commit comments

Comments
 (0)