精华内容
下载资源
问答
  • 这是一套蓝色简洁扁平文字图片排版PPT模板,共21张。第一PPT模板网提供精美简洁幻灯片模板免费下载; 关键词:极简风格幻灯片模板,欧美扁平文字排版PowerPoint模板,蓝色幻灯片图表,商务幻灯片背景图片,....
  • 最近写了套接发送文字图片功能,但是遇到一个问题就是,如我发送文本格式如:Text1 ImgPath1 Text2 ImgPath2...。我将其转换base64然后序列接着转成byte[]最后放到流里面,但是问题是我接收消息先将接收的字节组...
  • 因为所做项目需要应用国际,语言包用的是intl-messageformat的插件,自己根据需求又修改的,这样文字的问题配置js就可以解决了。 Intl对应的文件内容: import IntlMessageFormat from 'intl-messageformat';...

    因为所做项目需要应用国际化,语言包用的是intl-messageformat的插件,自己根据需求又修改的,这样文字的问题配置js就可以解决了。

    Intl对应的文件内容:

    import IntlMessageFormat from 'intl-messageformat';
    import zh from '../locales/zh-CN';
    import en from '../locales/en-US';
    const MESSAGES = { en, zh };
    
    
    class Intl {
        constructor(LOCALE){
            this.LOCALE = LOCALE
            this.set = this.set.bind(this);
            this.get = this.get.bind(this);
        }
        set(LOCALE){
            this.LOCALE = LOCALE;
        }
        get(key, defaultMessage, options) {
            let msg = MESSAGES[this.LOCALE][key];
            if (msg == null) {
                if (defaultMessage != null) {
                    return defaultMessage;
                }
                return key;
            }
            if (options) {
                msg = new IntlMessageFormat(msg, this.LOCALE);
                return msg.format(options);
            }
            return msg;
        }
    }
    
    export default Intl;

    en-US.js和zh-CN.js都是一个对象

    export default ({
            "hello" : "你好",
    })

    之后为了使用方便,将语言配置添加到redux中使用,actions如下:

    /**
     * 设置Actions的type值,需要修改的store对象的值。
     */
    import Storage from '../container/storage'
    
    const prefix = 'LANG'
    
    export const SET_LANG = `${prefix}/SET_LANG`
    export const setLang = function(Intl) {
      Storage.setItem("LANGUAGE_TYPE" , Intl.LOCALE)
      return {type: SET_LANG, Intl}
    }

    reducers如下:

    /**
     * 引入Actions中的type名称及需要返回的store值
     * 设置初始的initalState值
     * 根据acitions的type值进行修改store对象的值
     */
    
    import * as Lang from '../Actions/Lang'
    const initialState = {}
    
    export default function (state = initialState, action) {
      switch (action.type) {
        case Lang.SET_LANG:
          return Object.assign({}, state, action.Intl)
        default:
          return state
      }
    }

    Root合并的文件我也贴一下吧,好麻烦啊,我就想介绍一下语言包配置好不好,难道还需要讲一遍redux吗....新手的话建议粘贴复制照着搞,以能跑起来看效果为主......

    /**
     * 函数修改store的值
     * 后续需要添加的reducers纯函数,先引入之后格式例如AppShellReducer
     * 引入之后插入到appReudcer对象中即可
     * combinReducers方法的作用是将多个小reducer函数整合成一个大的reducers对象。
     */
    
    import { combineReducers } from 'redux'
    
    import LangReducer from './Lang'
    
    const appReducer = combineReducers({
      "lang": LangReducer,
    })
    
    export default (state, action) => {
      return appReducer(state, action)
    }
    

    还有一个connect进行关联的文件.....

    import { connect } from 'react-redux'
    
    // Connect a component to specific reducer names.
    // e.g., connect(MyComponent, "core", "settings")
    export default function(component, ...reducers) {
      let connector = connect((state) => {
        var props =  {}
    
        reducers.forEach((name) => {
          var value = state[name]
    
          if (!value) {
            throw new Error(`Tried connecting '${component.name}' to unknown state: ${name}`)
          }
           
          props[name] = value
        })
    
        return props
      }, (dispatch) => {
        return {
          dispatch
        }
      })
      return connector(component)
    }

    以上这些,新手照葫芦画瓢你就可以使用redux了....我真的没有骗你,有新需要储存的数据的话,添加对应的actions及reducers文件,然后在root进行关联,项目目录大概如下:

     

    整不明白的留言吧,没有招啊,redux配置的时候就是很麻烦的啊,但是搞明白了用起来确实是爽,现在我们把RootReducer对象注入到跟组件中,这样组件就能使用存储到store中的数据了。

    import React, { Component } from 'react';
    import ReactDOM from 'react-dom';
    import thunk from 'redux-thunk'
    import RootReducer from './reducers/Root'
    //引入redux状态控制器
    import { createStore , applyMiddleware} from 'redux';
    import { Provider } from 'react-redux';
    import App from './container/App';      //通过App引入导航
    //引入谷歌统计
    import ReactGA from 'react-ga';
    class Index extends Component{
        render(){
            return (
                <div>
                    <App />
                </div>
            )
        }
    }
    //引入RootReducer对象中的纯函数
    //将store注入进整体组件中
    const store = createStore(
        RootReducer ,
        applyMiddleware(thunk)
    );
    ReactDOM.render(
        <Provider store = {store}>
            <Index />   
        </Provider>
    //   <Pro />
        , document.getElementById('root')
    )
    

    Index就是跟组件的内容哈,太麻烦了,然后在App.js中初始化语言类型。

    import React, { Component } from 'react';
    //路由配置
    import {BrowserRouter, Route,Switch} from 'react-router-dom'; //BrowserRouter路径不加#号须有服务器支持HashRouter会有#
    import connect from '../reducers/connect'
     //引入多语言
    import Intl from '../messageformat/Intl'
    import Home from './Home'
    import * as LangActions from '../Actions/Lang'
    import Storage from './storage'
    
    class App extends Component {
      constructor(props){
        super(props)
         // 注入当前语言
         let lang = Storage.getItem("LANGUAGE_TYPE");
         this.props.dispatch(LangActions.setLang(new Intl(lang)));
      }
      render() {
        const lang = this.props.lang;
        if(JSON.stringify(lang) === "{}") return false;
        return (
          <BrowserRouter>
            <div>
             <Switch>
                {/* 路由适配地址   后期页面如果有跳转   直接在下面添加就可以 */}
                  <Route exact path="/" component={Home} />
                </Switch>
            </div>
          </BrowserRouter>
        )
      }
    }
     export default connect(App , "lang");
    

    在index.html中需要设置默认的LANGUAGE_TYPE值,一般公司会要求会先从本地储存里面取,没设置过的话从连接里面取,连接里面没有的话读取浏览器默认语言,大致是这个过程,代码就不贴了,太烦了,这样操作之后再下面的组件里面讲connect和组件关联上就可以直接使用了。如下

    
    class Demo extends ECompontent {
        constructor() {
            super();
        }
        componentDidMount() {
        }
        render() {
            const Intl = this.props.lang.get;
            return (
                <div>
                    <p>{Intl("hello")}</p>
                </div>
            )
        }
    }
    export default connect(Demo, "lang");

    然后是切换语言的方法.....我累了真心的,我估计大部分人照我这个也够呛能弄明白,你要是确实碰到这样的需求了,留言吧,我看到了会加你帮你搞一下。

    import * as LangActions from '../../Actions/Lang'
    import IntlObj from '../../messageformat/Intl'
    
    class Header extends ECompontent {
        constructor() {
            super();
        }
        _handerSaveLang(langType){
            this.props.dispatch(LangActions.setLang(new IntlObj(langType)))
            window.location.reload();
        }
        render() {
            const Intl = this.props.lang.get;
            return (
                <div>
                    <span onClick={()=>{this._handerSaveLang("en")}}>EN</span>
                    <span onClick={()=>{this._handerSaveLang("zh")}}>中文</span>
                </div>
            )
        }
    }
    export default connect(Header, "lang");

    派发actions中已经写好的事件,然后刷新一下页面,至此over。

    不过还有图片及样式的问题需要处理,样式是针对不同语言单独写了一套,都是以中文为样板修改的,所以样式修改并不多,因为每次切换语言的话都会重新刷新页面,所以直接在index.html做的判断引入处理。

    let cssNameUrl = [];
            if(localStorage.getItem("LANGUAGE_TYPE") === "en"){
              cssNameUrl = ["GreenStyle_en" , "Toast_en" , "antd_en" , "register_en"];              //配置需要引入的css
            }else{
              cssNameUrl = ["GreenStyle" , "Toast" , "antd" , "register"];                    //配置需要引入的css
            }
            let linkUrlObj = {}
            for( let i =0 ; i < cssNameUrl.length ; i ++){
              linkUrlObj[i] = document.createElement("link");
              linkUrlObj[i].setAttribute("rel" , "stylesheet");
              linkUrlObj[i].setAttribute("href" , "%PUBLIC_URL%/css/" + cssNameUrl[i] + ".css");
              document.head.appendChild(linkUrlObj[i]);
            }  

    切换语言的时候记得将语言存入到本地储存,这里是因为只做中英文的适配,如果还有其他语言那么需要对应修改判断条件,最后就剩图片素材了,我的想法是根据图片的命名规范去做国际化方案,如下:

    const maths = [
        "list1",
        "list2",
        "list3",
    ]
    const LangaugeName = Storage.getItem("LANGUAGE_TYPE");
    const ticks = maths.map((item) => require("../../../images/home/silder/" + item + "_" + LangaugeName + ".jpg"))

     

    Storage就是localStorage,自己做了一层简单的封装。

    export default {
        setItem(key , value){
            localStorage.setItem(key , value)
        },
        getItem(key){
            return localStorage.getItem(key)
        }
    }

     

    这样我们在组件里面直接使用ticks数据对应的图片即可,文件名以 list_zh.png / list_en.png 命名区分,虽然还是很麻烦,但是做国际化又哪有不麻烦的......

    展开全文
  • 之前写了谈谈文字图片像素,主要是为了将文字和图片像素后的坐标提取出来,而本篇所讲即为像素后的粒子过程。先上一个简单的demo ->粒子demo,本篇的目的就是为了讲解怎样做这样的简单demo(大牛请无视)...

    之前写了谈谈文字图片像素化,主要是为了将文字和图片像素化后的坐标提取出来,而本篇所讲即为像素化后的粒子化过程。

    先上一个简单的demo -> 粒子化demo,本篇的目的就是为了讲解怎样做这样的简单demo(大牛请无视);同时会介绍一些优秀的demo供大家参考。

    主要思路

    首先我们谈谈粒子化的主要思路。

    像素化后(不知道怎样像素化,参考谈谈文字图片像素化),我们得到了所需图像或者文字的具体坐标,我们将它们形象地用一个个的粒子表示(这里用了圆形),得到的坐标即是粒子的最终位置。粒子的初始位置在哪里?粒子从初始位置到最终位置的运动又是如何?这些是我们可以自由发挥的。所以粒子化过程究其根本,就是怎样表示粒子的运动过程。

    基本准备

    canvas自适应电脑屏幕(不出现滚条):

    css部分:

    body {margin:0; padding:0; wdith:100%; height: 100%}

    canvas {display:block; background-color:#000}

    js部分:

    window.canvas = document.createElement('canvas');

    document.body.appendChild(window.canvas);

    canvas.height = window.height = window.innerHeight;

    canvas.width = window.width = window.innerWidth;

    关于像素化再补充几句:

    像素化过程简单描述就是将所需的文字fillText到画布上或者将图片drawImage到画布上(设置一个离屏的canvas),然后利用getImagedata这个api将像素点提取出来。值得注意的是getImagedata并不会获取背景点的像素,所以canvas的背景使用怎样的颜色并不会影响像素点的提取。

    一般像素点的提取是根据某个像素点rgba的a值进行判断,a值的取值是0~255(rgba当做颜色属性赋值时a的取值是0~1),通常做法是判断a值非0或者半透(>125)。这里我也做了个简单的测试,当color值取black或者#000时,a值如下:

               

    关于阴影

    粒子化效果一般在黑夜最漂亮,所以背景我一般设置成黑色。如果要更带感,需要一点阴影效果。

    其实很简单,调整一下透明度即可。比如这样:

    body {margin:0; padding:0; wdith:100%; height: 100%}

    canvas {display:block; background-color:#000}

    // window.onload = function() {

    window.canvas = document.createElement('canvas');

    document.body.appendChild(window.canvas);

    canvas.height = window.height = window.innerHeight;

    canvas.width = window.width = window.innerWidth;

    window.ctx = canvas.getContext('2d');

    // }

    var x = 0, y = 0;

    setInterval(function() {

    ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';

    ctx.fillRect(0, 0, width,height);

    x+=5; y+=5;

    ctx.beginPath();

    ctx.fillStyle = 'red'

    ctx.arc(x, y, 5, 0, Math.PI * 2);

    ctx.fill();

    }, 1000 / 60)

    当然用globalAlpha也是一样的。

    粒子具有的属性:

    将粒子放入运动场中,我们可以赋予它一些属性,比如速度,加速度,位移等等,而这些属性都可以用矢量来表示。

    粒子运动

    之前我说过,以上皆是铺垫,运动才是粒子化的关键。因为粒子最终要汇聚成一定的形状,所以运动的某一段的终点已知,那么粒子怎样能运动到对应的位置?

    我们从最简单的直线运动说起。

    直线运动:

    谈谈文字图片像素化中用的demo就是直线运动 -> 像素化

    如何用js描述一个直线运动?首先我们要明白在怎样的情况下物体会做直线运动?学过物理我们知道速度和加速度在一条直线时,物体做直线运动。

    那么很简单,已知粒子的终点,随机粒子的起点,速度方向就确定了(起点指向终点),如果有必要,还可以设置加速度。

    曲线运动:

    仅仅做直线运动或许视觉效果太差,曲线运动会不会产生更好的视觉效果?

    什么情况下物体会做曲线运动?速度和加速度不在一条直线时,比如抛物运动。

    先看这个demo:demoHome(W·Axes) 我们取它的第一个过程进行分析,实际上就是一个二维的曲线运动。和抛物运动的不同之处是,加速度方向指向粒子的终点,为的是能够准确达到终点位置。W.Axes的另一个粒子demo也大同小异:粒子化,相比于前一个demo只是改变了粒子的初始位置和初始速度,以及粒子运动顺序。

    我们尝试着来完成一个demo。

    前面说到,为了能使粒子能到达指定的位置,我们给了粒子一个指向指定位置的加速度,在粒子的每一帧运动中,可以将该加速度分解到x和y轴分别进行计算。比如这样:

    update: function() {

    var v = this.pos2.minusNew(this.now);

    var angle = v.getAngle();

    this.v.x = (this.v.x + this.a * Math.cos(angle) / 1000 * 60) * 0.96;

    this.v.y = (this.v.y + this.a * Math.sin(angle) / 1000 * 60) * 0.96;

    this.now.x += this.v.x;

    this.now.y += this.v.y;

    }

    a表示粒子的加速度值,/1000*60表示每帧的速度增加,*0.96模拟能量损失。这样的运动的话粒子通过曲线运动就能到达指定位置。

    模拟屏幕左上角到屏幕中心的曲线运动:

    粒子运动

    body {margin:0; padding:0; wdith:100%; height: 100%}

    canvas {display:block; background-color:#000}

    window.canvas = document.createElement('canvas');

    document.body.appendChild(window.canvas);

    canvas.height = window.height = window.innerHeight;

    canvas.width = window.width = window.innerWidth;

    window.ctx = canvas.getContext('2d');

    window.vpx = width / 2;

    window.vpy = height / 2;

    var ball = {

    pos2: new Vector2(width/2, height/2),

    now: new Vector2(0, 0),

    r: 5,

    color: getRandomColor(),

    v: new Vector2(10, 0),

    a: 10,

    draw: function() {

    ctx.clearRect(0, 0, width, height);

    ctx.beginPath();

    ctx.fillStyle = this.color;

    ctx.arc(this.now.x, this.now.y, this.r, 0, Math.PI * 2);

    ctx.fill();

    },

    update: function() {

    var v = this.pos2.minusNew(this.now);

    var angle = v.getAngle();

    this.v.x = (this.v.x + this.a * Math.cos(angle) / 1000 * 60) * 0.96;

    this.v.y = (this.v.y + this.a * Math.sin(angle) / 1000 * 60) * 0.96;

    this.now.x += this.v.x;

    this.now.y += this.v.y;

    }

    };

    setInterval(function() {

    ball.draw();

    ball.update();

    }, 1000 / 60);

    当然你也可以自己设置运动函数,不过我觉得这样比较方便而已。

    关于缓动:

    有时为了效果我们需要设计一个缓动,什么是缓动?就是速度越来越小的运动。

    或许涉及到x和y轴同时变化的运动太过复杂,我们假设一个物体沿着x轴正方向运动,并且物体运动速度越来越小,即为缓动。

    最简单的缓动如下:

    update: function() {

    var v = this.pos2.minusNew(this.now);

    v.scale(0.05);

    this.now.add(v);

    }

    稍微复杂点的缓动v-s图像可以设计成二次函数或者三角函数,因为某点的切线的斜率即为速度,而切线斜率越来越小即为速度越来越小。

    二维三维:

    三维和二维环境下的粒子化其实大同小异,不了解三维的话可以参考rotate 3d基础试着实现一个球体的3d旋转demo。

    关于创意

    其实粒子化本身并不难,难的是创意。这里稍微介绍几个有创意的demo。

    codepen上的一个demo,代码很长,其实实现思路也大同小异,就是变着花样的粒子的运动。

    同样只是粒子的运动,只是多了点创意,构造了动态文字效果。

    总结

    文字图片粒子化其实就是粒子系统的一部分,不妨可以从最简单的一个粒子系统开始,一步步实现一个简单的粒子化demo。

    觉得不尽兴,可以参考下面更多文章:

    展开全文
  • 谈谈文字图片粒子

    2015-02-27 13:29:00
    之前写了谈谈文字图片像素,主要是为了将文字和图片像素后的坐标提取出来,而本篇所讲即为像素后的粒子过程。  先上一个简单的demo ->粒子demo,本篇的目的就是为了讲解怎样做这样的简单demo(大牛请...

      之前写了谈谈文字图片像素化,主要是为了将文字和图片像素化后的坐标提取出来,而本篇所讲即为像素化后的粒子化过程。

      先上一个简单的demo -> 粒子化demo,本篇的目的就是为了讲解怎样做这样的简单demo(大牛请无视);同时会介绍一些优秀的demo供大家参考。

     

    主要思路

      首先我们谈谈粒子化的主要思路。

      像素化后(不知道怎样像素化,参考谈谈文字图片像素化),我们得到了所需图像或者文字的具体坐标,我们将它们形象地用一个个的粒子表示(这里用了圆形),得到的坐标即是粒子的最终位置。粒子的初始位置在哪里?粒子从初始位置到最终位置的运动又是如何?这些是我们可以自由发挥的。所以粒子化过程究其根本,就是怎样表示粒子的运动过程。

     

    基本准备

    • canvas自适应电脑屏幕(不出现滚条):

    css部分:

    body {margin:0; padding:0; wdith:100%; height: 100%}
    canvas {display:block; background-color:#000}
    

    js部分:

    window.canvas = document.createElement('canvas'); 
    document.body.appendChild(window.canvas); 
    canvas.height = window.height = window.innerHeight;
    canvas.width = window.width = window.innerWidth;

     

    • 关于像素化再补充几句:

      像素化过程简单描述就是将所需的文字fillText到画布上或者将图片drawImage到画布上(设置一个离屏的canvas),然后利用getImagedata这个api将像素点提取出来。值得注意的是getImagedata并不会获取背景点的像素,所以canvas的背景使用怎样的颜色并不会影响像素点的提取。

      一般像素点的提取是根据某个像素点rgba的a值进行判断,a值的取值是0~255(rgba当做颜色属性赋值时a的取值是0~1),通常做法是判断a值非0或者半透(>125)。这里我也做了个简单的测试,当color值取black或者#000时,a值如下:

               

     

    • 关于阴影

      粒子化效果一般在黑夜最漂亮,所以背景我一般设置成黑色。如果要更带感,需要一点阴影效果。

      其实很简单,调整一下透明度即可。比如这样:

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title> </title> <style type="text/css"> body {margin:0; padding:0; wdith:100%; height: 100%} canvas {display:block; background-color:#000} </style> </head> <body> <script src='http://sandbox.runjs.cn/js/sandbox/jquery/jquery-1.8.3.min.js'></script> <script src='http://hanzichi.github.io/game/Vector.js'></script> <script> // window.onload = function() { window.canvas = document.createElement('canvas'); document.body.appendChild(window.canvas); canvas.height = window.height = window.innerHeight; canvas.width = window.width = window.innerWidth; window.ctx = canvas.getContext('2d'); // } var x = 0, y = 0; setInterval(function() { ctx.fillStyle = 'rgba(0, 0, 0, 0.5)'; ctx.fillRect(0, 0, width,height); x+=5; y+=5; ctx.beginPath(); ctx.fillStyle = 'red' ctx.arc(x, y, 5, 0, Math.PI * 2); ctx.fill(); }, 1000 / 60) </script> </body> </html>
      当然用globalAlpha也是一样的。
     
    • 粒子具有的属性:
      将粒子放入运动场中,我们可以赋予它一些属性,比如速度,加速度,位移等等,而这些属性都可以用矢量来表示。
     

    粒子运动

      之前我说过,以上皆是铺垫,运动才是粒子化的关键。因为粒子最终要汇聚成一定的形状,所以运动的某一段的终点已知,那么粒子怎样能运动到对应的位置?

      我们从最简单的直线运动说起。

     

    • 直线运动:

      谈谈文字图片像素化中用的demo就是直线运动 -> 像素化

      如何用js描述一个直线运动?首先我们要明白在怎样的情况下物体会做直线运动?学过物理我们知道速度和加速度在一条直线时,物体做直线运动。

      那么很简单,已知粒子的终点,随机粒子的起点,速度方向就确定了(起点指向终点),如果有必要,还可以设置加速度。
     
    • 曲线运动:
      仅仅做直线运动或许视觉效果太差,曲线运动会不会产生更好的视觉效果?
      什么情况下物体会做曲线运动?速度和加速度不在一条直线时,比如抛物运动。
      先看这个demo:demoHome(W·Axes) 我们取它的第一个过程进行分析,实际上就是一个二维的曲线运动。和抛物运动的不同之处是,加速度方向指向粒子的终点,为的是能够准确达到终点位置。W.Axes的另一个粒子demo也大同小异:粒子化,相比于前一个demo只是改变了粒子的初始位置和初始速度,以及粒子运动顺序。
      我们尝试着来完成一个demo。
      前面说到,为了能使粒子能到达指定的位置,我们给了粒子一个指向指定位置的加速度,在粒子的每一帧运动中,可以将该加速度分解到x和y轴分别进行计算。比如这样:
    update: function() {
      var v = this.pos2.minusNew(this.now);
      var angle = v.getAngle();
      this.v.x = (this.v.x + this.a * Math.cos(angle) / 1000 * 60) * 0.96;
      this.v.y = (this.v.y + this.a * Math.sin(angle) / 1000 * 60) * 0.96;
      this.now.x += this.v.x;
      this.now.y += this.v.y;
    }
    

      a表示粒子的加速度值,/1000*60表示每帧的速度增加,*0.96模拟能量损失。这样的运动的话粒子通过曲线运动就能到达指定位置。

      模拟屏幕左上角到屏幕中心的曲线运动:

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title> 粒子运动 </title> <style type="text/css"> body {margin:0; padding:0; wdith:100%; height: 100%} canvas {display:block; background-color:#000} </style> </head> <body bgcolor='#000'> <script src='http://hanzichi.github.io/common/vector.js'></script> <script src='http://hanzichi.github.io/common/common.js'></script> <script> window.canvas = document.createElement('canvas'); document.body.appendChild(window.canvas); canvas.height = window.height = window.innerHeight; canvas.width = window.width = window.innerWidth; window.ctx = canvas.getContext('2d'); window.vpx = width / 2; window.vpy = height / 2; var ball = { pos2: new Vector2(width/2, height/2), now: new Vector2(0, 0), r: 5, color: getRandomColor(), v: new Vector2(10, 0), a: 10, draw: function() { ctx.clearRect(0, 0, width, height); ctx.beginPath(); ctx.fillStyle = this.color; ctx.arc(this.now.x, this.now.y, this.r, 0, Math.PI * 2); ctx.fill(); }, update: function() { var v = this.pos2.minusNew(this.now); var angle = v.getAngle(); this.v.x = (this.v.x + this.a * Math.cos(angle) / 1000 * 60) * 0.96; this.v.y = (this.v.y + this.a * Math.sin(angle) / 1000 * 60) * 0.96; this.now.x += this.v.x; this.now.y += this.v.y; } }; setInterval(function() { ball.draw(); ball.update(); }, 1000 / 60); </script> </body> </html>
      当然你也可以自己设置运动函数,不过我觉得这样比较方便而已。
     
      
    • 关于缓动:
      有时为了效果我们需要设计一个缓动,什么是缓动?就是速度越来越小的运动。
      或许涉及到x和y轴同时变化的运动太过复杂,我们假设一个物体沿着x轴正方向运动,并且物体运动速度越来越小,即为缓动。
      最简单的缓动如下:
    update: function() {
      var v = this.pos2.minusNew(this.now);
      v.scale(0.05);
      this.now.add(v);
    }
      稍微复杂点的缓动v-s图像可以设计成二次函数或者三角函数,因为某点的切线的斜率即为速度,而切线斜率越来越小即为速度越来越小。
      更多可以参考岑安的文章 -> 【前端应该知道的那些事儿】运动学基础
     
    • 二维三维:
      三维和二维环境下的粒子化其实大同小异,不了解三维的话可以参考rotate 3d基础试着实现一个球体的3d旋转demo。
     

    关于创意

      其实粒子化本身并不难,难的是创意。这里稍微介绍几个有创意的demo。

      codepen上的一个demo,代码很长,其实实现思路也大同小异,就是变着花样的粒子的运动。

     

      同样只是粒子的运动,只是多了点创意,构造了动态文字效果。

     

    总结

      文字图片粒子化其实就是粒子系统的一部分,不妨可以从最简单的一个粒子系统开始,一步步实现一个简单的粒子化demo。

      觉得不尽兴,可以参考下面更多文章:

      

      

    转载于:https://www.cnblogs.com/lessfish/p/4303125.html

    展开全文
  • 谈谈文字图片像素

    2015-01-26 19:48:00
    本篇主要谈谈如何将文字和图片的像素粒子。针对这个demo,也就是如何实现如下两个图片的转换。      无论文字还是图片,本篇所讲都是针对画布,这点要清楚。如果是文字,用fillText方法将文字写到画布上,...

      先来看个简单的demo-> 像素粒子化

      demo是基于3d旋转算法+像素粒子化实现的,尚有一些bug和性能问题,我们不做深究。本篇主要谈谈如何将文字和图片的像素粒子化。针对这个demo,也就是如何实现如下两个图片的转换。

           

      

      无论文字还是图片,本篇所讲都是针对画布,这点要清楚。如果是文字,用fillText方法将文字写到画布上,如果是图片,则用drawImage方法将图片画到画布上。然后通过getImageData方法获取像素,进行判断,从而取得想要的坐标。不了解getImageData的具体可参考:getImageData

      如何获取想要的像素点坐标?一般情况下我们可以根据像素点rgba中的a值(透明度)进行判断。

      法1:

    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');
    var img =  document.getElementById('img1');
    ctx.drawImage(img, 0, 0);
    var data = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
    var length = data.length;
    var textPoint = [];
    for (var i = 0, wl = canvas.width * 4; i < length; i += 4) {
      if (data[i + 3]) {  // 根据透明度判断
        var x = (i % wl) / 4;
        var y = parseInt(i / wl)
        textPoint.push([x, y]);
      }
    }
    

      法2:

    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');
    var img =  document.getElementById('img1');
    ctx.drawImage(img, 0, 0);
    var textPoint = [];
    var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    for(var i = 0; i < imgData.width; i++)
      for(var j = 0; j < imgData.height; j++) {
        var index = (i + j * imgData.width) * 4 + 3;
        if(imgData.data[index]) {
          textPoint.push([i, j]);
        }
      }  
    

      fillText:

    ctx.font = "bold 12px serif"
    ctx.textAlign = "left";
    ctx.textBaseline = "top";
    ctx.fillStyle = 'red';
    ctx.fillText('慧', 0, 0);
    

      

     

    1、文字像素粒子化

    • 小文字 * textSize 法

      这是一种比较常用的方法。首先在画布上用fillText写文字,但是写的文字像素要小,一般选择笔画宽2~3个像素,甚至一个像素点。然后通过getImageData获取的data值再进行判断计算获得坐标,其实就是获得文字所组成像素的相对位置。然后将获得的坐标乘以一个常数,就是粒子的大小(实际粒子大小可能会小于textSize以产生粒子间的间隙),这里把它称为textSize,乘以常数后得到一个新的坐标即为粒子化后粒子的坐标。这样在每帧渲染时只需操作新的坐标即可,得到的是相对来说扩大textSize倍的字。

      demo:06wj demo

      优点:可任意文字代码扩展性强

      缺点:字体选择少;效果不直观,需调整文字大小和textSize值调整效果

      总结:适用于粒子大的demo,一般文字宽度1~3个像素

     

    • 大文字 + 舍弃部分像素点法

      这种方法也比较常见。首先在画布上用fillText写好文字,但是文字一定要大,跟最终出现的效果文字差不多大小,然后也是通过getImageData操作像素点,但是这里要舍弃部分像素点,因为并发的粒子太多进程会卡掉。舍弃多少因情况而异,一般舍弃的数量和粒子的大小成正比,因为舍弃的粒子需要留下的粒子通过扩大来占位。

      怎么舍弃?方法参数根据需要的效果随意,例举一二:

         

      demo:W·Axes 粒子化Demo2     岑安 demo

      优点:可任意文字代码扩展性强;最终大小效果直观

      缺点:字体选择少;需要靠舍弃像素的多少调整粒子大小

      总结:适用于粒子小的demo

     

    • 其他

      直接用大文字,因为像素点太多太密,而且如果不舍弃的话粒子只能以0.5为半径,体验十分差,在粒子化中基本不考虑。倒是在别的方面可能有用处,花丛效果文字就用到了,因为每帧不用重绘,所以渲染也不会卡。

      直接用小文字那就根本不用考虑了。

     

    2、图片像素粒子化

      demo采用的就是图片像素粒子化。先把图片draw到画布上,接下去的操作就和文字一样了。这里提一点,在本地操作时,getImageData方法报错:

      提示跨域操作data,实际上就是跨域操作图片了。解决方法就是把代码和图片都放到服务器环境下(相同域名)。因为本地测试用的图片是文件夹内的,js跨域限制是不能获取非同一域名下的数据的, 而本地的位置是没有域名的,所以浏览器都认为你是跨域,导致报错。或者check  Javascript - getImageData after fillRect and drawImage

      图片操作的结果其实就和小文字*textSize类似(有人可能会说可以用大图片,剔除部分像素点,但是大图片体积大加载不易,并且剔除麻烦,我这里就不考虑了),不同的是图片能操作各种炫酷的文字,除了文字之外图片还能操作别的需要的形状。图片的像素点也有要求,像素点太多后续渲染压力会很大浏览器会崩溃,最好像素删减后控制在1000以内,一般图片20*20可取图上所有像素点;不考虑直接用大图片,浏览器会崩溃,所以只能小图片 * size。

      demo:岑安 JX官网首页3D粒子效果

      优点:不仅限于文字,适用范围广; 文字字体选择多样,效果好看

      缺点:获取图片不方便;可扩展性不强每个demo要重新获取图片

     

    3、其他

      粒子化除了文字和图片外,还有很多,比如数组模拟,这里就不加介绍了,具体请check:事情没有想象中那么难--JX官网首页3D粒子效果 

    转载于:https://www.cnblogs.com/lessfish/p/4251174.html

    展开全文
  • 关于图片字体

    2015-03-12 16:14:35
    最近项目中开始使用图片字体,这对于简单又小的图片来说,可以节约很多空间,以及不需要去记住那么多图片的名字,只需要留一张图片与字体的映射图就可以。 转载地址:...
  • python 读取、保存、二值、灰度化图片+opencv处理图片的方法 进行手写数字的图片预测的时候碰到了这样的问题。 先说说处理图片有三种方式 一、matplotlib 二、PIL 三、opencv 一、matplotlib 1、显示图片 import ...
  • 答:就是自己的应用程序在不同的国家或者地区打开的时候会出现相应的图片或者文字,这样就叫“国际”。 二、 实际上自己目前涉及到的国际的呢容就两种:“文字”、“图片” 三、 比方说为了创建“文字的...
  • matlab有关数字信道系统的数字AGC研究-图片7.pdf AGC,它的作用是当信号源较强时,使其增益自动降低;当信号较弱时,又使其增益自动增高,从而保证了强弱信号的均匀性,对输入的信号进行一个稳定的增益的控制。 包括...
  • matlab有关数字信道系统的数字AGC研究-图片1.pdf AGC,它的作用是当信号源较强时,使其增益自动降低;当信号较弱时,又使其增益自动增高,从而保证了强弱信号的均匀性,对输入的信号进行一个稳定的增益的控制。 包括...
  • Android中实现文字、图片资源国际案例!
  • 这是一张01数字虚拟抽象科技PPT背景图片,第一PPT模板网提供PowerPoint背景图片免费下载; 关键词:数字背景图片,蓝色幻灯片背景图片,科技PowerPoint背景图片,.PPTX格式;
  • 参数齿轮带公式图片+PROE字体,m代表模数,z代表齿数,b代表齿宽,d代表分度圆直径,db代表基圆直径,da代表齿顶圆直径,df代表齿根圆直径,s代表齿厚
  • 隐藏字体来达到语义,但是今天出现了问题,我在一个标签上图片代替文字,做一个抽奖按钮, 按钮转动的时候,页面出现了滚动条,页面的宽度和高度都变大很多,找来找去才发现是text-indent的问题 偏移掉字体...
  • 今天小编就为大家分享一篇Python之文字转图片方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧Pygame模块一览表:Pygame模块一览表引入pygame模块 ,若本机没有请自行pip install pygame#载...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,079
精华内容 2,831
关键字:

化字图片