Commit fd54cd1c authored by 张媛's avatar 张媛

添加组件源码预览功能

parent 444aea85
.codeContainer{
.code{
background-color: #333333;
margin: 20px;
border-radius: 4px;
box-shadow: grey 0 0px 3px 0px, #333333 0 0 0 0px;
color: #FFFFFF;
font-size: 13px;
}
.title{
color:#ffffff;
font-size: 16px;
font-weight: bold;
}
}
\ No newline at end of file
......@@ -3,6 +3,9 @@ module.exports = {
stories: ['../src/**/*.stories.tsx'],
addons:[
"@storybook/addon-essentials",
"@storybook/addon-info"
// "@storybook/addon-info",
// "@storybook/addon-docs",
// "@storybook/addon-storysource",
]
};
\ No newline at end of file
import { themes } from '@storybook/theming';
import "codemirror/lib/codemirror.css";
import "codemirror/lib/codemirror.js";
import 'codemirror/mode/javascript/javascript';
import 'codemirror/theme/dracula.css';
import "codemirror/addon/fold/foldcode.js";
import "codemirror/addon/fold/foldgutter.js";
import "codemirror/addon/fold/brace-fold.js";
import "codemirror/addon/fold/comment-fold.js";
import "./global.less";
const customViewports = {
kindleFire2: {
name: 'Kindle Fire 2',
......@@ -16,7 +28,7 @@ const customViewports = {
},
};
export const parameters = {
layout: 'fullscreen',
layout: 'centered',
controls: {
matchers: {
color: /(background|color)$/i,
......@@ -27,4 +39,5 @@ export const parameters = {
theme: themes.dark,
},
viewport: { viewports: customViewports },
};
\ No newline at end of file
};
.code{
background-color: #333333;
padding: 20px;
border-radius: 4px;
box-shadow: grey 0 0px 3px 0px, #333333 0 0 0 0px;
color: #FFFFFF;
font-size: 13px;
}
\ No newline at end of file
const path = require('path');
module.exports = ({config, mode}) => {
config.module.rules.push({
test: /\.(less|css)$/,
test: /\.less$/,
loaders: ["style-loader", "css-loader", "less-loader"],
include: path.resolve(__dirname, '../')
});
// config.module.rules.push( {
// test: /\.css$/,
// //user可为loader加入选项
// use: [
// 'style-loader',
// {loader: 'css-loader',options: {importLoaders: 1}},
// {loader: 'postcss-loader',options: {plugins: [require('autoprefixer')({browsers:["last 5 versions"]})]}}
// ],
// })
config.module.rules.push({
test: /\.(js|jsx|ts|tsx)$/,
loader: require.resolve('babel-loader'),
......
......@@ -2536,6 +2536,36 @@
}
}
},
"@storybook/addon-storysource": {
"version": "6.3.2",
"resolved": "http://npm.dui88.com:80/@storybook%2faddon-storysource/-/addon-storysource-6.3.2.tgz",
"integrity": "sha1-tJD01zRPdI1jrZKhnBPdYe8w5LY=",
"dev": true,
"requires": {
"@storybook/addons": "6.3.2",
"@storybook/api": "6.3.2",
"@storybook/client-logger": "6.3.2",
"@storybook/components": "6.3.2",
"@storybook/router": "6.3.2",
"@storybook/source-loader": "6.3.2",
"@storybook/theming": "6.3.2",
"core-js": "^3.8.2",
"estraverse": "^5.2.0",
"loader-utils": "^2.0.0",
"prettier": "~2.2.1",
"prop-types": "^15.7.2",
"react-syntax-highlighter": "^13.5.3",
"regenerator-runtime": "^0.13.7"
},
"dependencies": {
"estraverse": {
"version": "5.2.0",
"resolved": "http://npm.dui88.com:80/estraverse/-/estraverse-5.2.0.tgz",
"integrity": "sha1-MH30JUfmzHMk088DwVXVzbjFOIA=",
"dev": true
}
}
},
"@storybook/addon-toolbars": {
"version": "6.3.2",
"resolved": "http://npm.dui88.com:80/@storybook%2faddon-toolbars/-/addon-toolbars-6.3.2.tgz",
......@@ -2721,6 +2751,18 @@
}
}
},
"cosmiconfig": {
"version": "7.0.0",
"resolved": "http://npm.dui88.com:80/cosmiconfig/-/cosmiconfig-7.0.0.tgz",
"integrity": "sha1-75tE13OVnK5j3ezRIt4jhTtg+NM=",
"requires": {
"@types/parse-json": "^4.0.0",
"import-fresh": "^3.2.1",
"parse-json": "^5.0.0",
"path-type": "^4.0.0",
"yaml": "^1.10.0"
}
},
"css-loader": {
"version": "3.6.0",
"resolved": "http://npm.dui88.com:80/css-loader/-/css-loader-3.6.0.tgz",
......@@ -2794,6 +2836,56 @@
"p-limit": "^3.0.2"
}
},
"postcss-loader": {
"version": "4.3.0",
"resolved": "http://npm.dui88.com:80/postcss-loader/-/postcss-loader-4.3.0.tgz",
"integrity": "sha1-LE3pZXzU8Hr1q0K9YKZzAE2huMw=",
"requires": {
"cosmiconfig": "^7.0.0",
"klona": "^2.0.4",
"loader-utils": "^2.0.0",
"schema-utils": "^3.0.0",
"semver": "^7.3.4"
},
"dependencies": {
"json5": {
"version": "2.2.0",
"resolved": "http://npm.dui88.com:80/json5/-/json5-2.2.0.tgz",
"integrity": "sha1-Lf7+cgxrpSXZ69kJlQ8FFTFsiaM=",
"requires": {
"minimist": "^1.2.5"
}
},
"loader-utils": {
"version": "2.0.0",
"resolved": "http://npm.dui88.com:80/loader-utils/-/loader-utils-2.0.0.tgz",
"integrity": "sha1-5MrOW4FtQloWa18JfhDNErNgZLA=",
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
}
},
"schema-utils": {
"version": "3.1.0",
"resolved": "http://npm.dui88.com:80/schema-utils/-/schema-utils-3.1.0.tgz",
"integrity": "sha1-lZhutgT2bare7Vbjeb/np/ljzbk=",
"requires": {
"@types/json-schema": "^7.0.7",
"ajv": "^6.12.5",
"ajv-keywords": "^3.5.2"
}
},
"semver": {
"version": "7.3.5",
"resolved": "http://npm.dui88.com:80/semver/-/semver-7.3.5.tgz",
"integrity": "sha1-C2Ich5NI2JmOSw5L6Us/EuYBjvc=",
"requires": {
"lru-cache": "^6.0.0"
}
}
}
},
"schema-utils": {
"version": "2.7.1",
"resolved": "http://npm.dui88.com:80/schema-utils/-/schema-utils-2.7.1.tgz",
......@@ -4118,6 +4210,11 @@
"resolved": "http://npm.dui88.com:80/@xtuc%2flong/-/long-4.2.2.tgz",
"integrity": "sha1-0pHGpOl5ibXGHZrPOWrk/hM6cY0="
},
"abbrev": {
"version": "1.1.1",
"resolved": "http://npm.dui88.com:80/abbrev/-/abbrev-1.1.1.tgz",
"integrity": "sha1-+PLIh60Qv2f2NPAFtph/7TF5qsg="
},
"accepts": {
"version": "1.3.7",
"resolved": "http://npm.dui88.com:80/accepts/-/accepts-1.3.7.tgz",
......@@ -5856,6 +5953,11 @@
"resolved": "http://npm.dui88.com:80/code-point-at/-/code-point-at-1.1.0.tgz",
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
},
"codemirror": {
"version": "5.62.0",
"resolved": "http://npm.dui88.com:80/codemirror/-/codemirror-5.62.0.tgz",
"integrity": "sha1-6ezQEub56vLgX/SkSf91D1FhniI="
},
"collapse-white-space": {
"version": "1.0.6",
"resolved": "http://npm.dui88.com:80/collapse-white-space/-/collapse-white-space-1.0.6.tgz",
......@@ -5985,6 +6087,15 @@
"typedarray": "^0.0.6"
}
},
"config-chain": {
"version": "1.1.13",
"resolved": "http://npm.dui88.com:80/config-chain/-/config-chain-1.1.13.tgz",
"integrity": "sha1-+tB5Wqamza/57Rto6d/5Q3LCMvQ=",
"requires": {
"ini": "^1.3.4",
"proto-list": "~1.2.1"
}
},
"console-browserify": {
"version": "1.2.0",
"resolved": "http://npm.dui88.com:80/console-browserify/-/console-browserify-1.2.0.tgz",
......@@ -6904,6 +7015,43 @@
"stream-shift": "^1.0.0"
}
},
"editorconfig": {
"version": "0.15.3",
"resolved": "http://npm.dui88.com:80/editorconfig/-/editorconfig-0.15.3.tgz",
"integrity": "sha1-vvhMTnX7jcsM5c7o79UcFZmb78U=",
"requires": {
"commander": "^2.19.0",
"lru-cache": "^4.1.5",
"semver": "^5.6.0",
"sigmund": "^1.0.1"
},
"dependencies": {
"commander": {
"version": "2.20.3",
"resolved": "http://npm.dui88.com:80/commander/-/commander-2.20.3.tgz",
"integrity": "sha1-/UhehMA+tIgcIHIrpIA16FMa6zM="
},
"lru-cache": {
"version": "4.1.5",
"resolved": "http://npm.dui88.com:80/lru-cache/-/lru-cache-4.1.5.tgz",
"integrity": "sha1-i75Q6oW+1ZvJ4z3KuCNe6bz0Q80=",
"requires": {
"pseudomap": "^1.0.2",
"yallist": "^2.1.2"
}
},
"semver": {
"version": "5.7.1",
"resolved": "http://npm.dui88.com:80/semver/-/semver-5.7.1.tgz",
"integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc="
},
"yallist": {
"version": "2.1.2",
"resolved": "http://npm.dui88.com:80/yallist/-/yallist-2.1.2.tgz",
"integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
}
}
},
"ee-first": {
"version": "1.1.1",
"resolved": "http://npm.dui88.com:80/ee-first/-/ee-first-1.1.1.tgz",
......@@ -8506,9 +8654,9 @@
"integrity": "sha1-hK5l+n6vsWX922FWauFLrwVmTw8="
},
"highlight.js": {
"version": "10.7.3",
"resolved": "http://npm.dui88.com:80/highlight.js/-/highlight.js-10.7.3.tgz",
"integrity": "sha1-aXJy45kTVuQMPKxWanTu9oF1ZTE="
"version": "10.6.0",
"resolved": "http://npm.dui88.com:80/highlight.js/-/highlight.js-10.6.0.tgz",
"integrity": "sha1-AHOqcdVmkGllum4be+eyaC9eGLY="
},
"hmac-drbg": {
"version": "1.0.1",
......@@ -9335,6 +9483,17 @@
"supports-color": "^7.0.0"
}
},
"js-beautify": {
"version": "1.14.0",
"resolved": "http://npm.dui88.com:80/js-beautify/-/js-beautify-1.14.0.tgz",
"integrity": "sha1-LOeQxVXVPOHj1zYyJ6z13GkCTC0=",
"requires": {
"config-chain": "^1.1.12",
"editorconfig": "^0.15.3",
"glob": "^7.1.3",
"nopt": "^5.0.0"
}
},
"js-string-escape": {
"version": "1.0.1",
"resolved": "http://npm.dui88.com:80/js-string-escape/-/js-string-escape-1.0.1.tgz",
......@@ -9589,6 +9748,13 @@
"requires": {
"fault": "^1.0.0",
"highlight.js": "~10.7.0"
},
"dependencies": {
"highlight.js": {
"version": "10.7.3",
"resolved": "http://npm.dui88.com:80/highlight.js/-/highlight.js-10.7.3.tgz",
"integrity": "sha1-aXJy45kTVuQMPKxWanTu9oF1ZTE="
}
}
},
"lru-cache": {
......@@ -10172,6 +10338,14 @@
"resolved": "http://npm.dui88.com:80/node-releases/-/node-releases-1.1.73.tgz",
"integrity": "sha1-3U6B3dUnf/hGuAtSu0DEnt96eyA="
},
"nopt": {
"version": "5.0.0",
"resolved": "http://npm.dui88.com:80/nopt/-/nopt-5.0.0.tgz",
"integrity": "sha1-UwlCu1ilEvzK/lP+IQ8TolNV3Ig=",
"requires": {
"abbrev": "1"
}
},
"normalize-package-data": {
"version": "2.5.0",
"resolved": "http://npm.dui88.com:80/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
......@@ -10873,15 +11047,13 @@
}
},
"postcss-loader": {
"version": "4.3.0",
"resolved": "http://npm.dui88.com:80/postcss-loader/-/postcss-loader-4.3.0.tgz",
"integrity": "sha1-LE3pZXzU8Hr1q0K9YKZzAE2huMw=",
"version": "6.1.1",
"resolved": "http://npm.dui88.com:80/postcss-loader/-/postcss-loader-6.1.1.tgz",
"integrity": "sha1-WN0KOszZvIfMUu/3UkTbV40RMBo=",
"requires": {
"cosmiconfig": "^7.0.0",
"klona": "^2.0.4",
"loader-utils": "^2.0.0",
"schema-utils": "^3.0.0",
"semver": "^7.3.4"
"semver": "^7.3.5"
},
"dependencies": {
"cosmiconfig": {
......@@ -11071,6 +11243,11 @@
"xtend": "^4.0.0"
}
},
"proto-list": {
"version": "1.2.4",
"resolved": "http://npm.dui88.com:80/proto-list/-/proto-list-1.2.4.tgz",
"integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk="
},
"proxy-addr": {
"version": "2.0.7",
"resolved": "http://npm.dui88.com:80/proxy-addr/-/proxy-addr-2.0.7.tgz",
......@@ -11085,6 +11262,11 @@
"resolved": "http://npm.dui88.com:80/prr/-/prr-1.0.1.tgz",
"integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY="
},
"pseudomap": {
"version": "1.0.2",
"resolved": "http://npm.dui88.com:80/pseudomap/-/pseudomap-1.0.2.tgz",
"integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM="
},
"public-encrypt": {
"version": "4.0.3",
"resolved": "http://npm.dui88.com:80/public-encrypt/-/public-encrypt-4.0.3.tgz",
......@@ -11614,6 +11796,11 @@
"@babel/runtime": "^7.12.13"
}
},
"react-codemirror2": {
"version": "7.2.1",
"resolved": "http://npm.dui88.com:80/react-codemirror2/-/react-codemirror2-7.2.1.tgz",
"integrity": "sha1-ONq0kvy+X7jr9WMOW7eSLbjToQw="
},
"react-colorful": {
"version": "5.2.2",
"resolved": "http://npm.dui88.com:80/react-colorful/-/react-colorful-5.2.2.tgz",
......@@ -12541,6 +12728,11 @@
}
}
},
"save-dev": {
"version": "0.0.1-security",
"resolved": "http://npm.dui88.com:80/save-dev/-/save-dev-0.0.1-security.tgz",
"integrity": "sha1-XrcmfiWocJwgrDNvAQHI01kAyl4="
},
"sax": {
"version": "1.2.4",
"resolved": "http://npm.dui88.com:80/sax/-/sax-1.2.4.tgz",
......@@ -12751,6 +12943,11 @@
"object-inspect": "^1.9.0"
}
},
"sigmund": {
"version": "1.0.1",
"resolved": "http://npm.dui88.com:80/sigmund/-/sigmund-1.0.1.tgz",
"integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA="
},
"signal-exit": {
"version": "3.0.3",
"resolved": "http://npm.dui88.com:80/signal-exit/-/signal-exit-3.0.3.tgz",
......
......@@ -5,7 +5,7 @@
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"storybook": "start-storybook -p 9003 -c .storybook"
"storybook": "start-storybook -s src/asserts -p 9003 -c .storybook"
},
"keywords": [],
"author": "",
......@@ -16,11 +16,13 @@
"@storybook/addon-essentials": "^6.3.2",
"@storybook/addon-links": "^6.3.2",
"@storybook/addon-notes": "^5.3.21",
"@storybook/addon-storysource": "^6.3.2",
"@storybook/addons": "^6.3.2",
"@storybook/react": "^6.3.2",
"@types/storybook__react": "^5.2.1",
"babel-loader": "^8.2.2",
"babel-plugin-import": "^1.13.3",
"highlight.js": "^10.6.0",
"storybook-readme": "^5.0.9",
"typescript": "^4.3.5",
"webpack-combine-loaders": "^2.0.4"
......@@ -31,13 +33,18 @@
"@storybook/preset-ant-design": "^0.0.2",
"antd": "^4.16.6",
"babel-preset-react-app": "^10.0.0",
"codemirror": "^5.62.0",
"css-loader": "5.2.6",
"js-beautify": "^1.14.0",
"less": "3.13.1",
"less-loader": "5.0.0",
"postcss-loader": "^6.1.1",
"react": "^17.0.2",
"react-codemirror2": "^7.2.1",
"react-dom": "^17.0.2",
"resolve-url-loader": "^4.0.0",
"style-loader": "2.0.0",
"save-dev": "0.0.1-security",
"style-loader": "^2.0.0",
"styled-components": "^5.3.0"
}
}
import React from 'react';
import { CarouselComponent } from "./carouseComponent";
import { useEffect } from 'react';
import {createStage,isExistStage} from "../../common/createStage"
interface TestProps {
/**item组件*/
......@@ -19,12 +20,12 @@ interface TestProps {
}
export const CarouselCom = (pros:TestProps)=>{
createStage();
isExistStage(()=>{
stage.removeAllChildren();
const carouseCom = new CarouselComponent(pros.carouselItem, pros.itemWidth, pros.itemHeight, pros.vertical, pros.num, pros.k);
stage.addChild(carouseCom);
carouseCom.position.set(10,20)
createStage()
isExistStage(()=>{
window.stage.removeAllChildren();
const {carouselItem,itemWidth,itemHeight,vertical,num,k} = pros
const carouseCom = new CarouselComponent(carouselItem, itemWidth, itemHeight,vertical, num, k);
window.stage.addChild(carouseCom);
carouseCom.updateData(pros.data);
})
return (
......
import React from 'react';
import { UnControlled as CodeMirror } from 'react-codemirror2';
const jsBeautify = require("js-beautify").html;
interface Props {
code:string
}
const CodePanel =(args:Props) => {
return(
<div className = "code">
<CodeMirror value={args.code}
options = {{
mode:"javascript",
theme:"dracula",
lineNumbers: true,
lineWrapping: false,
indentWithTabs: true,
smartIndent: true,
}}
/>
</div>
)
}
export const CodeCom = ()=>{
let useCode = getUseCodeStr();
let sourceCode = getSourceCode();
let itemCode = getItemCodeStr();
return (
<div className = "codeContainer">
<label className="title">组件使用代码:</label>
<CodePanel code ={useCode}/>
<label className="title">carouselItem代码:</label>
<CodePanel code ={itemCode}/>
<label className="title">组件源码代码:</label>
<CodePanel code ={sourceCode}/>
</div>
)
}
const getItemCodeStr = ()=>{
return `
class carouselItem extends window.FYGE.Container {
constructor(data) {
super();
let itemBg = window.FYGE.Sprite.fromUrl("test/prizeItemBg.png");
this.addChild(itemBg);
let itemName = new window.FYGE.TextField();
itemName.text = data.name;
itemName.size = 24;
itemName.fillColor = "#000000";
itemName.textAlign = window.FYGE.TEXT_ALIGN.CENTER;
itemName.textWidth = itemBg.width;
this.addChild(itemName);
itemName.position.set(0, 200);
let itemImg = window.FYGE.Sprite.fromUrl(data.icon);
itemBg.addChild(itemImg);
itemImg.width = 183;
itemImg.height = 183;
itemImg.position.set(5, 5);
}
}
`
}
const getUseCodeStr = ()=>{
return `
const {carouselItem,itemWidth,itemHeight,vertical,num,k} = pros
const carouseCom = new CarouselComponent(carouselItem, itemWidth, itemHeight,vertical, num, k);
window.stage.addChild(carouseCom);
carouseCom.updateData(pros.data);
`
}
const getSourceCode = ()=>{
return `
export class CarouselComponent extends FYGE.Container {
bgContainer: FYGE.Container;
itemComponent: any;
itemWidth: number;
itemHeight: number;
vertical: boolean;
timer: any;
listContainer1: any;
listContainer2: any;
listWidth: number;
listHeight: number;
bgmask: FYGE.Graphics;
num: number;
k: number;//缓动系数,系数越大移动越快。在0-1之间。
totalStep: number;//累计移动了多少距离
stopStep: number;//滑动多少距离之后暂停一下
/**
*
* @param itemComponent //item组件
* @param itemWidth //每一个item的宽度
* @param itemHeight //每一个item的高度
* @param vertical //是否是垂直的
* @param num //要显示的个数
* @param k ////缓动系数,系数越大移动越快。在0-1之间
*/
constructor(itemComponent, itemWidth, itemHeight, vertical = false, num = 3, k = 0.24) {
super();
this.num = num;
this.totalStep = 0;
this.bgContainer = new FYGE.Container();
this.itemComponent = itemComponent;
this.itemHeight = itemHeight;
this.itemWidth = itemWidth;
this.vertical = vertical;
this.k = k;
if (this.vertical) {
this.stopStep = itemHeight;
this.bgmask = new FYGE.Graphics();
this.bgmask.beginFill();
this.bgmask.drawRect(0, 0, itemWidth, num * itemHeight)
this.bgmask.endFill();
} else {
this.stopStep = itemWidth;
this.bgmask = new FYGE.Graphics();
this.bgmask.beginFill();
this.bgmask.drawRect(0, 0, num * itemWidth, itemHeight)
this.bgmask.endFill();
}
}
//更新数据触发轮播
updateData(data) {
this.removeChildren();
this.bgContainer.removeChildren();
this.timer && clearTimeout(this.timer);
this.timer = null;
this.addChild(this.bgmask);
this.listContainer1 = new FYGE.Container();
this.listContainer2 = new FYGE.Container();
data.forEach((el, index) => {
let picture1 = new this.itemComponent(el);
let picture2 = new this.itemComponent(el);
if (!this.vertical) {
picture1.position.set(index * this.itemWidth, 0);
picture2.position.set(index * this.itemWidth, 0);
} else {
picture1.position.set(0, index * this.itemHeight);
picture2.position.set(0, index * this.itemHeight);
}
this.listContainer1.addChild(picture1);
this.listContainer2.addChild(picture2);
})
if (!this.vertical) {
this.listWidth = data.length * this.itemWidth;
this.listContainer1.position.set(0, 0)
this.listContainer2.position.set(data.length * this.itemWidth, 0)
} else {
this.listHeight = data.length * this.itemHeight;
this.listContainer1.position.set(0, 0)
this.listContainer2.position.set(0, data.length * this.itemHeight)
}
this.bgContainer.addChild(this.listContainer1);
this.bgContainer.addChild(this.listContainer2);
this.addChild(this.bgContainer);
this.bgContainer.mask = this.bgmask;
setTimeout(() => {
this.loop();
}, 1000)
}
loop() {
this.timer && clearTimeout(this.timer);
this.timer = null;
var step = (this.stopStep - this.totalStep) * this.k;
step = parseInt(step.toFixed(0))
step = step ? step : 1;
var sum = this.totalStep + step;
if (sum > this.stopStep) {
step = this.stopStep - this.totalStep;
}
// console.log(step)
if (!this.vertical) {
let x1 = this.listContainer1.x
let x2 = this.listContainer2.x
if (x1 + this.listWidth < 0) {
x1 = this.listWidth + (x1 + this.listWidth);
}
if (x2 + this.listWidth < 0) {
x2 = this.listWidth + (x2 + this.listWidth);
}
this.listContainer1.position.set(x1 - step, 0)
this.listContainer2.position.set(x2 - step, 0)
} else {
let y1 = this.listContainer1.y
let y2 = this.listContainer2.y
if (y1 + this.listHeight < 0) {
y1 = this.listHeight + (y1 + this.listHeight);
}
if (y2 + this.listHeight < 0) {
y2 = this.listHeight + (y2 + this.listHeight);
}
this.listContainer1.position.set(0, y1 - step)
this.listContainer2.position.set(0, y2 - step)
}
this.totalStep = this.totalStep + step
if (Math.abs(this.stopStep - this.totalStep) < 0.1) {
this.setTimeoutSelf(() => {
this.timer = this.setTimeoutSelf(() => {
this.loop()
}, 50)
}, 1000)
this.totalStep = 0;
} else {
this.timer = this.setTimeoutSelf(() => {
this.loop()
}, 50)
}
}
setTimeoutSelf(cb, interval) { // 实现setTimeout功能
let now = Date.now
let stime = now()
let etime = stime
let loop = () => {
var timeoutTimer = requestAnimationFrame(loop)
etime = now()
if (etime - stime >= interval) {
cb()
cancelAnimationFrame(timeoutTimer)
}
}
loop()
}
destroy() {
this.timer && clearTimeout(this.timer);
this.timer = null;
}
}
`
}
\ No newline at end of file
import React from 'react';
import { UnControlled as CodeMirror } from 'react-codemirror2';
const jsBeautify = require("js-beautify").html;
interface Props {
code:string
}
const CodePanel =(args:Props) => {
return(
<div className = "code">
<CodeMirror value={args.code}
options = {{
mode:"javascript",
theme:"dracula",
lineNumbers: true,
lineWrapping: false,
indentWithTabs: true,
smartIndent: true,
}}
/>
</div>
)
}
export const CodeCom = ()=>{
let useCode = getUseCodeStr();
let sourceCode = getSourceCode();
return (
<div className = "codeContainer">
<label className="title">组件使用代码:</label>
<CodePanel code ={useCode}/>
<label className="title">组件源码代码:</label>
<CodePanel code ={sourceCode}/>
</div>
)
}
//使用代码
const getUseCodeStr = ()=>{
return `
const goldCoinAni = new GoldCoinAni(pros.start, pros.end, pros.imgUrl, pros.callBack, pros.isMinus, pros.curvature, pros.goldNum, pros.coordNum);
window.stage.addChild(goldCoinAni);
goldCoinAni.triggerAni();
`
}
//源码
const getSourceCode = ()=>{
return`
export class GoldCoinAni extends FYGE.Container {
start: any;
end: any;
imgUrl: string; //金币的图标。
isMinus: boolean; //true为向上凸,false为向下凹。
startCallback: any; //第一个金币动效结束后的回调函数
endCallback: any; //最后一个金币动效结束后的回调函数
callback:any;
lineCoords: any; //根据起始点计算出来的贝赛曲线坐标。
curvature: number; //0-1之间,0代表直线,1代表最弯
goldNum: number; //动效上面金币个数。
time: number;//动效完成时间。
coordNum:any;//坐标串个数
/**
*
* @param start 动效起点,[120,30]
* @param end 动效终点,[120,30]
* @param imgUrl 动效图片
* @param callback 每一个金币动效结束时的回调
* @param isMinus true为向上凸,false为向下凹。
* @param curvature 0-1之间,0代表直线,1代表最弯
* @param goldNum 动效上面金币个数
* @param time 动效完成时间
* @param coordNum 路线上的坐标串个数
*/
constructor(
start,
end,
imgUrl,
callback?: (start,end) => void,
isMinus = false,
curvature = 0.8,
goldNum = 10,
time = 500,
coordNum = 50,
) {
super();
this.start = start;
this.end = end;
this.imgUrl = imgUrl;
this.curvature = curvature;
this.isMinus = isMinus;
this.goldNum = goldNum;
this.callback = callback;
this.coordNum = goldNum > coordNum? goldNum:coordNum;
this.time = Math.floor( time / this.coordNum );
this.initUi();
}
initUi() {}
/**
* 重设起点和终点
* @param start [120,30]
* @param end [120,30]
*/
triggerAni(start = null, end = null) {
if(start)this.start = start;
if(end) this.end = end;
this.lineCoords = this.getBeiSaiCoords(this.start, this.end);
this._produceGoldCoinAni(this.createNewGoldCoin,(goldCodeNum)=>{
this.callback && this.callback(goldCodeNum)
});
}
createNewGoldCoin = (goldNum) => {
this._produceGoldCoinAni(() => {},(goldCodeNum) => {this.callback && this.callback(goldCodeNum)},goldNum);
}
/**
*
* @param createNewGoldCoin 金币移动时的回调函数。
* @param callback 到达终点位置后的回调函数
* @param goldCodeNum 产生的金币编号。
*/
_produceGoldCoinAni(
createNewGoldCoin?: (goldNum: number) => void,
callback?: (goldCodeNum) => void,
goldCodeNum = 1
) {
let coin = FYGE.Sprite.fromUrl(this.imgUrl);
this.addChild(coin);
coin["goldCodeNum"] = goldCodeNum;
let index = 0;
let timer = null;
let x = Math.floor(this.lineCoords.length/this.goldNum);
var loop = () => {
timer && clearTimeout(timer);
if (index === this.lineCoords.length) {
callback && callback( coin["goldCodeNum"] );
this.removeChild(coin);
return;
}
coin.position.set(
this.lineCoords[index][0],
this.lineCoords[index][1]
);
if( goldCodeNum < this.goldNum && ((index+1)% x === 0) ){
goldCodeNum ++;
createNewGoldCoin && createNewGoldCoin(goldCodeNum);
}
index = index + 1;
timer = this.setTimeoutSelf(() => {
loop();
}, this.time);
};
loop();
}
setTimeoutSelf(cb, interval) { // 实现setTimeout功能
let now = Date.now
let stime = now()
let etime = stime
let loop = () => {
var timeoutTimer = requestAnimationFrame(loop)
etime = now()
if (etime - stime >= interval) {
cb()
cancelAnimationFrame(timeoutTimer)
}
}
loop()
}
/**
* 输入起点终点坐标,得到贝塞曲线坐标
* @param start
* @param end
*/
getBeiSaiCoords(start, end) {
let x1 = start[0];
let y1 = start[1];
let x2 = end[0];
let y2 = end[1];
let x3 = (x1 + x2) / 2 + (y1 - y2) * this.curvature;
let y3 = (y1 + y2) / 2 + (x2 - x1) * this.curvature;
if (this.isMinus) {
x3 = (x1 + x2) / 2 - (y1 - y2) * this.curvature;
y3 = (y1 + y2) / 2 - (x2 - x1) * this.curvature;
}
let coords = [];
let speed =Number(1/this.coordNum);
for (let t = 0; t <= 1; t += speed) {
var x = quadraticBezier(x1, x3, x2, t);
var y = quadraticBezier(y1, y3, y2, t);
coords.push([x, y]);
}
function quadraticBezier(p1, p3, p2, t) {
var k = 1 - t;
return k * k * p1 + 2 * (1 - t) * t * p3 + t * t * p2;
}
return coords;
}
}
`
}
\ No newline at end of file
import React from 'react';
import {GoldCoinAni} from "./goldCoinAni";
import {createStage,isExistStage} from "../../common/createStage"
import { useEffect } from 'react';
interface TestProps {
/**动效起点,[120,30] */
start: Array<number>;
......@@ -21,15 +22,12 @@ interface TestProps {
/**路线上的坐标串个数 */
coordNum?:number
}
const goldCoinReceiveAniCallback =(goldCode)=>{
console.log(goldCode);
}
export const GoldCoinCom = (pros:TestProps)=>{
createStage();
createStage()
isExistStage(()=>{
stage.removeAllChildren();
window.stage.removeAllChildren();
const goldCoinAni = new GoldCoinAni(pros.start, pros.end, pros.imgUrl, pros.callBack, pros.isMinus, pros.curvature, pros.goldNum, pros.coordNum);
stage.addChild(goldCoinAni);
window.stage.addChild(goldCoinAni);
goldCoinAni.triggerAni();
})
return (
......
import React from 'react';
import {PolygonAxiosSystem} from "./polygonAxiosSystem";
import {createStage,isExistStage} from "../../common/createStage"
import {createStage,isExistStage} from "../../common/createStage";
import { useEffect } from 'react';
interface TestProps {
/**坐标系统中心点x坐标 */
centerX: number;
......@@ -13,12 +14,12 @@ interface TestProps {
/**坐标系统的单位长度,一个刻度多长 */
unitLength:number;
/**坐标系统顺时针旋转多少度,原坐标系统基准轴水平向右,也是drawShape传的第一个数值所在的坐标轴*/
rotateDeg:number;
rotateDeg?:number;
/**坐标轴名称,默认无 */
labels:Array<string>;
labels?:Array<string>;
/**坐标系统样式*/
style:any;
/**坐标值 */
style?:any;
/**坐标值:传到坐标系统中绘制出来的值,不属于构建坐标系统的参数 */
value:string;
}
export const PolygonSystemCom = (args:TestProps)=>{
......@@ -34,8 +35,8 @@ export const PolygonSystemCom = (args:TestProps)=>{
args.labels,
args.style
);
stage.removeAllChildren();
stage.addChild(polygonAxiosSystem);
window.stage.removeAllChildren();
window.stage.addChild(polygonAxiosSystem);
console.log(args.value)
polygonAxiosSystem.updateData(args.value);
})
......
import React from 'react';
import { UnControlled as CodeMirror } from 'react-codemirror2';
const jsBeautify = require("js-beautify").html;
interface Props {
code:string
}
const CodePanel =(args:Props) => {
return(
<div className = "code">
<CodeMirror value={args.code}
options = {{
mode:"javascript",
theme:"dracula",
lineNumbers: true,
lineWrapping: false,
indentWithTabs: true,
smartIndent: true,
}}
/>
</div>
)
}
export const CodeCom = ()=>{
let useCode = getUseCodeStr();
let sourceCode = getSourceCode();
return (
<div className = "codeContainer">
<label className="title">组件使用代码:</label>
<CodePanel code ={useCode}/>
<label className="title">组件源码代码:</label>
<CodePanel code ={sourceCode}/>
</div>
)
}
//使用代码
const getUseCodeStr = ()=>{
return `
const polygonAxiosSystem = new PolygonAxiosSystem(
args.centerX, //坐标系统原点在弹窗中的x坐标
args.centerY, //坐标系统原点在弹窗中的y坐标
args.axiosNum, //3个坐标轴
args.axiosNodeNum, //3个坐标节点
args.unitLength, //坐标系统的单位长度,一个刻度多长。
args.rotateDeg,//坐标系统顺时针旋转多少度,原坐标系统基准轴水平向右,也是drawShape传的第一个数值所在的坐标轴。
args.labels,
args.style
);
window.stage.addChild(polygonAxiosSystem);
polygonAxiosSystem.updateData(args.value);
`
}
//源码
const getSourceCode = ()=>{
return`
export class PolygonAxiosSystem extends FYGE.Container {
systemContainer: FYGE.Container;
orginX: number; //原点坐标X,默认0
orginY: number; //原点坐标Y,默认0
axiosLineNum: number; //坐标轴个数,默认3
axiosNodeNum: number; //坐标节点个数(包含原点),默认4个节点
step: number; //坐标轴的步长,默认40
rotationDeg: number; //整个坐标系统的旋转角度,单位度,如果不传基准轴水平右;默认0
labels: any; //坐标轴名称
style: any; //坐标系统样式
drawShapeObeject:any;//根据属性绘制的图形
/**默认样式
* style = {
gridStyle: {
color: 0x666666,
width: 1,
},
shapeStyle: {
color: 0x999999,
width: 5,
},
labelStyle: {
color: "#666666",
size: 24,
},
};
*/
/**
*
* @param x 原点坐标X
* @param y 原点坐标y
* @param axiosLineNum 坐标轴个数,默认3
* @param axiosNodeNum 坐标节点个数(包含原点),默认4个节点
* @param step 坐标轴的步长,默认40
* @param rotationDeg 整个坐标系统的旋转角度,单位度,如果不传基准轴水平右;默认0
* @param labels 坐标轴名称,默认无
* @param style 坐标系统样式
*/
constructor(
x = 0,
y = 0,
axiosLineNum = 3,
axiosNodeNum = 4,
step = 40,
rotationDeg = 0,
labels = [],
style = null
) {
super();
this.orginX = x;
this.orginY = y;
this.axiosLineNum = axiosLineNum;
this.axiosNodeNum = axiosNodeNum;
this.step = step;
this.rotationDeg = rotationDeg;
this.labels = labels;
let defaultStyle = {
gridStyle: {
color: 0xb46e42,
width: 1,
},
shapeStyle: {
color: 0x95d176,
alpha: 0.8,
},
labelStyle: {
color: "#7c3c23",
size: 24,
},
};
this.style = {
...defaultStyle,
...style,
};
this.initUi();
}
async initUi() {
this.position.set(this.orginX,this.orginY);
var coordsArr = this.computeAxiosCoords();
//绘制三角形
for (let i = 0; i < this.axiosNodeNum; i++) {
var shapeCoords = [];
coordsArr.forEach((el) => {
shapeCoords.push([el[i][0], el[i][1]]);
});
this.drawAxiosShape(shapeCoords);
}
//绘制轴线
for(let i =0 ;i<coordsArr.length-1;i++){
this.drawAxiosShape(coordsArr[i]);
}
}
/**
*
* @param points 一个坐标轴上所有节点坐标
* @param index 第几个坐标轴,从0开始
* @returns
*/
drawAxiosLabel(points, index) {
if (this.labels.length === 0) return;
let text = this.getText(
this.labels[index],
this.style.labelStyle.size,
this.style.labelStyle.color
);
let coordsArr = JSON.parse(JSON.stringify(points));
let len = coordsArr.length;
let dx = coordsArr[1][0] - coordsArr[0][0];
let dy = coordsArr[1][1] - coordsArr[0][1];
let x = coordsArr[len - 1][0];
let y = coordsArr[len - 1][1];
let coords = [x, y];
if (dx < 0) {
coords[0] = coords[0] - text.textWidth;
}
if (dy < 0) {
coords[1] = coords[1] - text.textHeight;
}
this.addChild(text).position.set(coords[0], coords[1]);
}
/**
*
* @param points
* @param isDrawGrid 是否是绘制坐标格网,不是就是根据实际值绘制图形。
* @param isLineShape 实际值如果相差很大,一个很大,另外都为0,就绘制线。
*/
drawAxiosShape(points, isDrawGrid = true) {
var data = [];
points.forEach(el => {
data.push([Number(el[0].toFixed(2)),Number(el[1]).toFixed(2)])
});
points = data;
let shape = null;
if (!isDrawGrid) {
var polygonData = [];
points.forEach(el => {
polygonData.push(Number(el[0]),Number(el[1]))
});
shape = new FYGE.Graphics();
shape.beginFill(this.style.shapeStyle.color,this.style.shapeStyle.alpha);
shape.drawPolygon(polygonData)
} else {
shape = new FYGE.Shape();
shape.beginStroke(
this.style.gridStyle.color,
this.style.gridStyle.width
);
shape.moveTo(points[0][0], points[0][1]);
points.forEach((el, index) => {
if (index !== 0) {
shape.lineTo(el[0], el[1]);
}
});
shape.endStroke();
}
this.addChild(shape);
return shape;
}
computeAxiosCoords() {
let baseCoordsArr = [];
//计算基准轴上的坐标,
for (let j = 0; j < this.axiosNodeNum; j++) {
let x = j * this.step;
let y = 0;
baseCoordsArr[j] = [x, y];
}
//计算基准轴上坐标集合经过旋转后的得到的坐标集合
//@ts-ignore
let coordsArr = new Array(this.axiosLineNum).fill([]);
const vectorArr = this.computeVectorArr();
for (let i = 0; i < vectorArr.length; i++) {
let rotationRatio = vectorArr[i]; //旋转系数;
let coords = [];
baseCoordsArr.forEach((el) => {
let x =
el[0] * rotationRatio[0][0] + el[1] * rotationRatio[0][1];
let y =
el[0] * rotationRatio[1][0] + el[1] * rotationRatio[1][1];
coords.push([x, y]);
});
coordsArr[i] = coords;
}
//所有坐标加上原点坐标
coordsArr.forEach((el) => {
el.forEach((item) => {
item[0] = item[0] ;
item[1] = item[1] ;
});
});
return coordsArr;
}
//计算每个坐标轴相对于基准轴的旋转矢量
computeVectorArr() {
//@ts-ignore
let vectorArr = new Array(this.axiosLineNum).fill([]);
let stepDeg = 360 / this.axiosLineNum;
for (let i = 0; i < this.axiosLineNum + 1; i++) {
let deg = ((i * stepDeg + this.rotationDeg) / 180) * Math.PI;
vectorArr[i] = [
[Number(Math.cos(deg).toFixed(5)), Number(-Math.sin(deg).toFixed(5))],
[Number(Math.sin(deg).toFixed(5)), Number(Math.cos(deg).toFixed(5))],
];
}
return vectorArr;
}
computeRotationVector() {
let deg = (180 / 180) * Math.PI;
let rotationVector = [
[Math.cos(deg), -Math.sin(deg)],
[Math.sin(deg), Math.cos(deg)],
];
return rotationVector;
}
updateData(str) {
var strArr = str.split(",");
if (strArr.length !== this.axiosLineNum) {
console.log("传参个数与坐标轴线条数不一致");
return;
}
this.drawShapeObeject && this.removeChild(this.drawShapeObeject)
strArr = this.getAddedData(strArr);
strArr = this.computeInputData(strArr);
var points = [];
strArr.forEach((el) => {
points.push([Number(el), 0]);
});
const vectorArr = this.computeVectorArr();
let coords = [];
for (let i = 0; i < vectorArr.length - 1; i++) {
let rotationRatio = vectorArr[i]; //旋转系数;
let el = points[i];
let x = el[0] * rotationRatio[0][0] + el[1] * rotationRatio[0][1];
let y = el[0] * rotationRatio[1][0] + el[1] * rotationRatio[1][1];
coords.push([x, y]);
}
coords.push(coords[0]);
this.drawShapeObeject = this.drawAxiosShape(coords,false);
}
//对坐标数据进行处理,防止数据超限
computeInputData(inputData) {
var result = [];
let len = this.step * (this.axiosNodeNum - 1) - 5; //坐标轴的长度
inputData.forEach((el) => {
var ratio = 1 - 100 / (Number(el) + 100);
result.push(len * ratio);
});
return result;
}
/**
* 判断否有小与15的数,有的话所有数都加20,防止数据太小绘不出来
* @param inputData 输入数据
*/
getAddedData(inputData) {
var isNeedAdd = false;
inputData.forEach((el) => {
if (Number(el) < 15) {
isNeedAdd = true;
}
});
let data = [];
if (!isNeedAdd) {
return inputData;
} else {
inputData.forEach((el) => {
data.push(Number(el) + 15);
});
}
return data;
}
getMaxData(inputData) {
let max = 0;
inputData.forEach((el) => {
if (Number(el) > max) {
max = Number(el);
}
});
return max;
}
getText(
txt: string,
size: number,
color: string = "#eee",
align: FYGE.TEXT_ALIGN = FYGE.TEXT_ALIGN.LEFT,
textWidth: number = 0,
x: number = 0,
y: number = 0
): FYGE.TextField {
var text = new FYGE.TextField();
text.fillColor = color;
text.size = size;
text.textWidth = textWidth;
text.textAlign = align;
text.x = x;
text.y = y;
text.text = txt;
text.bold = true;
return text;
}
}
`
}
\ No newline at end of file
// var aa = this.addChild(new RichText(
// [
// { text: "啊请问请问", style: { color: "#000000", size: 30 } },
// { text: "=2134324234啊请问请问", style: { color: "#ff0000", size: 30 } },
// { text: "驱蚊器问问", style: { color: "#000000", size: 30 } }
// ]
// ))
// aa.text = [
// { text: "啊请问请问", style: { color: "#000000", size: 30 } },
// { text: "=2134", style: { color: "#ff0000", size: 30 } },
// { text: "驱蚊器问问", style: { color: "#000000", size: 30 } }
// ]
// aa.position.set(375, 800);
// [{text: "测试",style:{color: ""}},{},{}]
interface IRichTextEle {
text: string,
style: { color: string, size: number }
}
export class RichText extends FYGE.Container {
private static cache: FYGE.TextField[] = []
/**
*
* @param text
*/
constructor(text?: IRichTextEle[]) {
super()
if (text) this.text = text;
}
/**
* 水平对齐方式,默认居中
*/
get textAlign() {
return this._textAlign
}
set textAlign(value: FYGE.TEXT_ALIGN) {
if (this._textAlign !== value) {
this._textAlign = value;
this.adaptate();
}
}
private _textAlign: FYGE.TEXT_ALIGN = FYGE.TEXT_ALIGN.CENTER;
/**
* 垂直居中方式,默认居中
*/
get verticalAlign() {
return this._verticalAlign
}
set verticalAlign(value: FYGE.VERTICAL_ALIGN) {
if (this._verticalAlign !== value) {
this._verticalAlign = value;
this.adaptate();
}
}
private _verticalAlign: FYGE.VERTICAL_ALIGN = FYGE.VERTICAL_ALIGN.MIDDLE;
/**
* 文字间隙
*/
get gap(): number {
return this._gap;
};
set gap(value: number) {
if (this._gap != value) {
this._gap = value;
this.adaptate();
}
};
private _gap: number = 0;
/**
* 文本
*/
private _text: IRichTextEle[];
/**
* 按顺序
*/
get text(): IRichTextEle[] {
return this._text
}
/**
*
*/
set text(value: IRichTextEle[]) {
this._text = value;
var arr = value || [];
for (var i = 0; i < arr.length; i++) {
let a = arr[i];
let c: FYGE.TextField = this.children[i] || this.addChild(RichText.cache.shift() || new FYGE.TextField());
c.text = a.text;
c.fillColor = a.style.color;
c.size = a.style.size;
}
//如果多了,去掉后面的,回收
if (this.children.length > arr.length) {
//移除后序
for (var i = this.children.length - 1; i >= arr.length; i--) {
let c = this.children[i];
this.removeChild(c);
RichText.cache.push(c);
}
}
//适配
this.adaptate()
}
/**
* 适配,
*/
private adaptate() {
if (!this.children.length) return
var len = this.children.length;
//算总长度
var sum = 0;
for (var m = 0; m < len; m++) {
sum += this.children[m].textWidth;
}
sum += (len - 1) * this._gap;
//算出左边第一个元素的位置
var left: number;
if (this._textAlign == FYGE.TEXT_ALIGN.LEFT) {
left = 0
}
else if (this._textAlign == FYGE.TEXT_ALIGN.RIGHT) {
left = -sum
} else {
left = -sum / 2
}
var temSum = 0;
for (var i = 0; i < this.children.length; i++) {
this.children[i].x = left + temSum
temSum += this.children[i].textWidth + this._gap;
}
var up: number;
if (this._verticalAlign == FYGE.VERTICAL_ALIGN.UP) {
up = 0
}
else if (this._verticalAlign == FYGE.VERTICAL_ALIGN.DOWN) {
up = -1
} else {
up = -1 / 2
}
for (var i = 0; i < this.children.length; i++) {
this.children[i].y = this.children[i].textHeight * up;
}
}
}
\ No newline at end of file
import React from 'react';
import {RichText} from "./RichText";
import {createStage,isExistStage} from "../../common/createStage";
import { useEffect } from 'react';
interface TestProps {
/** 要展示的文本内容 */
textArr:Array<any>;
/** 文本中心点的x坐标 */
x:number;
/** 文本中心点的y坐标 */
y:number;
}
export const RichTextCom = (args:TestProps)=>{
createStage();
isExistStage(()=>{
window.stage.removeAllChildren();
const richText = new RichText();
richText.position.set(args.x,args.y)
richText.text = args.textArr;
window.stage.addChild(richText);
})
return (
<div></div>
)
}
\ No newline at end of file
import React from 'react';
import { UnControlled as CodeMirror } from 'react-codemirror2';
const jsBeautify = require("js-beautify").html;
interface Props {
code:string
}
const CodePanel =(args:Props) => {
return(
<div className = "code">
<CodeMirror value={args.code}
options = {{
mode:"javascript",
theme:"dracula",
lineNumbers: true,
lineWrapping: false,
indentWithTabs: true,
smartIndent: true,
}}
/>
</div>
)
}
export const CodeCom = ()=>{
let useCode = getUseCodeStr();
let sourceCode = getSourceCode();
return (
<div className = "codeContainer">
<label className="title">组件使用代码:</label>
<CodePanel code ={useCode}/>
<label className="title">组件源码代码:</label>
<CodePanel code ={sourceCode}/>
</div>
)
}
//使用代码
const getUseCodeStr = ()=>{
return `
const richText = new RichText();
richText.position.set(args.x,args.y)
richText.text = args.textArr;
window.stage.addChild(richText);
`
}
//源码
const getSourceCode = ()=>{
return`
// var aa = this.addChild(new RichText(
// [
// { text: "啊请问请问", style: { color: "#000000", size: 30 } },
// { text: "=2134324234啊请问请问", style: { color: "#ff0000", size: 30 } },
// { text: "驱蚊器问问", style: { color: "#000000", size: 30 } }
// ]
// ))
// aa.text = [
// { text: "啊请问请问", style: { color: "#000000", size: 30 } },
// { text: "=2134", style: { color: "#ff0000", size: 30 } },
// { text: "驱蚊器问问", style: { color: "#000000", size: 30 } }
// ]
// aa.position.set(375, 800);
// [{text: "测试",style:{color: ""}},{},{}]
interface IRichTextEle {
text: string,
style: { color: string, size: number }
}
export class RichText extends FYGE.Container {
private static cache: FYGE.TextField[] = []
/**
*
* @param text
*/
constructor(text?: IRichTextEle[]) {
super()
if (text) this.text = text;
}
/**
* 水平对齐方式,默认居中
*/
get textAlign() {
return this._textAlign
}
set textAlign(value: FYGE.TEXT_ALIGN) {
if (this._textAlign !== value) {
this._textAlign = value;
this.adaptate();
}
}
private _textAlign: FYGE.TEXT_ALIGN = FYGE.TEXT_ALIGN.CENTER;
/**
* 垂直居中方式,默认居中
*/
get verticalAlign() {
return this._verticalAlign
}
set verticalAlign(value: FYGE.VERTICAL_ALIGN) {
if (this._verticalAlign !== value) {
this._verticalAlign = value;
this.adaptate();
}
}
private _verticalAlign: FYGE.VERTICAL_ALIGN = FYGE.VERTICAL_ALIGN.MIDDLE;
/**
* 文字间隙
*/
get gap(): number {
return this._gap;
};
set gap(value: number) {
if (this._gap != value) {
this._gap = value;
this.adaptate();
}
};
private _gap: number = 0;
/**
* 文本
*/
private _text: IRichTextEle[];
/**
* 按顺序
*/
get text(): IRichTextEle[] {
return this._text
}
/**
*
*/
set text(value: IRichTextEle[]) {
this._text = value;
var arr = value || [];
for (var i = 0; i < arr.length; i++) {
let a = arr[i];
let c: FYGE.TextField = this.children[i] || this.addChild(RichText.cache.shift() || new FYGE.TextField());
c.text = a.text;
c.fillColor = a.style.color;
c.size = a.style.size;
}
//如果多了,去掉后面的,回收
if (this.children.length > arr.length) {
//移除后序
for (var i = this.children.length - 1; i >= arr.length; i--) {
let c = this.children[i];
this.removeChild(c);
RichText.cache.push(c);
}
}
//适配
this.adaptate()
}
/**
* 适配,
*/
private adaptate() {
if (!this.children.length) return
var len = this.children.length;
//算总长度
var sum = 0;
for (var m = 0; m < len; m++) {
sum += this.children[m].textWidth;
}
sum += (len - 1) * this._gap;
//算出左边第一个元素的位置
var left: number;
if (this._textAlign == FYGE.TEXT_ALIGN.LEFT) {
left = 0
}
else if (this._textAlign == FYGE.TEXT_ALIGN.RIGHT) {
left = -sum
} else {
left = -sum / 2
}
var temSum = 0;
for (var i = 0; i < this.children.length; i++) {
this.children[i].x = left + temSum
temSum += this.children[i].textWidth + this._gap;
}
var up: number;
if (this._verticalAlign == FYGE.VERTICAL_ALIGN.UP) {
up = 0
}
else if (this._verticalAlign == FYGE.VERTICAL_ALIGN.DOWN) {
up = -1
} else {
up = -1 / 2
}
for (var i = 0; i < this.children.length; i++) {
this.children[i].y = this.children[i].textHeight * up;
}
}
}
`
}
\ No newline at end of file
import React from 'react';
import { CarouselCom } from '../canvasCom/carouselCom/carouselCom';
class carouselItem extends FYGE.Container {
import { CodeCom } from "../canvasCom/carouselCom/codeCom"
import {
Title,
Subtitle,
Description,
ArgsTable,
PRIMARY_STORY,
} from '@storybook/addon-docs';
import { clearStage } from '../common/createStage';
class carouselItem extends window.FYGE.Container {
constructor(data) {
super();
let itemBg = FYGE.Sprite.fromUrl("//yun.duiba.com.cn/spark/assets/029a53c6dc60b0c3a4538862cbeb0e3a329152f4.png");
let itemBg = window.FYGE.Sprite.fromUrl("test/prizeItemBg.png");
this.addChild(itemBg);
let itemName = new FYGE.TextField();
let itemName = new window.FYGE.TextField();
itemName.text = data.name;
itemName.size = 24;
itemName.fillColor = "#000000";
itemName.textAlign = FYGE.TEXT_ALIGN.CENTER;
itemName.textAlign = window.FYGE.TEXT_ALIGN.CENTER;
itemName.textWidth = itemBg.width;
this.addChild(itemName);
itemName.position.set(0, 200);
let itemImg = FYGE.Sprite.fromUrl(data.icon);
let itemImg = window.FYGE.Sprite.fromUrl(data.icon);
itemBg.addChild(itemImg);
itemImg.width = 183;
itemImg.height = 183;
......@@ -26,12 +34,38 @@ export default {
title: 'Canvas组件/轮播组件',
//👇 Creates specific argTypes
argTypes: {
backgroundColor: { control: 'color' },
label: {
description: 'Overwritten description',
table: {
type: {
summary: 'Something short',
detail: 'Something really really long'
},
},
control: {
type: null,
},
},
},
args: {
//👇 Now all Button stories will be primary.
primary: true,
primary: false,
},
parameters: {
docs: {
page: () => {
clearStage();
return( <>
<Title />
<Subtitle />
<Description />
<ArgsTable story={PRIMARY_STORY} />
<CodeCom/>
</>)
},
}
},
};
//👇 We create a “template” of how args map to rendering
const Template = (args) => <CarouselCom {...args} />;
......@@ -54,7 +88,7 @@ Primary.args = {
{
"rule": "ru_1",
"name": "飞科剃须刀1",
"icon": "//yun.duiba.com.cn/polaris/一波1.8644720387778750b4af371deb5f86562897aab2.jpg",
"icon": "prize.jpg",
"coins": 10000,
"stock": 111111111111,
"channel":0
......@@ -62,7 +96,7 @@ Primary.args = {
{
"rule": "ru_1",
"name": "飞科剃须刀2",
"icon": "//yun.duiba.com.cn/polaris/一波1.8644720387778750b4af371deb5f86562897aab2.jpg",
"icon": "prize.jpg",
"coins": 100,
"stock": 0,
"channel":0
......@@ -70,7 +104,7 @@ Primary.args = {
{
"rule": "ru_1",
"name": "飞科剃须刀3",
"icon": "//yun.duiba.com.cn/polaris/一波1.8644720387778750b4af371deb5f86562897aab2.jpg",
"icon": "prize.jpg",
"coins": 100,
"stock": 0,
"channel":0
......@@ -78,7 +112,7 @@ Primary.args = {
{
"rule": "ru_1",
"name": "飞科剃须刀4",
"icon": "//yun.duiba.com.cn/polaris/一波1.8644720387778750b4af371deb5f86562897aab2.jpg",
"icon": "prize.jpg",
"coins": 100,
"stock": 0,
"channel":2
......@@ -86,7 +120,7 @@ Primary.args = {
{
"rule": "ru_1",
"name": "飞科剃须刀5",
"icon": "//yun.duiba.com.cn/polaris/一波1.8644720387778750b4af371deb5f86562897aab2.jpg",
"icon": "prize.jpg",
"coins": 100,
"stock": 0,
"channel":2
......@@ -94,7 +128,7 @@ Primary.args = {
{
"rule": "ru_1",
"name": "飞科剃须刀6",
"icon": "//yun.duiba.com.cn/polaris/一波1.8644720387778750b4af371deb5f86562897aab2.jpg",
"icon": "prize.jpg",
"coins": 100,
"stock": 0,
"channel":1
......@@ -102,7 +136,7 @@ Primary.args = {
{
"rule": "ru_1",
"name": "飞科剃须刀7",
"icon": "//yun.duiba.com.cn/polaris/一波1.8644720387778750b4af371deb5f86562897aab2.jpg",
"icon": "prize.jpg",
"coins": 100,
"stock": 1,
"channel":0
......@@ -110,7 +144,7 @@ Primary.args = {
{
"rule": "ru_1",
"name": "飞科剃须刀8",
"icon": "//yun.duiba.com.cn/polaris/一波1.8644720387778750b4af371deb5f86562897aab2.jpg",
"icon": "prize.jpg",
"coins": 100,
"stock": 1,
"channel":2
......@@ -118,7 +152,7 @@ Primary.args = {
{
"rule": "ru_1",
"name": "飞科剃须刀0",
"icon": "//yun.duiba.com.cn/polaris/一波1.8644720387778750b4af371deb5f86562897aab2.jpg",
"icon": "prize.jpg",
"coins": 100,
"stock": 1,
"channel":2
......
import React from 'react';
import { GoldCoinCom } from '../canvasCom/goldCoinCom/GoldCoinCom.tsx';
import { GoldCoinCom } from '../canvasCom/goldCoinCom/GoldCoinCom';
import { CodeCom } from '../canvasCom/goldCoinCom/codeCom';
import {
Title,
Subtitle,
Description,
ArgsTable,
PRIMARY_STORY,
} from '@storybook/addon-docs';
import { clearStage } from '../common/createStage';
export default {
component: GoldCoinCom,
title: 'Canvas组件/金币动效',
//👇 Creates specific argTypes
argTypes: {
backgroundColor: { control: 'color' },
label: {
description: 'Overwritten description',
table: {
type: {
summary: 'Something short',
detail: 'Something really really long'
},
},
control: {
type: null,
},
},
},
args: {
//👇 Now all Button stories will be primary.
primary: true,
parameters: {
docs: {
page: () => {
clearStage();
return( <>
<Title />
<Subtitle />
<Description />
<ArgsTable story={PRIMARY_STORY} />
<CodeCom></CodeCom>
</>)
},
}
},
};
const goldCoinReceiveAniCallback =(goldCode)=>{
console.log(goldCode);
}
//👇 We create a “template” of how args map to rendering
const Template = (args) => <GoldCoinCom {...args} />;
......@@ -22,13 +53,19 @@ const Template = (args) => <GoldCoinCom {...args} />;
export const Primary = Template.bind({});
Primary.parameters = {
layout: 'centered',
backgrounds: {
values: [
{ name: 'red', value: '#f00' },
{ name: 'green', value: '#0f0' },
],
},
};
Primary.args = {
primary: true,
label: '金币动效',
start:[100, 200],
end:[516, 200],
imgUrl:"//yun.duiba.com.cn/spark/assets/eed18886070638f6119f04ba849cf93e23e0d186.png",
imgUrl:"homeGoldIconImg.png",
callBack: goldCoinReceiveAniCallback.bind(this),
isMinus:true,
curvature:0.2,
......
import React from 'react';
import { PolygonSystemCom } from '../canvasCom/polygonSystemCom/PolygonSystemCom.tsx';
import { PolygonSystemCom } from '../canvasCom/polygonSystemCom/PolygonSystemCom';
import {CodeCom} from "../canvasCom/polygonSystemCom/codeCom"
import {
Title,
Subtitle,
Description,
ArgsTable,
PRIMARY_STORY,
} from '@storybook/addon-docs';
import { clearStage } from '../common/createStage';
export default {
component: PolygonSystemCom,
title: 'Canvas组件/多变形坐标系统',
//👇 Creates specific argTypes
argTypes: {
backgroundColor: { control: 'color' },
label: {
description: 'Overwritten description',
table: {
type: {
summary: 'Something short',
detail: 'Something really really long'
},
},
control: {
type: null,
},
},
},
args: {
//👇 Now all Button stories will be primary.
primary: true,
parameters: {
docs: {
page: () => {
clearStage();
return( <>
<Title />
<Subtitle />
<Description />
<ArgsTable story={PRIMARY_STORY} />
<CodeCom></CodeCom>
</>)
},
}
},
};
......@@ -30,7 +61,7 @@ Primary.args = {
axiosNodeNum:3, //3个坐标节点
unitLength:30, //坐标系统的单位长度,一个刻度多长。
rotateDeg:90,
labels:["haha","heihei"],
labels:["haha","heihei","heihei"],
value:"70,100,90",
style:{
gridStyle: {
......@@ -45,7 +76,6 @@ Primary.args = {
color: "#7c3c23",
size: 24,
},
}
}
};
import React from 'react';
import { RichTextCom } from '../canvasCom/richTextCom/RichTextCom';
import { CodeCom } from '../canvasCom/richTextCom/codeCom';
import {
Title,
Subtitle,
Description,
ArgsTable,
PRIMARY_STORY,
} from '@storybook/addon-docs';
import { clearStage } from '../common/createStage';
export default {
component: RichTextCom,
title: 'Canvas组件/丰富文本',
//👇 Creates specific argTypes
argTypes: {
label: {
description: 'Overwritten description',
table: {
type: {
summary: 'Something short',
detail: 'Something really really long'
},
},
control: {
type: null,
},
},
},
parameters: {
docs: {
page: () => {
clearStage();
return( <>
<Title />
<Subtitle />
<Description />
<ArgsTable story={PRIMARY_STORY} />
<CodeCom></CodeCom>
</>)
},
}
},
};
//👇 We create a “template” of how args map to rendering
const Template = (args) => <RichTextCom {...args} />;
//👇 Each story then reuses that template
export const Primary = Template.bind({});
Primary.parameters = {
layout: 'centered',
backgrounds: {
values: [
{ name: 'red', value: '#f00' },
{ name: 'green', value: '#0f0' },
],
},
};
Primary.args = {
primary: true,
label: '丰富文本',
textArr: [
{ text: "啊请问请问", style: { color: "#00FF7F", size: 30 } },
{ text: "=2134324234啊请问请问", style: { color: "#ff0000", size: 30 } },
{ text: "驱蚊器问问", style: { color: "#9932CC", size: 30 } }
],
x:400,
y:100,
};
export const createStage = ()=>{
const height = document.body.clientHeight*(window.devicePixelRatio || 1)||1624;
const width = document.body.clientWidth*(window.devicePixelRatio || 1)||750;
console.log("ssssss",document.body.clientHeight,document.body.clientWidth)
let canvas = document.getElementById("canvas-container")
// const height = 800;
// const width = 750;
const scale = window.devicePixelRatio;
let canvas = document.getElementById("canvas-container");
if(!canvas){
canvas = document.createElement("canvas");
canvas.setAttribute("id","canvas-container")
canvas.setAttribute("height",height+"");
canvas.setAttribute("width",width+"");
canvas.style.position = "absolute";
canvas.style.top = 0 + "px";
canvas.style.left = 0 + "px";
document.body.appendChild(canvas);
}else{
return;
}
var stage = new FYGE.Stage(
var stage = new window.FYGE.Stage(
canvas,
width,
height,
document.body.clientWidth,
document.body.clientHeight,
FYGE.RENDERER_TYPE.CANVAS,
width,
height,
window.FYGE.RENDERER_TYPE.CANVAS,
false,
false
)
......@@ -31,7 +38,7 @@ export const createStage = ()=>{
canvas.addEventListener("click",mouseEvent,false);
function loop() {
stage.flush();
FYGE.Tween.flush();
window.FYGE.Tween.flush();
requestAnimationFrame(loop);
}
......@@ -39,8 +46,8 @@ export const createStage = ()=>{
window.stage = stage;
}
export const isExistStage = (cb)=>{
if(stage){
cb();
if(window.stage){
cb && cb();
}else{
setTimeout(isExistStage,100);
}
......
interface Window {
FYGE: any;
stage: any;
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment