4.html5 笔记2 canvas

HTML5 Canvas;
echarts;

image.png

CodePen
image.png

image.png

image.png

image.png

可以对同一个形状进行多次描绘.

// 画布
      var myCanvas = document.getElementById("myCanvas");
      // 创建画笔, 上下文
      var ctx = myCanvas.getContext("2d");
      
      
      // 一条路径 
        // 落笔
        ctx.moveTo(100,100);
        // 画直线
        ctx.lineTo(100,200);
        // 线宽
        ctx.lineWidth = 20;// 对已经画了的 线条进行装饰
        // 线颜色
        ctx.strokeStyle = 'red';//// 对已经画了的 线条进行装饰
        //描边
        ctx.stroke();
        ctx.lineTo(200,200);// 可以一直接着画直线
        ctx.lineTo(200,300);// 可以一直接着画直线
        // 线宽 // 线颜色 // 描边.
        ctx.lineWidth = 10;
        ctx.strokeStyle = "blueviolet";
        ctx.stroke();
        // 记住此时,我们不只是对新的线条进行了修饰,还对最上面的边也进行了修饰.
        ctx.lineWidth = 3;
        ctx.strokeStyle = "#009E86";
        ctx.stroke();
        // 也就是,我们可以对已经画了的线条,形状, 可以进行多次修饰.
        // 即使另起一行, 也是会进行对此修饰.
image.png

如何换一层? beginpath();

...
        ctx.beginPath();
        ctx.moveTo(300,100);
        ctx.lineTo(300,0);
        ctx.lineWidth = 15;
        ctx.strokeStyle = "#00458A";
        ctx.stroke();
        // 此时不会对beginPath() 前面的形状产生影响, 就好像另起一层

image.png

closePath() 闭合线路,回到movoTo 落笔处.

        ctx.moveTo(100,100);
        // 画直线
        ctx.lineTo(100,200);
        // 线宽
        ctx.lineWidth = 20;// 对已经画了的 线条进行装饰
        // 线颜色
        ctx.strokeStyle = 'red';//// 对已经画了的 线条进行装饰
        //描边
        ctx.stroke();
        ctx.lineTo(200,200);// 可以一直接着画直线
        ctx.lineTo(200,300);// 可以一直接着画直线
        // 线宽 // 线颜色 // 描边.
        ctx.lineWidth = 10;
        ctx.strokeStyle = "blueviolet";
        ctx.stroke();
        // 记住此时,我们不只是对新的线条进行了修饰,还对最上面的边也进行了修饰.
        ctx.lineWidth = 3;
        ctx.strokeStyle = "#009E86";
        ctx.closePath();
        ctx.stroke();
image.png

image.png

image.png

同样效果

        ctx.rect(0,0,100,100);
        ctx.strokeStyle = "#f00";
        ctx.stroke();
        ctx.strokeStyle = "#000000";
        ctx.strokeRect(0,0,100,100);

同样效果

        ctx.rect(0,0,100,100);
        ctx.fillStyle = "red";
        ctx.fill();
        ctx.fillStyle = "red";
        ctx.fillRect(0,0,100,100);

所以能看出来,只是为了让你更方便, 没必要觉得更复杂.

唯一的橡皮擦


image.png

矩形落地小demo

 ctx.fillRect(100,100,100,100);
        var y = 100;
        var timer = setInterval(function () {
          ctx.clearRect(0,0,500,500);
            ctx.fillRect(100,y,100,100);
            if (y >= 400) {
                clearInterval(timer);
            }
            y += 10;
        },50);

image.png

image.png

javascript三角函数的使用

html5 作业 canvas 雪花飘落

image.png

image.png

        ctx.arc(250,250,50,0,2*Math.PI,0);
        ctx.strokeStyle = "white"
        ctx.lineWidth = 5;
        ctx.stroke();
image.png
        ctx.moveTo(250,250);
        ctx.arc(250,250,50,0,-Math.PI/4,1);
        ctx.strokeStyle = "white"
        ctx.lineWidth = 5;
        ctx.closePath();
        ctx.stroke();
image.png
        
        ctx.moveTo(250,250);
        ctx.arc(250,250,50,0,-Math.PI/4,0);
        ctx.strokeStyle = "white"
        ctx.lineWidth = 5;
        ctx.closePath();
        ctx.stroke();
image.png

image.png
        ctx.moveTo(100,100);
        ctx.arcTo(100,200,200,200,10);
        ctx.stroke();
