Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
hanakla committed Jan 15, 2022
1 parent 555b459 commit d23517f
Show file tree
Hide file tree
Showing 49 changed files with 8,544 additions and 1,820 deletions.
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"[glsl]": {
"editor.formatOnSave": false
}
}
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
],
"scripts": {
"dev": "wsrun -p silk-web -c dev",
"build": "wsrun -p silk-web -c build",
"start": "wsrun -p silk-web -c start"
"build": "cd packages/silk-web; yarn build",
"start": "cd packages/silk-web; yarn start"
},
"devDependencies": {
"wsrun": "^5.2.4"
Expand Down
4 changes: 4 additions & 0 deletions packages/silk-core/bili.config.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { Config } from 'bili'
import typescript from 'rollup-plugin-typescript2'
import image from '@rollup/plugin-image'
import glslify from 'rollup-plugin-glslify'

export default {
input: 'src/index.ts',
plugins: {
typescript2: typescript(),
glslify: glslify(),
'@rollup/plugin-image': image(),
terser: {
compress: {
arrows: true,
Expand Down
21 changes: 20 additions & 1 deletion packages/silk-core/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
{
"name": "silk-core",
"version": "0.0.0",
"main": "src/index.ts",
"type": "module",
"main": "dist/index.js",
"module": "dist/index.esm.js",
"types": "dist/index.d.ts",
"scripts": {
"build:declarations": "tsc --emitDeclarationOnly --declaration --outDir ./dist",
"build:source": "bili",
"watch:declarations": "tsc --watch --emitDeclarationOnly --declaration --outDir ./dist",
"watch:source": "bili --watch",
"dev": "run-p -c watch:*",
"build": "run-p build:*",
"clean-dist": "rm -rf ./dist",
"prepublishOnly": "yarn clean-dist && yarn build"
},
"dependencies": {
"@yr/catmull-rom-spline": "^1.0.3",
"clone": "^2.1.2",
Expand All @@ -18,12 +31,18 @@
"uuidv4": "^6.2.11"
},
"devDependencies": {
"@rollup/plugin-image": "^2.1.0",
"@types/clone": "^2.1.1",
"@types/jest": "^26.0.24",
"@types/msgpack5": "^3.4.2",
"@types/offscreencanvas": "^2019.6.4",
"bili": "^5.0.5",
"npm-run-all": "^4.1.5",
"rollup-plugin-glslify": "^1.2.0",
"rollup-plugin-typescript2": "^0.30.0"
},
"resolutions": {
"glslify-deps": "1.3.2",
"glsl-tokenizer": "2.1.5"
}
}
6 changes: 3 additions & 3 deletions packages/silk-core/src/Brushes/ExampleBrush.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export class ExampleBrush implements IBrush {

public async initialize() {
this.image = new Image()
this.image.src = img.src
this.image.src = img

await new Promise((resolve) => {
this.image!.onload = resolve
Expand All @@ -24,8 +24,8 @@ export class ExampleBrush implements IBrush {

const { width, height } = this.image

stroke.eachSplinePoint(([x, y, force]) => {
ctx.globalAlpha = force / 2
stroke.path.mapPoints(({ x, y, weight }) => {
ctx.globalAlpha = weight / 2
ctx.drawImage(
this.image!,
x - width / 2,
Expand Down
25 changes: 0 additions & 25 deletions packages/silk-core/src/Entity/AdjustmentLayer.ts

This file was deleted.

2 changes: 2 additions & 0 deletions packages/silk-core/src/Entity/Document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,13 @@ export class Document {
}

const index = this.layers.findIndex((layer) => layer.id == aboveLayerId)

if (index === -1) {
this.layers.push(layer)
} else {
this.layers.splice(index, 0, layer)
}

this.mitt.emit('layersChanged')
}

Expand Down
16 changes: 16 additions & 0 deletions packages/silk-core/src/Entity/GroupLayer.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { assign } from '../utils'
import { CompositeMode, ILayer } from './IRenderable'

export class GroupLayer implements ILayer {
Expand All @@ -13,6 +14,21 @@ export class GroupLayer implements ILayer {

public layers: ILayer[] = []

public static deserialize(obj: any) {
return assign(new GroupLayer(), {
name: obj.name,
visible: obj.visible,
lock: obj.lock,
compositeMode: obj.compositeMode,
opacity: obj.opacity,
x: obj.x,
y: obj.y,
layers: obj.layers.map(),
})
}

protected constructor() {}

public get width() {
return 0
}
Expand Down
2 changes: 1 addition & 1 deletion packages/silk-core/src/Entity/IRenderable.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export type CompositeMode = 'normal' | 'multiply' | 'screen' | 'overlay'

export interface ILayer {
layerType: 'raster' | 'vector' | 'filter' | 'group'
layerType: 'raster' | 'vector' | 'filter' | 'group' | 'text'
name: string
visible: boolean
lock: boolean
Expand Down
64 changes: 64 additions & 0 deletions packages/silk-core/src/Entity/TextLayer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { ILayer } from './IRenderable'
import { v4 } from 'uuid'
import { Filter } from './Filter'
import { assign, deepClone } from '../utils'

export class TextLayer implements ILayer {
public readonly layerType = 'text'

public readonly id: string = `textlayer-${v4()}`
public name: string = ''
public visible: boolean = true
public lock: boolean = false
public compositeMode: ILayer['compositeMode'] = 'normal' as const
public opacity: number = 100

public width: number = 0
public height: number = 0
public x: number = 0
public y: number = 0
public filters: Filter[] = []

public content: TextLayer.Content[] = []
public letterSpacing: number = 1

public static create({
content,
letterSpacing,
}: {
content: TextLayer.Content[]
letterSpacing: number
}) {
return assign(new TextLayer(), {
content: content,
letterSpacing: letterSpacing,
})
}

public update(proc: (layer: TextLayer) => void) {
proc(this)
}

public serialize() {
return {
layerType: this.layerType,
id: this.id,
name: this.name,
visible: this.visible,
lock: this.lock,
compositeMode: this.compositeMode,
opacity: this.opacity,
width: this.width,
height: this.height,
x: this.x,
y: this.y,
filters: this.filters.map((f) => f.serialize()),
content: deepClone(this.content),
letterSpacing: this.letterSpacing,
}
}
}

export namespace TextLayer {
export type Content = { content: string }
}
10 changes: 6 additions & 4 deletions packages/silk-core/src/Entity/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { FilterLayer } from './FilterLayer'
import { RasterLayer } from './RasterLayer'
import { VectorLayer } from './VectorLayer'
import type { FilterLayer } from './FilterLayer'
import type { RasterLayer } from './RasterLayer'
import type { TextLayer } from './TextLayer'
import type { VectorLayer } from './VectorLayer'

export { RasterLayer } from './RasterLayer'
export { VectorLayer } from './VectorLayer'
export { FilterLayer } from './FilterLayer'
export { TextLayer } from './TextLayer'
export { GroupLayer as Group } from './GroupLayer'
export { Filter } from './Filter'
export { Document } from './Document'
export { Path } from './Path'
export { VectorObject } from './VectorObject'
export type LayerTypes = RasterLayer | VectorLayer | FilterLayer
export type LayerTypes = RasterLayer | VectorLayer | FilterLayer | TextLayer
37 changes: 17 additions & 20 deletions packages/silk-core/src/Filters/ChromaticAberration.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,30 @@
import { screenMix_func } from '../engine/Shaders'
import { FilterContext, IFilter } from '../engine/IFilter'

const FRAGMENT_SHADER = `
precision mediump float;
uniform sampler2D source;
uniform float distancePx;
uniform float angleRad;
uniform vec2 resolution;
varying vec2 vTexCoord;
vec4 screen(vec4 fore, vec4 back) {
// SEE: https://odashi.hatenablog.com/entry/20110921/1316610121
float a1 = fore.a * back.a;
float a2 = fore.a * (1.0 - back.a);
float a3 = (1.0 - fore.a) * back.a;
float alpha = a1 + a2 + a3;
vec3 mixed = ((fore + back) - (fore * back)).rgb;
vec3 result = (mixed * a1 + fore.rgb * a2 + back.rgb * a3) / alpha;
return vec4(result, alpha);
}
${screenMix_func}
void main() {
vec2 tFrag = vec2(1.0) / resolution;
vec2 movement = vec2(distancePx * tFrag.x, 0);
vec2 movement = vec2(
cos(angleRad) * (distancePx * tFrag.x),
sin(angleRad) * (distancePx * tFrag.y)
);
vec4 r = texture2D(source, vTexCoord + vec2(distancePx * tFrag.x, 0)) * vec4(1, 0, 0, 1);
vec4 g = texture2D(source, vTexCoord + vec2((distancePx * 1.5) * tFrag.x, 0)) * vec4(0, 1, 0, 1);
vec4 b = texture2D(source, vTexCoord + vec2((distancePx * 2.0) * tFrag.x, 0)) * vec4(0, 0, 1, 1);
vec4 r = texture2D(source, vTexCoord + movement) * vec4(1, 0, 0, 1);
vec4 g = texture2D(source, vTexCoord) * vec4(0, 1, 0, 1);
vec4 b = texture2D(source, vTexCoord + -movement) * vec4(0, 0, 1, 1);
gl_FragColor = screen(screen(r, g), b);
// gl_FragColor = screen(r, g);
gl_FragColor = screenMix(screenMix(r, g), b);
}
`

Expand Down Expand Up @@ -62,10 +54,15 @@ export class ChromaticAberrationFilter implements IFilter {
{
resolution: gl.uni2f(size.width, size.height),
distancePx: gl.uni1f(distance),
angleDeg: gl.uni1f(angleDeg),
angleRad: gl.uni1f(normalizeDegree(angleDeg) * (Math.PI / 180)),
},
source,
dest
)
}
}

const normalizeDegree = (deg: number) => {
const norm = deg % 360
return norm < 0 ? norm + 360 : norm
}
1 change: 0 additions & 1 deletion packages/silk-core/src/Filters/GaussBlur.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ export class GaussBlurFilter implements IFilter {
}: FilterContext) {
const rad = Math.round(radius)

console.log({ rad })
const programH = gl.createProgram(this.generateShader(rad, true))
const programV = gl.createProgram(this.generateShader(rad, false))

Expand Down
7 changes: 4 additions & 3 deletions packages/silk-core/src/SilkHelpers.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { CompositeMode } from './Entity/IRenderable'
import * as SilkEntity from './Entity/index'
import type { CompositeMode } from './Entity/IRenderable'
import type * as SilkEntity from './Entity/index'
import { RasterLayer } from './Entity/RasterLayer'

export async function imageToLayer(img: HTMLImageElement) {
const layer = SilkEntity.RasterLayer.create({
const layer = RasterLayer.create({
width: img.width,
height: img.height,
})
Expand Down
21 changes: 18 additions & 3 deletions packages/silk-core/src/declarations.d.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,38 @@
declare module '@yr/catmull-rom-spline' {
declare const _: {
const _: {
points(points: number[][])
}

export = _
}

declare module 'svg-path-bounds' {
declare function _(
function _(
path: string
): [left: number, top: number, right: number, bottom: number]
export = _
}

declare module 'point-at-length' {
declare const _: (path: string) => {
const _: (path: string) => {
length(): number
at(point: number): [x: number, y: number]
}

export = _
}

declare module '*.png' {
const _: string
export default _
}

declare module '*.frag' {
const _: string
export default _
}

declare module '*.glsl' {
const _: string
export default _
}
Loading

0 comments on commit d23517f

Please sign in to comment.