如何在Canvas中制作这样的翻页效果呢?

发布于 2024-10-05 02:29:13 字数 2602 浏览 4 评论 0原文

google 出版了一本电子书:http://www.20thingsilearned.com/

阅读体验是这样的乐趣。

我注意到他们使用画布在阅读区域上产生翻页效果。

从技术上讲,您可以绘制自定义形状,填充渐变,装饰阴影。

但形状必须用两条贝泽曲线(用于顶部和底部边缘)和两条直线绘制。

问题是如何动态绘制这两条贝泽曲线。我花了一整天的时间来画这两条曲线。这是一些代码。

有谁知道如何在谷歌的电子书上产生同样的效果。 或者我基本上跑错了方向?

/**
 * PageFlip effects using HTML Canvas
 * @author RobinQu
 * @version 0.1
 */

/*global x$ */
var elf = {};
elf.fx = {};
elf.fx.pageflip = {
    /**
     * initialize the pageflip
     * @param {String} cId The id of canvas element
     */
    init: function(cId, width, height) {
        var canvas,
        ctx;
        this.$ = x$("#" + cId);
        canvas = this.canvas = this.$[0];

        this.width = canvas.width = width;
        this.height = canvas.height = height;
        this.margin = 60;
        this.context = canvas.getContext("2d");



        //this.bind();
    },
    bind: function() {
        this.$.on("mouseover", this.beginRoll.bind(this));
        this.$.on("mousemove", this.doRoll.bind(this));
        this.$.on("mouseout", this.endRoll.bind(this));
    },
    _over: false,
    beginRoll: function() {
        this._over = true;
    },
    _clear: function() {
        var ctx = this.context;
        ctx.clearRect(0, 0, this.width, this.height);
        var w = this.width;
        this.canvas.width = 1;
        this.canvas.width = w;
    },
    doRoll: function(e) {
        //offset, plus scroll; client, no scroll
        if (this._over) {
            //console.log(e.offsetX, e.offsetY, e.clientX, e.clientY);
            var x = e.offsetX,
            y = e.offsetY,
            ctx = this.context,
            startx = x,
            starty = x / this.width * this.margin,
            endx = (this.width - x)/2 + x,
            endy = this.margin + 8,
            cp1x = x + 10,
            cp1y = Math.min(this.margin * Math.sin(x * Math.PI  / this.width), 5),
            cp2x = endx - 10,
            cp2y = Math.min(this.margin  * Math.cos(x * Math.PI  / this.width), 5);

            console.log(this.margin * Math.sin(x * Math.PI  / this.width));

            //enxy = this.margin * Math.sin(x * Math.PI * 2 / this.width),
            //cp2x = ;
            console.log(this.width, this.height);
            this._clear();
            ctx.beginPath();
            ctx.moveTo(startx, starty);
            ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, endx, endy);
            ctx.strokeStyle = "#000";
            ctx.stroke();
        }

    },
    endRoll: function() {
        this._over = false;
    }
};

google has published an e-book : http://www.20thingsilearned.com/

the reading experience is kind of fun.

I notice they used canvas to produce the page flip effects over reading areas.

Technically, you can draw a customized shape, filled with gradient, decorated with shadow.

but the shape has to be drawn with two beizer curves (for top and bottom edges) and two straight lines.

The problem is how to dynamically draw those two beizer curves. I spent a whole day to draw these two curves. here is some code of.

Does anyone knows how to produce the same effects on Google's ebook.
or i basically ran into wrong direction?

/**
 * PageFlip effects using HTML Canvas
 * @author RobinQu
 * @version 0.1
 */

/*global x$ */
var elf = {};
elf.fx = {};
elf.fx.pageflip = {
    /**
     * initialize the pageflip
     * @param {String} cId The id of canvas element
     */
    init: function(cId, width, height) {
        var canvas,
        ctx;
        this.$ = x$("#" + cId);
        canvas = this.canvas = this.$[0];

        this.width = canvas.width = width;
        this.height = canvas.height = height;
        this.margin = 60;
        this.context = canvas.getContext("2d");



        //this.bind();
    },
    bind: function() {
        this.$.on("mouseover", this.beginRoll.bind(this));
        this.$.on("mousemove", this.doRoll.bind(this));
        this.$.on("mouseout", this.endRoll.bind(this));
    },
    _over: false,
    beginRoll: function() {
        this._over = true;
    },
    _clear: function() {
        var ctx = this.context;
        ctx.clearRect(0, 0, this.width, this.height);
        var w = this.width;
        this.canvas.width = 1;
        this.canvas.width = w;
    },
    doRoll: function(e) {
        //offset, plus scroll; client, no scroll
        if (this._over) {
            //console.log(e.offsetX, e.offsetY, e.clientX, e.clientY);
            var x = e.offsetX,
            y = e.offsetY,
            ctx = this.context,
            startx = x,
            starty = x / this.width * this.margin,
            endx = (this.width - x)/2 + x,
            endy = this.margin + 8,
            cp1x = x + 10,
            cp1y = Math.min(this.margin * Math.sin(x * Math.PI  / this.width), 5),
            cp2x = endx - 10,
            cp2y = Math.min(this.margin  * Math.cos(x * Math.PI  / this.width), 5);

            console.log(this.margin * Math.sin(x * Math.PI  / this.width));

            //enxy = this.margin * Math.sin(x * Math.PI * 2 / this.width),
            //cp2x = ;
            console.log(this.width, this.height);
            this._clear();
            ctx.beginPath();
            ctx.moveTo(startx, starty);
            ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, endx, endy);
            ctx.strokeStyle = "#000";
            ctx.stroke();
        }

    },
    endRoll: function() {
        this._over = false;
    }
};

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文