Skip to content
This repository has been archived by the owner on Feb 10, 2023. It is now read-only.

Commit

Permalink
feat(soba): add GradientTexture
Browse files Browse the repository at this point in the history
ISSUES CLOSED: #28
  • Loading branch information
nartc committed Dec 30, 2021
1 parent 53b5429 commit 34004e2
Show file tree
Hide file tree
Showing 2 changed files with 139 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { EnhancedRxState, NgtMaterial, Tail } from '@angular-three/core';
import { DOCUMENT } from '@angular/common';
import {
Directive,
Inject,
Input,
NgModule,
NgZone,
Optional,
Output,
} from '@angular/core';
import { requestAnimationFrame } from '@rx-angular/cdk/zone-less';
import { selectSlice } from '@rx-angular/state';
import * as THREE from 'three';

interface NgtSobaGradientTextureState {
stops: Array<number>;
colors: Array<string>;
args: Tail<ConstructorParameters<typeof THREE.Texture>>;
texture: THREE.Texture;
size: number;
}

@Directive({
selector: 'ngt-soba-gradient-texture[stops][colors]',
exportAs: 'ngtSobaGradientTexture',
})
export class NgtSobaGradientTexture extends EnhancedRxState<NgtSobaGradientTextureState> {
@Input() set stops(stops: Array<number>) {
this.set({ stops });
}

@Input() set colors(colors: Array<string>) {
this.set({ colors });
}

@Input() set size(size: number) {
this.set({ size });
}

@Input() set args(args: Tail<ConstructorParameters<typeof THREE.Texture>>) {
this.set({ args });
}

@Output() ready = this.select('texture');

get texture() {
return this.get('texture');
}

constructor(
ngZone: NgZone,
@Inject(DOCUMENT) document: Document,
@Optional() material: NgtMaterial
) {
super();

this.set({ size: 2048, args: [] });

requestAnimationFrame(() => {
this.connect(
'texture',
this.select(selectSlice(['stops', 'args'])),
(_, { stops, args }) => {
const { colors, size } = this.get();
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d')!;
canvas.width = 16;
canvas.height = size;
const gradient = context.createLinearGradient(0, 0, 0, size);
let i = stops.length;
while (i--) {
gradient.addColorStop(stops[i], colors[i]);
}
context.fillStyle = gradient;
context.fillRect(0, 0, 16, size);
const texture = new THREE.Texture(canvas, ...args);
texture.needsUpdate = true;
return texture;
}
);

this.holdEffect(this.select('texture'), (texture) => {
if (material) {
Object.assign(material.material, { map: texture });
}

return () => {
texture.dispose();
};
});
});
}
}

@NgModule({
declarations: [NgtSobaGradientTexture],
exports: [NgtSobaGradientTexture],
})
export class NgtSobaGradientTextureModule {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { NgtSidePipeModule } from '@angular-three/core';
import { NgtPlaneGeometryModule } from '@angular-three/core/geometries';
import { NgtMeshBasicMaterialModule } from '@angular-three/core/materials';
import { NgtMeshModule } from '@angular-three/core/meshes';
import { setupCanvas, setupCanvasModules } from '@angular-three/storybook';
import {
componentWrapperDecorator,
Meta,
moduleMetadata,
} from '@storybook/angular';
import { NgtSobaGradientTextureModule } from './gradient-texture.directive';

export default {
title: 'Soba/Abstractions/Gradient Texture',
decorators: [
componentWrapperDecorator(setupCanvas({ black: true })),
moduleMetadata({
imports: [
...setupCanvasModules,
NgtSobaGradientTextureModule,
NgtMeshModule,
NgtMeshBasicMaterialModule,
NgtPlaneGeometryModule,
NgtSidePipeModule,
],
}),
],
} as Meta;

export const Default = () => ({
template: `
<ngt-mesh>
<ngt-plane-geometry></ngt-plane-geometry>
<ngt-mesh-basic-material [parameters]='{depthWrite: false, side: ""|side:"double"}'>
<ngt-soba-gradient-texture [stops]='[0, 1]' [colors]='["aquamarine", "hotpink"]'></ngt-soba-gradient-texture>
</ngt-mesh-basic-material>
</ngt-mesh>
`,
});

0 comments on commit 34004e2

Please sign in to comment.