image.png

注意,
画弧结束后的笔不是,弧度的第二个坐标, 而是半径和第二条线的切线处.

        ctx.moveTo(100,100);
        ctx.arcTo(100,200,200,200,10);
        ctx.closePath();
        ctx.stroke();
image.png

画一个有圆角的矩形.

        ctx.moveTo(100,110);
        ctx.arcTo(100,200,200,200,10);
        ctx.arcTo(200,200,200,100,10);
        ctx.arcTo(200,100,100,100,10);
        ctx.arcTo(100,100,100,200,10);
        
        ctx.stroke();
image.png

如何画曲线?


image.png

具体数学上怎么实现的暂时不用理会,不用理解.
我们只需要知道, 可以设置控制点的方式,绘制曲线.
先确定起点,和终点,起始点不是由 quadraticCurveTo 来决定,
而是看上一次落笔在哪里.
然后调整中间点,就可以控制曲线了

        ctx.moveTo(100,100);
        ctx.quadraticCurveTo(200,200,300,100);
        ctx.stroke();
image.png
        ctx.quadraticCurveTo(200,400,300,100);
image.png

三次也类似.

image.png
        ctx.moveTo(100,100);
        ctx.lineTo(100,200);
        ctx.lineTo(200,200);
        ctx.lineWidth = 10;
        ctx.stroke();
        
        ctx.translate(200,200);
        ctx.lineWidth = 5;
        ctx.strokeStyle = "red";
        // 必须重新落笔, 上一个坐标系中的 终点,不是这个坐标系中的默认起点.
        ctx.moveTo(0,0)
        ctx.lineTo(100,100);
        ctx.stroke();
        // 可以看到 坐标系的变换, 并不能替代 beginpath的作用
        // 后面的样式,依然会影响前面的线条.
image.png
        ctx.moveTo(100,100);
        ctx.lineTo(100,200);
        ctx.lineTo(200,200);
        ctx.lineWidth = 10;
        ctx.stroke();
        
        ctx.translate(200,200);
        ctx.lineWidth = 5;
        ctx.strokeStyle = "red";
        ctx.moveTo(0,0)
        ctx.lineTo(100,100);
        ctx.lineTo(100,200);
        ctx.closePath();
        // closePath 只会影响这个坐标系的线条,不会影响上一个坐标系
        ctx.stroke();
        
image.png
        ctx.moveTo(100,100);
        ctx.lineTo(100,200);
        ctx.lineTo(200,200);
        ctx.lineWidth = 10;
        ctx.stroke();
        
        ctx.translate(200,200);
        ctx.scale(0.5,0.5);
        // scale 和 translate 一样也是对坐标系的伸缩
        // 注意 scale 和 translate 顺序是对效果有影响的.
        ctx.lineWidth = 5;
        ctx.strokeStyle = "red";
        ctx.moveTo(0,0)
        ctx.lineTo(100,100);
        ctx.lineTo(100,200);
        ctx.closePath();
        ctx.stroke();
image.png

调换scale,translate 顺序

        ctx.moveTo(100,100);
        ctx.lineTo(100,200);
        ctx.lineTo(200,200);
        ctx.lineWidth = 10;
        ctx.stroke();
        
        ctx.scale(0.5,0.5);
        // 注意 scale,translate,rotate 的顺序 对坐标系是有影响的.
        ctx.translate(200,200);
        ctx.lineWidth = 5;
        ctx.strokeStyle = "red";
        ctx.moveTo(0,0)
        ctx.lineTo(100,100);
        ctx.lineTo(100,200);
        ctx.closePath();
        ctx.stroke();
        
image.png

rotate(Math.PI) 也是对坐标系的操作

        ctx.moveTo(100,100);
        ctx.lineTo(100,200);
        ctx.lineTo(200,200);
        ctx.lineWidth = 10;
        ctx.stroke();
        
        ctx.translate(200,200);
        ctx.scale(0.5,0.5);
        ctx.rotate(Math.PI/4);
        // 与css3不同, css3可以通过transform-origin 来调整旋转轴坐标,默认为center
        // 而这里的默认转轴为 坐标系原点,想要进行精确旋转,
        // 就要在设置图形的时候, 设定好与 远点的关系.
        ctx.lineWidth = 5;
        ctx.strokeStyle = "red";
        ctx.moveTo(0,0)
        ctx.lineTo(100,100);
        ctx.lineTo(100,200);
        ctx.closePath();
        ctx.stroke();

