designpaca 초기 구현 — 스킬 · 설치 CLI · 배포 파이프라인
웹 디자인 파이프라인 스킬과 이를 5개 에이전트에 설치하는 CLI 를 담은 모노레포. 스킬 (packages/skill) - SKILL.md 261줄 + 참조 문서 16개 3,349줄. progressive disclosure 로 본문은 절차와 인덱스만, 지식은 references/ 로 분리 - 0~6단계 파이프라인. 규모에 따라 전체·연장·국소 세 경로로 분기 - 하드 게이트 12개는 grep·카운트로 검증 가능한 것만. 취향 판단은 제외 - 미학 프리셋 5종, AI 슬롭 지문 목록, 한글 조판 규칙, SVG 필터·three.js·인터랙티브 모션·HTML-in-Canvas 실전 지침 설치 CLI (packages/cli, packages/core) - npx designpaca 온보딩 TUI. Claude Code · Codex · Cursor · Windsurf · AGENTS.md - 매니페스트에 설치 시점 해시를 기록해 사용자가 고친 파일은 update 가 건너뛴다 - 타깃별로 본문의 references/ 경로를 실제 설치 위치로 재작성 - AGENTS.md 는 항상 로드되므로 본문 대신 303자 포인터만 주입 - Windsurf 는 12,000자 상한 초과 시 설치를 차단 배포 (build/ci, .forgejo/workflows) - 태그 v* → 검사·테스트·빌드 → npmjs 배포 + Forgejo 레지스트리 미러 → draft 릴리스 → Cloudflare Pages. 재실행 멱등 근거 (research/) - 약 250개 웹 소스 조사 결과와 도그푸딩 검증 2건. 스킬의 모든 수치는 여기서 나온다 테스트 22개 통과 (core 16 · cli 6)
This commit is contained in:
commit
8808c672dc
135 changed files with 38838 additions and 0 deletions
193
research/canvas/_raw/ex-webGL.html
Normal file
193
research/canvas/_raw/ex-webGL.html
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
<!doctype html>
|
||||
<meta charset="utf-8" />
|
||||
<title>Demo of complex text in WebGL</title>
|
||||
<script
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/2.8.1/gl-matrix-min.js"
|
||||
integrity="sha512-zhHQR0/H5SEBL3Wn6yYSaTTZej12z0hVZKOv3TwCUXT1z5qeqGcXJLLrbERYRScEDDpYIJhPC1fk31gqR783iQ=="
|
||||
crossorigin="anonymous"
|
||||
defer>
|
||||
</script>
|
||||
<script src="webGLSetup.js"></script>
|
||||
<style>
|
||||
canvas {
|
||||
border: 1px solid blue;
|
||||
width: 638px;
|
||||
height: 318px;
|
||||
}
|
||||
#draw_element {
|
||||
border: 1px solid blue;
|
||||
width: 400px;
|
||||
height: 400px;
|
||||
padding: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<canvas id="gl-canvas" width="638" height="318" layoutsubtree="true">
|
||||
<!-- inert to prevent hit testing in this example. -->
|
||||
<div id="draw_element" inert>
|
||||
Hello world!<br>I'm multi-line, <b>formatted</b>,
|
||||
rotated text with emoji (😀), RTL text
|
||||
<span dir=rtl>من فارسی صحبت میکنم</span>,
|
||||
vertical text,
|
||||
<p style="writing-mode: vertical-rl;">
|
||||
这是垂直文本
|
||||
</p>
|
||||
an inline image (<img width="150" src="wolf.jpg">), and
|
||||
<svg width="50" height="50">
|
||||
<circle cx="25" cy="25" r="20" fill="green" />
|
||||
<text x="25" y="30" font-size="15" text-anchor="middle" fill="#fff">
|
||||
SVG
|
||||
</text>
|
||||
</svg>!
|
||||
</div>
|
||||
</canvas>
|
||||
|
||||
<script>
|
||||
let cubeRotation = 0.0;
|
||||
let currentTime = 0;
|
||||
let deltaTime = 0;
|
||||
let render_context = null;
|
||||
|
||||
//
|
||||
// Initialize a texture and load an image.
|
||||
// When the image finished loading copy it into the texture.
|
||||
//
|
||||
function loadTexture(gl) {
|
||||
const texture = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, texture);
|
||||
|
||||
const internalFormat = gl.RGBA8;
|
||||
try {
|
||||
gl.texElementImage2D(gl.TEXTURE_2D, internalFormat, draw_element);
|
||||
} catch (e) {
|
||||
// The texElementImage2D API was recently changed (see:
|
||||
// https://github.com/WICG/html-in-canvas#idl-changes). This snippet
|
||||
// supports the old syntax temporarily so that the demos do not break.
|
||||
const level = 0;
|
||||
const srcFormat = gl.RGBA;
|
||||
const destType = gl.UNSIGNED_BYTE;
|
||||
gl.texElementImage2D(gl.TEXTURE_2D, level, internalFormat,
|
||||
srcFormat, destType, draw_element);
|
||||
console.log('Note: using old texElementImage2D API');
|
||||
}
|
||||
|
||||
|
||||
// Linear texture filtering produces better results than mipmap with text.
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
// Draw the scene repeatedly
|
||||
function render() {
|
||||
let new_time = performance.now() * 0.001; // convert to seconds
|
||||
deltaTime = new_time - currentTime;
|
||||
currentTime = new_time;
|
||||
|
||||
if (render_context === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
drawScene(render_context.gl,
|
||||
render_context.program,
|
||||
render_context.buffers,
|
||||
render_context.texture,
|
||||
cubeRotation);
|
||||
|
||||
cubeRotation += deltaTime;
|
||||
requestAnimationFrame(render);
|
||||
}
|
||||
|
||||
function main() {
|
||||
const canvas = document.querySelector('#gl-canvas');
|
||||
// Initialize the GL context
|
||||
const gl = canvas.getContext('webgl2');
|
||||
|
||||
// Only continue if WebGL is available and working
|
||||
if (gl === null) {
|
||||
alert(
|
||||
'Unable to initialize WebGL. Your browser or machine may not support it.',
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Vertex shader program
|
||||
const vsSource = `
|
||||
attribute vec4 aVertexPosition;
|
||||
attribute vec2 aTextureCoord;
|
||||
|
||||
uniform mat4 uModelViewMatrix;
|
||||
uniform mat4 uProjectionMatrix;
|
||||
|
||||
varying highp vec2 vTextureCoord;
|
||||
|
||||
void main(void) {
|
||||
gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition;
|
||||
vTextureCoord = aTextureCoord;
|
||||
}
|
||||
`;
|
||||
|
||||
// Fragment shader program
|
||||
const fsSource = `
|
||||
varying highp vec2 vTextureCoord;
|
||||
|
||||
uniform sampler2D uSampler;
|
||||
|
||||
void main(void) {
|
||||
gl_FragColor = texture2D(uSampler, vTextureCoord);
|
||||
}
|
||||
`;
|
||||
|
||||
// Initialize a shader program; this is where all the lighting
|
||||
// for the vertices and so forth is established.
|
||||
const shaderProgram = initShaderProgram(gl, vsSource, fsSource);
|
||||
|
||||
// Collect all the info needed to use the shader program.
|
||||
// Look up which attribute our shader program is using
|
||||
// for aVertexPosition and look up uniform locations.
|
||||
const programInfo = {
|
||||
program: shaderProgram,
|
||||
attribLocations: {
|
||||
vertexPosition: gl.getAttribLocation(shaderProgram, 'aVertexPosition'),
|
||||
textureCoord: gl.getAttribLocation(shaderProgram, 'aTextureCoord'),
|
||||
},
|
||||
uniformLocations: {
|
||||
projectionMatrix: gl.getUniformLocation(shaderProgram, 'uProjectionMatrix'),
|
||||
modelViewMatrix: gl.getUniformLocation(shaderProgram, 'uModelViewMatrix'),
|
||||
uSampler: gl.getUniformLocation(shaderProgram, 'uSampler'),
|
||||
},
|
||||
};
|
||||
|
||||
const buffers = initBuffers(gl);
|
||||
|
||||
// Load texture
|
||||
const texture = loadTexture(gl);
|
||||
// Flip image pixels into the bottom-to-top order that WebGL expects.
|
||||
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
|
||||
|
||||
render_context = {
|
||||
gl: gl,
|
||||
program: programInfo,
|
||||
buffers: buffers,
|
||||
texture:texture,
|
||||
};
|
||||
|
||||
requestAnimationFrame(render);
|
||||
}
|
||||
|
||||
onload = () => {
|
||||
const canvas = document.querySelector('#gl-canvas');
|
||||
canvas.onpaint = () => {
|
||||
main();
|
||||
}
|
||||
canvas.requestPaint();
|
||||
|
||||
const observer = new ResizeObserver(([entry]) => {
|
||||
canvas.width = entry.devicePixelContentBoxSize[0].inlineSize;
|
||||
canvas.height = entry.devicePixelContentBoxSize[0].blockSize;
|
||||
});
|
||||
observer.observe(canvas, {box: 'device-pixel-content-box'});
|
||||
}
|
||||
</script>
|
||||
Loading…
Add table
Add a link
Reference in a new issue