ctx.save()

首先 ctx.save() 不能代替 beginpath()
换言之, 不管你设置几个ctx.save() 只要没设置 ctx.beginpath()
那么后面的样式会依旧影响前面所有坐标系的样式.

        ctx.moveTo(100,100);
        ctx.lineTo(100,200);
        ctx.lineTo(200,200);
        ctx.lineWidth = 10;
        ctx.stroke();
        
        ctx.translate(200,200);
        ctx.scale(0.5,0.5);
        ctx.rotate(Math.PI/4);
        ctx.lineWidth = 5;
        ctx.strokeStyle = "red";
        ctx.moveTo(0,0)
        ctx.lineTo(100,100);
        ctx.lineTo(100,200);
        ctx.closePath();
        ctx.stroke();
        ctx.save();
        
        ctx.lineWidth = 2;
        ctx.strokeStyle = "yellow";
        ctx.stroke();
image.png

ctx.save() 可以理解为 坐标系的 时间戳, 或者画布层?
用ctx.restore() 配合进行在不同坐标系之间的切换.
(而beginpath() 则没有相应的切换到前面状态的方式.)

注意 save 和 restore

        ctx.moveTo(100,100);
        ctx.lineTo(100,200);
        ctx.lineTo(200,200);
        ctx.lineWidth = 10;
        ctx.stroke();
        ctx.save();//第一状态坐标系
        
        ctx.translate(200,200);
        ctx.save();// 第二状态坐标系
        
        ctx.scale(0.5,0.5);
        ctx.save();// 第三状态坐标系
        
        ctx.rotate(Math.PI/4);
        ctx.lineWidth = 5;
        ctx.strokeStyle = "red";
        ctx.moveTo(0,0)
        ctx.lineTo(100,100);
        ctx.lineTo(100,200);
        ctx.closePath();
        ctx.stroke();
        
        ctx.restore();// 回到第三状态坐标系, 也就是现在
        ctx.beginPath();
        ctx.moveTo(0,0);
        ctx.lineTo(100,300);
        ctx.lineWidth = 5;
        ctx.strokeStyle = 'blue';
        ctx.stroke();
image.png

再来一次

...
        ctx.restore();// 回到第三状态坐标系, 也就是现在
        ctx.beginPath();
        ctx.moveTo(0,0);
        ctx.lineTo(100,300);
        ctx.lineWidth = 5;
        ctx.strokeStyle = 'blue';
        ctx.stroke();
        
        
        ctx.restore();// 回到第二状态坐标系,
        ctx.beginPath();
        ctx.moveTo(0,0);
        ctx.lineTo(100,300);
        ctx.lineWidth = 5;
        ctx.strokeStyle = 'blue';
        ctx.stroke();
        
image.png

再来一次

...
        ctx.restore();// 回到第三状态坐标系, 也就是现在
        ctx.beginPath();
        ctx.moveTo(0,0);
        ctx.lineTo(100,300);
        ctx.lineWidth = 5;
        ctx.strokeStyle = 'blue';
        ctx.stroke();
        
        
        ctx.restore();// 回到第二状态坐标系,
        ctx.beginPath();
        ctx.moveTo(0,0);
        ctx.lineTo(100,300);
        ctx.lineWidth = 5;
        ctx.strokeStyle = 'blue';
        ctx.stroke();
        
        
        
        ctx.restore();// 回到第一状态坐标系,
        ctx.beginPath();
        ctx.moveTo(0,0);
        ctx.lineTo(100,300);
        ctx.lineWidth = 5;
        ctx.strokeStyle = 'blue';
        ctx.stroke();
        
image.png

每次restore() 都会寻找上一个save() 对应的 坐标系.
restore 的方向只能是往后切换, 无法往前切换.

image.png
        var img = new Image();
        img.src = "img/2test.jpg";
        img.onload = function () {
          console.log(123);
          var bg = ctx.createPattern(img,"no-repeat");
          ctx.strokeStyle = bg;
          ctx.moveTo(0,0);
          ctx.lineTo(0,400);
          ctx.lineWidth = 800;
          ctx.stroke();
        }
image.png

var bg = ctx.createPattern(img,"no-repeat");
创建的是一个"颜色",可以用于fillstyle,strokestyle,两个参数一个都不能少.

        var myCanvas = document.getElementById("myCanvas");
        var myCanvas2 = document.getElementById("myCanvas2");
        var ctx = myCanvas.getContext("2d");
        var ctx2 = myCanvas2.getContext("2d");
        
          // 用于充当 "颜色的" canvas
          ctx2.moveTo(50,50);
          ctx2.arc(50,50,40,0,1.8 * Math.PI,0);
          ctx2.lineWidth = 5;
          ctx2.fillStyle = "deeppink";
          ctx2.strokeStyle = "purple";
          ctx2.stroke();
          ctx2.fill();
          
          // 把颜色 拿过来.
          var bg = ctx.createPattern(myCanvas2,"repeat");
          ctx.fillStyle = bg;
          ctx.fillRect(0,0,500,500);
          
image.png
image.png

跟createPattern 一样, 最后也是成为一个颜色.

        var myCanvas = document.getElementById("myCanvas");
        var ctx = myCanvas.getContext("2d");
        
        var bg = ctx.createLinearGradient(100,100,100,300);
        // 中间 可以有多个渐变 颜色
        bg.addColorStop(0,"black");
        bg.addColorStop(0.5,"pink");
        bg.addColorStop(1,"purple");
//        ctx.fillStyle = bg;
//        ctx.fillRect(0,0,500,500);
          
          ctx.strokeStyle = bg;
          ctx.lineWidth = 500;
          ctx.moveTo(0,0);
          ctx.lineTo(0,500);
          ctx.stroke();
          
image.png
        var myCanvas = document.getElementById("myCanvas");
        var ctx = myCanvas.getContext("2d");
        
        var bg = ctx.createRadialGradient(250,250,50,250,250,200);
        // 中间 可以有多个渐变 颜色
        bg.addColorStop(0,"black");
        bg.addColorStop(0.5,"pink");
        bg.addColorStop(1,"purple");
//        ctx.fillStyle = bg;
//        ctx.fillRect(0,0,500,500);
          
          ctx.strokeStyle = bg;
          ctx.lineWidth = 500;
          ctx.moveTo(0,0);
          ctx.lineTo(0,500);
          ctx.stroke();
image.png
image.png
        var bg = ctx.createRadialGradient(250,250,100,250,250,150);
        // 中间 可以有多个渐变 颜色
        bg.addColorStop(0,"white");
        bg.addColorStop(0.5,"black");
        bg.addColorStop(1,"white");
          ctx.fillStyle = bg;
          ctx.fillRect(0,0,500,500);
image.png
        var bg = ctx.createLinearGradient(0,0,0,100);
        // 中间 可以有多个渐变 颜色
        bg.addColorStop(0,"black");
        bg.addColorStop(1,"white");
          ctx.fillStyle = bg;
          ctx.fillRect(0,0,500,500);
image.png
image.png
        ctx.shadowColor = "red";
        ctx.shadowBlur = 10;
        ctx.shadowOffsetX = 20;
        ctx.shadowOffsetY = 20;
        ctx.fillRect(100,100,100,100);
        
        
        ctx.beginPath();// 结束落笔
        ctx.translate(10,10);// 更换坐标系
        ctx.arc(400,400,50,0,2 * Math.PI,1);
        ctx.stroke();
image.png

发现,beginPath(), translate 都无法影响,
换言之, 所有 生成的图形都会生成 阴影.
除非,

        ctx.shadowColor = "red";
        ctx.shadowBlur = 10;
        ctx.shadowOffsetX = 20;
        ctx.shadowOffsetY = 20;
        ctx.fillRect(100,100,100,100);
        
        ctx.shadowBlur = 0;
        ctx.shadowOffsetX = 0;
        ctx.shadowOffsetY = 0;        
        ctx.arc(400,400,50,0,2 * Math.PI,1);
        ctx.stroke();
image.png

问题: 如果我希望为一个元素, 增加多个阴影怎么办?
找到一个不是很好的方法

        ctx.shadowColor = "red";
        ctx.shadowBlur = 10;
        ctx.shadowOffsetX = 20;
        ctx.shadowOffsetY = 20;
        ctx.fillRect(100,100,100,100);

        再画一次.
        ctx.shadowColor = "red";
        ctx.shadowBlur = 10;
        ctx.shadowOffsetX = -20;
        ctx.shadowOffsetY = -20;
        ctx.fillRect(100,100,100,100);
image.png
image.png

文字居中

                ctx.textAlign = "center";
                ctx.verticalAlign = "middle";
image.png

image.png
image.png
        ctx.beginPath();
        ctx.arc(250,250,100,0, 2 * Math.PI,1);
        ctx.stroke();
        ctx.closePath();
        ctx.clip();
        
        ctx.fillStyle = "red";
        ctx.fillRect(200,200,300,300);
image.png

问题 : 怎么才能摆脱clip() 效果? 用 save() + restore()

        ctx.beginPath();
        ctx.arc(250,250,100,0, 2 * Math.PI,1);
        ctx.stroke();
        ctx.closePath();
        ctx.save();
        ctx.clip();
        
        ctx.fillStyle = "red";
        ctx.fillRect(200,200,300,300);
        
        ctx.restore();
        ctx.fillStyle = "blue";
        ctx.fillRect(100,100,100,100);
image.png

问题 必须加上 closepath, 完成封闭区间嘛? 不必,

        ctx.beginPath();
        ctx.arc(250,250,100,0, Math.PI,1);
        ctx.lineTo(250,300);
        ctx.stroke();
        ctx.save();
        ctx.clip();
        
        ctx.fillStyle = "red";
        ctx.fillRect(200,200,300,300);
        
        ctx.restore();
        ctx.fillStyle = "blue";
        ctx.fillRect(100,100,100,100);
image.png

image.png

image.png

解决 新旧像素(形状重合,重叠时的情况)


image.png

image.png

只会影响, 该语句后面的所有像素.

        
        ctx.beginPath();
        ctx.arc(250,250,100,0, 2*Math.PI,1);
        ctx.fillStyle = "red";
        ctx.globalAlpha = '0.5';
        ctx.fill();
        ctx.fillStyle = "blue";
        ctx.fillRect(250,250,150,150);
image.png
        ctx.beginPath();
        ctx.arc(250,250,100,0, 2*Math.PI,1);
        ctx.fillStyle = "red";
        ctx.fill();
        ctx.globalAlpha = '0.5';
        ctx.fillStyle = "blue";
        ctx.fillRect(250,250,150,150);
image.png

image.png

三个参数时,图片会按自身大小显示.

        var img = new Image();
        img.src = "img/2test.jpg";
        img.onload = function () {
            ctx.drawImage(img,0,0);
        }
image.png

五个参数时,限制范围, 图片会按比例缩小(或放大?).

            ctx.drawImage(img,0,0,250,250);
image.png

九个参数时, 前四个数字,是截取图片, 后四个参数是 决定位置和大小.

            ctx.drawImage(img,100,100,300,300,0,0,250,250);
image.png

image.png
        var myCanvas = document.getElementById("myCanvas");
        var ctx = myCanvas.getContext("2d");
        
        var img = new Image();
        img.src = "img/2test.jpg";
        img.onload = function () {
          ctx.fillRect(0,0,500,500);
            ctx.drawImage(img,100,100,300,300,150,150,250,250);
            
            var canvasUrl = myCanvas.toDataURL();
            
            var oImg = new Image();
            oImg.src = canvasUrl;
            oImg.onload = function () {
                document.body.appendChild(oImg);
            }
        }
image.png

问题 toDataUrl() 方法 , img有没有该方法?
只有canvas 才有.


image.png

图片高斯模糊处理的方法.
获取一张图片
利用ctx.dragImage() 方式放进一个画布里.
利用ctx.getImageData(x,y,dx,dy) 得到像素对象.
对像素对象中的数据进行处理,
利用ctx.putImageData(imgData,x,y),重新放进画布
可以利用 canvas.toDataUrl 转换成图片.

          ctx.fillRect(0,0,500,500);
            ctx.drawImage(img,100,100,300,300,150,150,250,250);
            console.log(ctx.getImageData(0,0,500,500));
image.png

image.png

image.png
        var myCanvas = document.getElementById("myCanvas");
        var ctx = myCanvas.getContext("2d");
        
        ctx.fillRect(0,0,500,500);
        
        function changeGray () {
          var imageData = ctx.getImageData(0,0,500,500);
          imageData.data.forEach(function (item,index,self) {
            if (((index+1)%4) != 0) {
                self[index] = 100;
            }
          });
          ctx.putImageData(imageData,0,0);
            
        }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,752评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,100评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,244评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,099评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,210评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,307评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,346评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,133评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,546评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,849评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,019评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,702评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,331评论 3 319
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,030评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,260评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,871评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,898评论 2 351

推荐阅读更多精彩内容