9 生活离不开规则(课件)-2025-2026学年统编版(五四制)道德与法治三年级下册

| 18页
| 78人阅读
| 1人下载
普通

内容正文:

第1课时 生活处处有规则 生活离不开规则 部编版小学道德与法治三年级下册第9课 同学们好,我是月月! 游戏盲盒 规则 “规则”,就是规定出来供大家共同遵守的制度或章程。 1.游戏双方必须同时出手。 2.一旦出手,不能改变手势。 3.按照提前约定的局数定胜负。 游戏规则: 小讨论 你们经常玩哪些游戏?说说其中要遵守的规则。 游戏名称 游戏规则 离开“规则”的游戏会不会更好玩?你遇到过不遵守规则的情况或是不遵守游戏规则的小伙伴吗?当时你的感受怎样? “抢板凳” “跳绳” 还有哪里有规则? 规则大调查 我们小组调查的是 我们找到的规则: 衣( ) 食( ) 住( ) 行( ) 其他( ) 1. 2. 3. 4. 5. 小组活动: 1.小组内交流课前寻找到的公共生活规则; 2.小组内选取一位代表上台分享; 3.音乐停,交流停。 我不想遵守这些规则,好想去没有规则的世界! 如果驾驶汽车时没有规则,_______________。 如果乘坐交通工具时没有规则,_______________。 如果上下楼梯时没有规则,___________。 请同学们以小组为单位,选择一个场景,体会一下“自由”的生活是什么样的 “规则小能手”学习单 序号 规则 作用 1 搭乘电梯要先出后进 防止造成混乱,想出的人出不来,想进的人进不去。 2     3     4     5     ......     生活需要规则,请你举例说一说规则对生活的影响。 某市一所小学的学生玲玲,下楼去操场做广播体操,玲玲按照老师的要求,靠右下楼梯,但此时她被一名靠左上楼的同学撞倒,玲玲不禁感叹:“为什么守规则反而倒霉”。 你有没有过类似的经历,有没有产生过这样的想法? 为什么会发生这样的事情? 规则看似在约束我们,实则在保护我们 规则让我们的生活有序、安全又美好。 我知道生活需要规则,有时候不是我想破坏规则,而是没有办法...... 过马路时,一辆车都没有,我选择…… 下面的情况,该如何遵守规则? 很多人都在插队购票,我在后面等了很久,要不我也…… 花儿真漂亮,前面的人摘了一朵没人管,我也想…… 过马路时,一辆车都没有,我选择…… 课后请大家观察生活中出现的破坏规则的事,采访了解一下他们是出于什么原因破坏规则,想一想有没有解决办法。 课后作业 interact_pk_1.0.0.1040/assets/audio/btnClick.mp3 null 261.2245 interact_pk_1.0.0.1040/assets/audio/excellent.mp3 1044.8976 interact_pk_1.0.0.1040/assets/audio/gameBgm.mp3 null 21524.873 interact_pk_1.0.0.1040/assets/audio/gameEnd.mp3 null 2014-09-24 5198.3794 interact_pk_1.0.0.1040/assets/audio/good.mp3 679.1835 interact_pk_1.0.0.1040/assets/audio/great.mp3 679.1835 interact_pk_1.0.0.1040/assets/audio/prepare.mp3 2020 Blues 4388.58 interact_pk_1.0.0.1040/assets/audio/right.mp3 809.79565 interact_pk_1.0.0.1040/assets/audio/unbelievable.mp3 1410.6117 interact_pk_1.0.0.1040/assets/audio/wrong.mp3 »éÀñÒôЧ »éÀñÒôÀÖ´óÈ« www.igooood.com Other 835.9184 chi - www.igooood.com ��� - www.igooood.com interact_pk_1.0.0.1040/assets/img/1.png interact_pk_1.0.0.1040/assets/img/2.png interact_pk_1.0.0.1040/assets/img/3.png interact_pk_1.0.0.1040/assets/img/answerBtn.png interact_pk_1.0.0.1040/assets/img/answerReport_bg.png interact_pk_1.0.0.1040/assets/img/centerBg.png interact_pk_1.0.0.1040/assets/img/circleBtn.png interact_pk_1.0.0.1040/assets/img/continueBtn.png interact_pk_1.0.0.1040/assets/img/element/element1_1.png interact_pk_1.0.0.1040/assets/img/element/element1_2.png interact_pk_1.0.0.1040/assets/img/element/element2_1.png interact_pk_1.0.0.1040/assets/img/element/element2_2.png interact_pk_1.0.0.1040/assets/img/element/element3_1.png interact_pk_1.0.0.1040/assets/img/element/element3_2.png interact_pk_1.0.0.1040/assets/img/element/element4_1.png interact_pk_1.0.0.1040/assets/img/element/element4_2.png interact_pk_1.0.0.1040/assets/img/errorShadow.png interact_pk_1.0.0.1040/assets/img/errorShadow_bottom.png interact_pk_1.0.0.1040/assets/img/failRightIcon.png interact_pk_1.0.0.1040/assets/img/finishPage_left.png interact_pk_1.0.0.1040/assets/img/finishPage_right.png interact_pk_1.0.0.1040/assets/img/gameLevelStar.png interact_pk_1.0.0.1040/assets/img/goodFont/0.png interact_pk_1.0.0.1040/assets/img/goodFont/1.png interact_pk_1.0.0.1040/assets/img/goodFont/2.png interact_pk_1.0.0.1040/assets/img/goodFont/3.png interact_pk_1.0.0.1040/assets/img/goodFont/4.png interact_pk_1.0.0.1040/assets/img/goodFont/5.png interact_pk_1.0.0.1040/assets/img/goodFont/6.png interact_pk_1.0.0.1040/assets/img/goodFont/7.png interact_pk_1.0.0.1040/assets/img/goodFont/8.png interact_pk_1.0.0.1040/assets/img/goodFont/9.png interact_pk_1.0.0.1040/assets/img/goodFont/good10.png interact_pk_1.0.0.1040/assets/img/goodFont/good11.png interact_pk_1.0.0.1040/assets/img/goodFont/good12.png interact_pk_1.0.0.1040/assets/img/goodFont/good13.png interact_pk_1.0.0.1040/assets/img/goodFont/good14.png interact_pk_1.0.0.1040/assets/img/goodFont/good15.png interact_pk_1.0.0.1040/assets/img/goodFont/good16.png interact_pk_1.0.0.1040/assets/img/goodFont/good17.png interact_pk_1.0.0.1040/assets/img/goodFont/good18.png interact_pk_1.0.0.1040/assets/img/goodFont/good19.png interact_pk_1.0.0.1040/assets/img/goodFont/good20.png interact_pk_1.0.0.1040/assets/img/goodFont/good3.png interact_pk_1.0.0.1040/assets/img/goodFont/good4.png interact_pk_1.0.0.1040/assets/img/goodFont/good5.png interact_pk_1.0.0.1040/assets/img/goodFont/good6.png interact_pk_1.0.0.1040/assets/img/goodFont/good7.png interact_pk_1.0.0.1040/assets/img/goodFont/good8.png interact_pk_1.0.0.1040/assets/img/goodFont/good9.png interact_pk_1.0.0.1040/assets/img/goodFont/level1.png interact_pk_1.0.0.1040/assets/img/goodFont/level2.png interact_pk_1.0.0.1040/assets/img/goodFont/level3.png interact_pk_1.0.0.1040/assets/img/goodFont/level4.png interact_pk_1.0.0.1040/assets/img/header-btn-bg-bottom.png interact_pk_1.0.0.1040/assets/img/header-btn-bg-corner.png interact_pk_1.0.0.1040/assets/img/header-btn-bg-line.png interact_pk_1.0.0.1040/assets/img/icon_upload_btn.png interact_pk_1.0.0.1040/assets/img/img_grass.png interact_pk_1.0.0.1040/assets/img/img_light.png interact_pk_1.0.0.1040/assets/img/leftGroup.png interact_pk_1.0.0.1040/assets/img/letsgo.png interact_pk_1.0.0.1040/assets/img/pauseBtn.png interact_pk_1.0.0.1040/assets/img/pausePage.png interact_pk_1.0.0.1040/assets/img/picture/picture1_1.png interact_pk_1.0.0.1040/assets/img/picture/picture1_2.png interact_pk_1.0.0.1040/assets/img/picture/picture2_1.png interact_pk_1.0.0.1040/assets/img/picture/picture2_2.png interact_pk_1.0.0.1040/assets/img/picture/picture3_1.png interact_pk_1.0.0.1040/assets/img/picture/picture3_2.png interact_pk_1.0.0.1040/assets/img/picture/picture4_1.png interact_pk_1.0.0.1040/assets/img/picture/picture4_2.png interact_pk_1.0.0.1040/assets/img/picture/??ɫ-????.png interact_pk_1.0.0.1040/assets/img/picture/??ɫ-????.png interact_pk_1.0.0.1040/assets/img/resetBtn.png interact_pk_1.0.0.1040/assets/img/resetBtn2.png interact_pk_1.0.0.1040/assets/img/rightGroup.png interact_pk_1.0.0.1040/assets/img/rightIcon.png interact_pk_1.0.0.1040/assets/img/sameScorePage.png interact_pk_1.0.0.1040/assets/img/select_set.png interact_pk_1.0.0.1040/assets/img/showAnswerBtn.png interact_pk_1.0.0.1040/assets/img/shrink.png interact_pk_1.0.0.1040/assets/img/sprite/blow.gif interact_pk_1.0.0.1040/assets/img/sprite/blow.png interact_pk_1.0.0.1040/assets/img/sprite/blow1.png interact_pk_1.0.0.1040/assets/img/sprite/blows.gif interact_pk_1.0.0.1040/assets/img/star_gray.png interact_pk_1.0.0.1040/assets/img/theme/theme1.png interact_pk_1.0.0.1040/assets/img/theme/theme2.png interact_pk_1.0.0.1040/assets/img/theme/theme3.png interact_pk_1.0.0.1040/assets/img/theme/theme4.png interact_pk_1.0.0.1040/assets/img/theme/theme_1.png interact_pk_1.0.0.1040/assets/img/theme/theme_2.png interact_pk_1.0.0.1040/assets/img/theme/theme_3.png interact_pk_1.0.0.1040/assets/img/theme/theme_4.png interact_pk_1.0.0.1040/assets/img/theme/thumb_1.png interact_pk_1.0.0.1040/assets/img/theme/thumb_2.png interact_pk_1.0.0.1040/assets/img/theme/thumb_3.png interact_pk_1.0.0.1040/assets/img/theme/thumb_4.png interact_pk_1.0.0.1040/assets/img/wrongIcon.png interact_pk_1.0.0.1040/libs/customiseControls.js /* * fabric.js Controls Extension * for fabric.js current build * Simon Kunz 09.02.2016 for pixolith * Licensed under the MIT license. */ 'use strict'; (function(window) { var fabric = window.fabric || ( window.fabric = {} ), minExtCompat = '1.6.0', isVML = function() { return typeof G_vmlCanvasManager !== 'undefined'; }, degreesToRadians = fabric.util.degreesToRadians, cursorOffset = { mt: 0, // n tr: 1, // ne mr: 2, // e br: 3, // se mb: 4, // s bl: 5, // sw ml: 6, // w tl: 7, // nw }; if (minExtCompat.localeCompare(window.fabric.version) > -1) { console.warn('this extension might not be fully compatible with your version ' + 'of fabric.js (' + window.fabric.version + ').' + 'Consider using the latest compatible build of fabric.js (> ' + minExtCompat + ')' ); } fabric.util.object.extend(fabric.Object.prototype, { /** * When true, image icons are loaded via the drawImage method * @type Boolean * @default false */ useCustomIcons: false, /** * Sets a background-color for drawImage operations with transparency * @type string * @default transparent */ cornerBackgroundColor: 'transparent', /** * Sets the shape of the background for drawImage operations with transparency * @type string * @default rect */ cornerShape: '', /** * Inner Padding between Shape Background and drawn Image * @type int * @default rect */ cornerPadding: 0, /** * Set a custom corner icon * @param {Object} obj settings and icon url. * @param callback function */ customiseCornerIcons: function(obj, callback) { var setting, cornerConfig; for (setting in obj) { if (obj.hasOwnProperty(setting)) { cornerConfig = {}; if (obj[setting].cornerShape !== undefined) { this.cornerShape = obj[setting].cornerShape; } if (obj[setting].cornerBackgroundColor !== undefined) { this.cornerBackgroundColor = obj[setting].cornerBackgroundColor; } if (obj[setting].borderColor !== undefined) { this.borderColor = obj[setting].borderColor; } if (obj[setting].cornerSize !== undefined) { this.cornerSize = obj[setting].cornerSize; } if (obj[setting].cornerPadding !== undefined) { this.cornerPadding = obj[setting].cornerPadding; } if (obj[setting].icon !== undefined || Object.keys(obj)[0] === 'settings') { this.useCustomIcons = true; if (obj[setting].settings !== undefined) { cornerConfig.settings = obj[setting].settings; } if (obj[setting].icon !== undefined) { cornerConfig.icon = obj[setting].icon; this.loadIcon(setting, cornerConfig, function() { if (callback && typeof( callback ) === 'function') { callback(); } }); } } } } }, /** * loads the icon image as an image src. * @param {Object} corner to load an icon. * @param cornerConfig as object containing icon url and corner specific settings * @param callback function. */ loadIcon: function(corner, cornerConfig, callback) { var self = this, icon = new Image(); icon.onload = function() { self[corner + 'Icon'] = this; if (cornerConfig.settings) { self[corner + 'Settings'] = cornerConfig.settings; } if (callback && typeof( callback ) === 'function') { callback(); } }; icon.onerror = function() { fabric.warn(this.src + ' icon is not an image'); }; if (cornerConfig.icon.match(/^http[s]?:\/\//) || cornerConfig.icon.substring(0, 2) === '//') { icon.crossOrigin = 'Anonymous'; } icon.src = cornerConfig.icon; }, /** * copy of the setter method for our american friends. * @param {Object} obj containing corner icon urls and settings. */ customizeCornerIcons: function(obj) { this.customiseCornerIcons(obj); }, /** * Draws corners of an object's bounding box. * Requires public properties: width, height * Requires public options: cornerSize, padding * @param {CanvasRenderingContext2D} ctx Context to draw on * @return {fabric.Object} thisArg * @chainable */ drawControls: function(ctx) { if (!this.hasControls) { return this; } var wh = this._calculateCurrentDimensions(), width = wh.x, height = wh.y, scaleOffset = this.cornerSize, left = -(width + scaleOffset) / 2, top = -(height + scaleOffset) / 2, methodName; if (!this.useCustomIcons) { ctx.lineWidth = 1; ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1; ctx.strokeStyle = ctx.fillStyle = this.cornerColor; if (!this.transparentCorners) { ctx.strokeStyle = this.cornerStrokeColor; } methodName = this.transparentCorners ? 'stroke' : 'fill'; } else { methodName = 'drawImage'; } ctx.save(); this._setLineDash(ctx, this.cornerDashArray, null); // top-left this._drawControl('tl', ctx, methodName, left, top, this.tlIcon, this.tlSettings ); // top-right this._drawControl('tr', ctx, methodName, left + width, top, this.trIcon, this.trSettings ); // bottom-left this._drawControl('bl', ctx, methodName, left, top + height, this.blIcon, this.blSettings ); // bottom-right this._drawControl('br', ctx, methodName, left + width, top + height, this.brIcon, this.brSettings ); if (!this.get('lockUniScaling')) { // middle-top this._drawControl('mt', ctx, methodName, left + width / 2, top, this.mtIcon, this.mtSettings ); // middle-bottom this._drawControl('mb', ctx, methodName, left + width / 2, top + height, this.mbIcon, this.mbSettings ); // middle-right this._drawControl('mr', ctx, methodName, left + width, top + height / 2, this.mrIcon, this.mrSettings ); // middle-left this._drawControl('ml', ctx, methodName, left, top + height / 2, this.mlIcon, this.mlSettings ); } // middle-top-rotate if (this.hasRotatingPoint) { this._drawControl('mtr', ctx, methodName, left + width / 2, top - this.rotatingPointOffset, this.mtrIcon, this.mtrSettings ); } ctx.restore(); return this; }, /** Draw controls either with background-shape and color (transparency) or plain image (modified core method) * @private * {string} icon url of the control */ _drawControl: function(control, ctx, methodName, left, top, icon, settings) { if (!this.isControlVisible(control)) { return; } var size = this.cornerSize, cornerStroke = this.cornerStrokeColor || 'transparent', cornerBG = this.cornerBackgroundColor || 'black', cornerShape = this.cornerShape || 'rect', cornerPadding = typeof this.cornerPadding === 'number' ? this.cornerPadding : 10; if (settings) { if (settings.cornerSize) { // Set the size, and also recalc left and top left = left + size / 2 - settings.cornerSize / 2; top = top + size / 2 - settings.cornerSize / 2; size = settings.cornerSize; } cornerShape = settings.cornerShape || cornerShape; cornerBG = settings.cornerBackgroundColor || cornerBG; cornerPadding = typeof settings.cornerPadding === 'number' ? settings.cornerPadding : cornerPadding; cornerStroke = settings.cornerStrokeColor || cornerStroke; } if (this.useCustomIcons) { if (cornerShape) { ctx.globalAlpha = 1; ctx.fillStyle = cornerBG; ctx.lineWidth = 1; ctx.strokeStyle = cornerStroke; switch (cornerShape) { case 'rect': ctx.fillRect(left, top, size, size); if (cornerStroke) { ctx.strokeRect(left, top, size, size); } break; case 'circle': ctx.beginPath(); ctx.arc(left + size / 2, top + size / 2, size / 2, 0, 2 * Math.PI); ctx.fill(); if (cornerStroke) { ctx.stroke(); } ctx.closePath(); break; } if (icon !== undefined) { ctx[methodName]( icon, left + cornerPadding / 2, top + cornerPadding / 2, size - cornerPadding, size - cornerPadding ); } } else { if (icon !== undefined) { ctx[methodName]( icon, left, top, size, size ); } } } else { isVML() || this.transparentCorners || ctx.clearRect(left, top, size, size); ctx[methodName + 'Rect'](left, top, size, size); if (!this.transparentCorners && cornerStroke) { ctx.strokeRect(left, top, size, size); } } }, }); fabric.util.object.extend(fabric.Canvas.prototype, { /** * When true, actions can be overwritten * @type Boolean * @default false */ overwriteActions: false, /** * When true, cursors are fixed * @type Boolean * @default false */ fixedCursors: false, /** * setter Method for actions and cursors. * @param {Object} obj containing corner action and cursor url/type. */ customiseControls: function(obj) { var setting; for (setting in obj) { if (obj.hasOwnProperty(setting)) { if (obj[setting].action !== undefined) { this.overwriteActions = true; this.setCustomAction(setting, obj[setting].action); } if (obj[setting].cursor !== undefined) { this.fixedCursors = true; this.setCustomCursor(setting, obj[setting].cursor); } } } }, /** * loads the icon image as an image src. * @param {Object} corner to load an icon. * @param action as a string. */ setCustomAction: function(corner, action) { this[corner + 'Action'] = action; }, /** * loads the icon image as an image src. * @param {Object} corner to load an icon. * @param cursorUrl as a string. */ setCustomCursor: function(corner, cursorUrl) { this[corner + 'cursorIcon'] = cursorUrl; }, /** * copy of the setter method for our american friends. * @param {Object} obj containing corner action and cursor url/type. */ customizeControls: function(obj) { this.customiseControls(obj); }, /** * @private */ _getActionFromCorner: function(target, corner, e) { if (!corner) { return 'drag'; } if (corner) { if (this[corner + 'Action'] && this.overwriteActions) { switch (corner) { case 'mtr': return this[corner + 'Action'] || 'rotate'; case 'ml': case 'mr': if (e[this.altActionKey]) { return e[this.altActionKey] ? 'skewY' : 'scaleX'; } return this[corner + 'Action']; case 'mt': case 'mb': if (e[this.altActionKey]) { return e[this.altActionKey] ? 'skewY' : 'scaleY'; } return this[corner + 'Action']; default: return this[corner + 'Action'] || 'scale'; } } else { switch (corner) { case 'mtr': return 'rotate'; case 'ml': case 'mr': return e[this.altActionKey] ? 'skewY' : 'scaleX'; case 'mt': case 'mb': return e[this.altActionKey] ? 'skewX' : 'scaleY'; default: return 'scale'; } } } return false; }, /** * @private * @param {Event} e Event object * @param {fabric.Object} target */ _setupCurrentTransform: function(e, target) { if (!target) { return; } var pointer = this.getPointer(e), corner = target._findTargetCorner(this.getPointer(e, true)), action = this._getActionFromCorner(target, corner, e), origin = this._getOriginFromCorner(target, corner); if (typeof action === 'function') { action.call(this, e, target); // as of fabric 1.7.11 object cache will try to slice the action to check for scale so we need to convert this to a string action = 'void'; } this._currentTransform = { target: target, action: action, corner: corner, scaleX: target.scaleX, scaleY: target.scaleY, skewX: target.skewX, skewY: target.skewY, offsetX: pointer.x - target.left, offsetY: pointer.y - target.top, originX: origin.x, originY: origin.y, ex: pointer.x, ey: pointer.y, lastX: pointer.x, lastY: pointer.y, left: target.left, top: target.top, theta: degreesToRadians(target.angle), width: target.width * target.scaleX, mouseXSign: 1, mouseYSign: 1, shiftKey: e.shiftKey, altKey: e[this.centeredKey], }; this._currentTransform.original = { left: target.left, top: target.top, scaleX: target.scaleX, scaleY: target.scaleY, skewX: target.skewX, skewY: target.skewY, originX: origin.x, originY: origin.y, }; if (action === 'remove') { this._removeAction(e, target); } if (action === 'moveUp') { this._moveLayerUpAction(e, target); } if (action === 'moveDown') { this._moveLayerDownAction(e, target); } if (typeof action === 'object') { if (Object.keys(action)[0] === 'rotateByDegrees') { this._rotateByDegrees(e, target, action.rotateByDegrees); } } this._resetCurrentTransform(); }, /** * Custom remove object action * @private * @param {Event} e Event object * @param {fabric.Object} target */ _removeAction: function(e, target) { var _this = this; if (this.getActiveGroup() && this.getActiveGroup() !== 'undefined') { this.getActiveGroup().forEachObject(function(o) { o.off(); o.remove(); }); this.discardActiveGroup(); // as of fabric 1.6.3 necessary for reasons.. setTimeout(function() { _this.deactivateAll(); }, 0); } else { target.off(); target.remove(); setTimeout(function() { _this.deactivateAll(); }, 0); } }, /** * Custom move up object action * @private * @param {Event} e Event object * @param {fabric.Object} target */ _moveLayerUpAction: function(e, target) { if (this.getActiveGroup() && this.getActiveGroup() !== 'undefined') { this.getActiveGroup().forEachObject(function(o) { o.bringForward(); }); } else { target.bringForward(); } }, /** * Custom move down object action * @private * @param {Event} e Event object * @param {fabric.Object} target */ _moveLayerDownAction: function(e, target) { if (this.getActiveGroup() && this.getActiveGroup() !== 'undefined') { this.getActiveGroup().forEachObject(function(o) { o.sendBackwards(); }); } else { target.sendBackwards(); } }, /** * Custom move down object action * @private * @param {Event} e Event object * @param {fabric.Object} target * @param {Integer} value of rotation */ _rotateByDegrees: function(e, target, value) { var angle = parseInt(target.getAngle()) + value, needsOriginRestore = false; if (( target.originX !== 'center' || target.originY !== 'center' ) && target.centeredRotation) { this._setOriginToCenter(target); needsOriginRestore = true; } angle = angle > 360 ? angle - 360 : angle; if (this.getActiveGroup() && this.getActiveGroup() !== 'undefined') { this.getActiveGroup().forEachObject(function(obj) { obj .setAngle(angle) .setCoords(); }); } else { target .setAngle(angle) .setCoords(); } if (needsOriginRestore) { this._setCenterToOrigin(target); } this.renderAll(); }, /** * Sets either the standard behaviour cursors or if fixedCursors is true, tries to set a custom cursor * either by using an icon or a build-in cursor. Cursor icon extensions are matched with a regular expression. * @private * {string} corner name * {target} event handler of the hovered corner */ _setCornerCursor: function(corner, target, e) { var iconUrlPattern = /\.(?:jpe?g|png|gif|jpg|jpeg|svg)$/; if (this.fixedCursors && this[corner + 'cursorIcon']) { if (this[corner + 'cursorIcon'].match(iconUrlPattern)) { this.setCursor('url(' + this[corner + 'cursorIcon'] + '), auto'); } else { if (this[corner + 'cursorIcon'] === 'resize') { this.setCursor(this._getRotatedCornerCursor(corner, target, e)); } else { this.setCursor(this[corner + 'cursorIcon']); } } } else { if (corner in cursorOffset) { this.setCursor(this._getRotatedCornerCursor(corner, target, e)); } else if (corner === 'mtr' && target.hasRotatingPoint) { this.setCursor(this.rotationCursor); } else { this.setCursor(this.defaultCursor); return false; } } return false; }, }); if (typeof exports !== 'undefined') { module.exports = this; } })(window); interact_pk_1.0.0.1040/libs/customiseControls.js.gz interact_pk_1.0.0.1040/libs/customiseControls.js /* * fabric.js Controls Extension * for fabric.js current build * Simon Kunz 09.02.2016 for pixolith * Licensed under the MIT license. */ 'use strict'; (function(window) { var fabric = window.fabric || ( window.fabric = {} ), minExtCompat = '1.6.0', isVML = function() { return typeof G_vmlCanvasManager !== 'undefined'; }, degreesToRadians = fabric.util.degreesToRadians, cursorOffset = { mt: 0, // n tr: 1, // ne mr: 2, // e br: 3, // se mb: 4, // s bl: 5, // sw ml: 6, // w tl: 7, // nw }; if (minExtCompat.localeCompare(window.fabric.version) > -1) { console.warn('this extension might not be fully compatible with your version ' + 'of fabric.js (' + window.fabric.version + ').' + 'Consider using the latest compatible build of fabric.js (> ' + minExtCompat + ')' ); } fabric.util.object.extend(fabric.Object.prototype, { /** * When true, image icons are loaded via the drawImage method * @type Boolean * @default false */ useCustomIcons: false, /** * Sets a background-color for drawImage operations with transparency * @type string * @default transparent */ cornerBackgroundColor: 'transparent', /** * Sets the shape of the background for drawImage operations with transparency * @type string * @default rect */ cornerShape: '', /** * Inner Padding between Shape Background and drawn Image * @type int * @default rect */ cornerPadding: 0, /** * Set a custom corner icon * @param {Object} obj settings and icon url. * @param callback function */ customiseCornerIcons: function(obj, callback) { var setting, cornerConfig; for (setting in obj) { if (obj.hasOwnProperty(setting)) { cornerConfig = {}; if (obj[setting].cornerShape !== undefined) { this.cornerShape = obj[setting].cornerShape; } if (obj[setting].cornerBackgroundColor !== undefined) { this.cornerBackgroundColor = obj[setting].cornerBackgroundColor; } if (obj[setting].borderColor !== undefined) { this.borderColor = obj[setting].borderColor; } if (obj[setting].cornerSize !== undefined) { this.cornerSize = obj[setting].cornerSize; } if (obj[setting].cornerPadding !== undefined) { this.cornerPadding = obj[setting].cornerPadding; } if (obj[setting].icon !== undefined || Object.keys(obj)[0] === 'settings') { this.useCustomIcons = true; if (obj[setting].settings !== undefined) { cornerConfig.settings = obj[setting].settings; } if (obj[setting].icon !== undefined) { cornerConfig.icon = obj[setting].icon; this.loadIcon(setting, cornerConfig, function() { if (callback && typeof( callback ) === 'function') { callback(); } }); } } } } }, /** * loads the icon image as an image src. * @param {Object} corner to load an icon. * @param cornerConfig as object containing icon url and corner specific settings * @param callback function. */ loadIcon: function(corner, cornerConfig, callback) { var self = this, icon = new Image(); icon.onload = function() { self[corner + 'Icon'] = this; if (cornerConfig.settings) { self[corner + 'Settings'] = cornerConfig.settings; } if (callback && typeof( callback ) === 'function') { callback(); } }; icon.onerror = function() { fabric.warn(this.src + ' icon is not an image'); }; if (cornerConfig.icon.match(/^http[s]?:\/\//) || cornerConfig.icon.substring(0, 2) === '//') { icon.crossOrigin = 'Anonymous'; } icon.src = cornerConfig.icon; }, /** * copy of the setter method for our american friends. * @param {Object} obj containing corner icon urls and settings. */ customizeCornerIcons: function(obj) { this.customiseCornerIcons(obj); }, /** * Draws corners of an object's bounding box. * Requires public properties: width, height * Requires public options: cornerSize, padding * @param {CanvasRenderingContext2D} ctx Context to draw on * @return {fabric.Object} thisArg * @chainable */ drawControls: function(ctx) { if (!this.hasControls) { return this; } var wh = this._calculateCurrentDimensions(), width = wh.x, height = wh.y, scaleOffset = this.cornerSize, left = -(width + scaleOffset) / 2, top = -(height + scaleOffset) / 2, methodName; if (!this.useCustomIcons) { ctx.lineWidth = 1; ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1; ctx.strokeStyle = ctx.fillStyle = this.cornerColor; if (!this.transparentCorners) { ctx.strokeStyle = this.cornerStrokeColor; } methodName = this.transparentCorners ? 'stroke' : 'fill'; } else { methodName = 'drawImage'; } ctx.save(); this._setLineDash(ctx, this.cornerDashArray, null); // top-left this._drawControl('tl', ctx, methodName, left, top, this.tlIcon, this.tlSettings ); // top-right this._drawControl('tr', ctx, methodName, left + width, top, this.trIcon, this.trSettings ); // bottom-left this._drawControl('bl', ctx, methodName, left, top + height, this.blIcon, this.blSettings ); // bottom-right this._drawControl('br', ctx, methodName, left + width, top + height, this.brIcon, this.brSettings ); if (!this.get('lockUniScaling')) { // middle-top this._drawControl('mt', ctx, methodName, left + width / 2, top, this.mtIcon, this.mtSettings ); // middle-bottom this._drawControl('mb', ctx, methodName, left + width / 2, top + height, this.mbIcon, this.mbSettings ); // middle-right this._drawControl('mr', ctx, methodName, left + width, top + height / 2, this.mrIcon, this.mrSettings ); // middle-left this._drawControl('ml', ctx, methodName, left, top + height / 2, this.mlIcon, this.mlSettings ); } // middle-top-rotate if (this.hasRotatingPoint) { this._drawControl('mtr', ctx, methodName, left + width / 2, top - this.rotatingPointOffset, this.mtrIcon, this.mtrSettings ); } ctx.restore(); return this; }, /** Draw controls either with background-shape and color (transparency) or plain image (modified core method) * @private * {string} icon url of the control */ _drawControl: function(control, ctx, methodName, left, top, icon, settings) { if (!this.isControlVisible(control)) { return; } var size = this.cornerSize, cornerStroke = this.cornerStrokeColor || 'transparent', cornerBG = this.cornerBackgroundColor || 'black', cornerShape = this.cornerShape || 'rect', cornerPadding = typeof this.cornerPadding === 'number' ? this.cornerPadding : 10; if (settings) { if (settings.cornerSize) { // Set the size, and also recalc left and top left = left + size / 2 - settings.cornerSize / 2; top = top + size / 2 - settings.cornerSize / 2; size = settings.cornerSize; } cornerShape = settings.cornerShape || cornerShape; cornerBG = settings.cornerBackgroundColor || cornerBG; cornerPadding = typeof settings.cornerPadding === 'number' ? settings.cornerPadding : cornerPadding; cornerStroke = settings.cornerStrokeColor || cornerStroke; } if (this.useCustomIcons) { if (cornerShape) { ctx.globalAlpha = 1; ctx.fillStyle = cornerBG; ctx.lineWidth = 1; ctx.strokeStyle = cornerStroke; switch (cornerShape) { case 'rect': ctx.fillRect(left, top, size, size); if (cornerStroke) { ctx.strokeRect(left, top, size, size); } break; case 'circle': ctx.beginPath(); ctx.arc(left + size / 2, top + size / 2, size / 2, 0, 2 * Math.PI); ctx.fill(); if (cornerStroke) { ctx.stroke(); } ctx.closePath(); break; } if (icon !== undefined) { ctx[methodName]( icon, left + cornerPadding / 2, top + cornerPadding / 2, size - cornerPadding, size - cornerPadding ); } } else { if (icon !== undefined) { ctx[methodName]( icon, left, top, size, size ); } } } else { isVML() || this.transparentCorners || ctx.clearRect(left, top, size, size); ctx[methodName + 'Rect'](left, top, size, size); if (!this.transparentCorners && cornerStroke) { ctx.strokeRect(left, top, size, size); } } }, }); fabric.util.object.extend(fabric.Canvas.prototype, { /** * When true, actions can be overwritten * @type Boolean * @default false */ overwriteActions: false, /** * When true, cursors are fixed * @type Boolean * @default false */ fixedCursors: false, /** * setter Method for actions and cursors. * @param {Object} obj containing corner action and cursor url/type. */ customiseControls: function(obj) { var setting; for (setting in obj) { if (obj.hasOwnProperty(setting)) { if (obj[setting].action !== undefined) { this.overwriteActions = true; this.setCustomAction(setting, obj[setting].action); } if (obj[setting].cursor !== undefined) { this.fixedCursors = true; this.setCustomCursor(setting, obj[setting].cursor); } } } }, /** * loads the icon image as an image src. * @param {Object} corner to load an icon. * @param action as a string. */ setCustomAction: function(corner, action) { this[corner + 'Action'] = action; }, /** * loads the icon image as an image src. * @param {Object} corner to load an icon. * @param cursorUrl as a string. */ setCustomCursor: function(corner, cursorUrl) { this[corner + 'cursorIcon'] = cursorUrl; }, /** * copy of the setter method for our american friends. * @param {Object} obj containing corner action and cursor url/type. */ customizeControls: function(obj) { this.customiseControls(obj); }, /** * @private */ _getActionFromCorner: function(target, corner, e) { if (!corner) { return 'drag'; } if (corner) { if (this[corner + 'Action'] && this.overwriteActions) { switch (corner) { case 'mtr': return this[corner + 'Action'] || 'rotate'; case 'ml': case 'mr': if (e[this.altActionKey]) { return e[this.altActionKey] ? 'skewY' : 'scaleX'; } return this[corner + 'Action']; case 'mt': case 'mb': if (e[this.altActionKey]) { return e[this.altActionKey] ? 'skewY' : 'scaleY'; } return this[corner + 'Action']; default: return this[corner + 'Action'] || 'scale'; } } else { switch (corner) { case 'mtr': return 'rotate'; case 'ml': case 'mr': return e[this.altActionKey] ? 'skewY' : 'scaleX'; case 'mt': case 'mb': return e[this.altActionKey] ? 'skewX' : 'scaleY'; default: return 'scale'; } } } return false; }, /** * @private * @param {Event} e Event object * @param {fabric.Object} target */ _setupCurrentTransform: function(e, target) { if (!target) { return; } var pointer = this.getPointer(e), corner = target._findTargetCorner(this.getPointer(e, true)), action = this._getActionFromCorner(target, corner, e), origin = this._getOriginFromCorner(target, corner); if (typeof action === 'function') { action.call(this, e, target); // as of fabric 1.7.11 object cache will try to slice the action to check for scale so we need to convert this to a string action = 'void'; } this._currentTransform = { target: target, action: action, corner: corner, scaleX: target.scaleX, scaleY: target.scaleY, skewX: target.skewX, skewY: target.skewY, offsetX: pointer.x - target.left, offsetY: pointer.y - target.top, originX: origin.x, originY: origin.y, ex: pointer.x, ey: pointer.y, lastX: pointer.x, lastY: pointer.y, left: target.left, top: target.top, theta: degreesToRadians(target.angle), width: target.width * target.scaleX, mouseXSign: 1, mouseYSign: 1, shiftKey: e.shiftKey, altKey: e[this.centeredKey], }; this._currentTransform.original = { left: target.left, top: target.top, scaleX: target.scaleX, scaleY: target.scaleY, skewX: target.skewX, skewY: target.skewY, originX: origin.x, originY: origin.y, }; if (action === 'remove') { this._removeAction(e, target); } if (action === 'moveUp') { this._moveLayerUpAction(e, target); } if (action === 'moveDown') { this._moveLayerDownAction(e, target); } if (typeof action === 'object') { if (Object.keys(action)[0] === 'rotateByDegrees') { this._rotateByDegrees(e, target, action.rotateByDegrees); } } this._resetCurrentTransform(); }, /** * Custom remove object action * @private * @param {Event} e Event object * @param {fabric.Object} target */ _removeAction: function(e, target) { var _this = this; if (this.getActiveGroup() && this.getActiveGroup() !== 'undefined') { this.getActiveGroup().forEachObject(function(o) { o.off(); o.remove(); }); this.discardActiveGroup(); // as of fabric 1.6.3 necessary for reasons.. setTimeout(function() { _this.deactivateAll(); }, 0); } else { target.off(); target.remove(); setTimeout(function() { _this.deactivateAll(); }, 0); } }, /** * Custom move up object action * @private * @param {Event} e Event object * @param {fabric.Object} target */ _moveLayerUpAction: function(e, target) { if (this.getActiveGroup() && this.getActiveGroup() !== 'undefined') { this.getActiveGroup().forEachObject(function(o) { o.bringForward(); }); } else { target.bringForward(); } }, /** * Custom move down object action * @private * @param {Event} e Event object * @param {fabric.Object} target */ _moveLayerDownAction: function(e, target) { if (this.getActiveGroup() && this.getActiveGroup() !== 'undefined') { this.getActiveGroup().forEachObject(function(o) { o.sendBackwards(); }); } else { target.sendBackwards(); } }, /** * Custom move down object action * @private * @param {Event} e Event object * @param {fabric.Object} target * @param {Integer} value of rotation */ _rotateByDegrees: function(e, target, value) { var angle = parseInt(target.getAngle()) + value, needsOriginRestore = false; if (( target.originX !== 'center' || target.originY !== 'center' ) && target.centeredRotation) { this._setOriginToCenter(target); needsOriginRestore = true; } angle = angle > 360 ? angle - 360 : angle; if (this.getActiveGroup() && this.getActiveGroup() !== 'undefined') { this.getActiveGroup().forEachObject(function(obj) { obj .setAngle(angle) .setCoords(); }); } else { target .setAngle(angle) .setCoords(); } if (needsOriginRestore) { this._setCenterToOrigin(target); } this.renderAll(); }, /** * Sets either the standard behaviour cursors or if fixedCursors is true, tries to set a custom cursor * either by using an icon or a build-in cursor. Cursor icon extensions are matched with a regular expression. * @private * {string} corner name * {target} event handler of the hovered corner */ _setCornerCursor: function(corner, target, e) { var iconUrlPattern = /\.(?:jpe?g|png|gif|jpg|jpeg|svg)$/; if (this.fixedCursors && this[corner + 'cursorIcon']) { if (this[corner + 'cursorIcon'].match(iconUrlPattern)) { this.setCursor('url(' + this[corner + 'cursorIcon'] + '), auto'); } else { if (this[corner + 'cursorIcon'] === 'resize') { this.setCursor(this._getRotatedCornerCursor(corner, target, e)); } else { this.setCursor(this[corner + 'cursorIcon']); } } } else { if (corner in cursorOffset) { this.setCursor(this._getRotatedCornerCursor(corner, target, e)); } else if (corner === 'mtr' && target.hasRotatingPoint) { this.setCursor(this.rotationCursor); } else { this.setCursor(this.defaultCursor); return false; } } return false; }, }); if (typeof exports !== 'undefined') { module.exports = this; } })(window); interact_pk_1.0.0.1040/libs/fabric.js /* build: `node build.js modules=ALL exclude=gestures,accessors requirejs minifier=uglifyjs` */ /*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */ var fabric = fabric || {version: '3.6.1'}; if (typeof exports !== 'undefined') { exports.fabric = fabric; } /* _AMD_START_ */ else if (typeof define === 'function' && define.amd) { define([], function () { return fabric; }); } /* _AMD_END_ */ if (typeof document !== 'undefined' && typeof window !== 'undefined') { if (document instanceof (typeof HTMLDocument !== 'undefined' ? HTMLDocument : Document)) { fabric.document = document; } else { fabric.document = document.implementation.createHTMLDocument(''); } fabric.window = window; } else { // assume we're running under node.js when document/window are not present var jsdom = require('jsdom'); var virtualWindow = new jsdom.JSDOM( decodeURIComponent('%3C!DOCTYPE%20html%3E%3Chtml%3E%3Chead%3E%3C%2Fhead%3E%3Cbody%3E%3C%2Fbody%3E%3C%2Fhtml%3E'), { features : { FetchExternalResources: ['img'] }, resources: 'usable' }).window; fabric.document = virtualWindow.document; fabric.jsdomImplForWrapper = require('jsdom/lib/jsdom/living/generated/utils').implForWrapper; fabric.nodeCanvas = require('jsdom/lib/jsdom/utils').Canvas; fabric.window = virtualWindow; DOMParser = fabric.window.DOMParser; } /** * True when in environment that supports touch events * @type boolean */ fabric.isTouchSupported = 'ontouchstart' in fabric.window || 'ontouchstart' in fabric.document || (fabric.window && fabric.window.navigator && fabric.window.navigator.maxTouchPoints > 0); /** * True when in environment that's probably Node.js * @type boolean */ fabric.isLikelyNode = typeof Buffer !== 'undefined' && typeof window === 'undefined'; /* _FROM_SVG_START_ */ /** * Attributes parsed from all SVG elements * @type array */ fabric.SHARED_ATTRIBUTES = [ 'display', 'transform', 'fill', 'fill-opacity', 'fill-rule', 'opacity', 'stroke', 'stroke-dasharray', 'stroke-linecap', 'stroke-dashoffset', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'id', 'paint-order', 'vector-effect', 'instantiated_by_use', 'clip-path' ]; /* _FROM_SVG_END_ */ /** * Pixel per Inch as a default value set to 96. Can be changed for more realistic conversion. */ fabric.DPI = 96; fabric.reNum = '(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:[eE][-+]?\\d+)?)'; fabric.rePathCommand = /([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:[eE][-+]?\d+)?)/ig; fabric.reNonWord = /[ \.,;!\?\-]/; fabric.fontPaths = {}; fabric.iMatrix = [1, 0, 0, 1, 0, 0]; fabric.svgNS = 'http://www.w3.org/2000/svg'; /** * Pixel limit for cache canvases. 1Mpx , 4Mpx should be fine. * @since 1.7.14 * @type Number * @default */ fabric.perfLimitSizeTotal = 2097152; /** * Pixel limit for cache canvases width or height. IE fixes the maximum at 5000 * @since 1.7.14 * @type Number * @default */ fabric.maxCacheSideLimit = 4096; /** * Lowest pixel limit for cache canvases, set at 256PX * @since 1.7.14 * @type Number * @default */ fabric.minCacheSideLimit = 256; /** * Cache Object for widths of chars in text rendering. */ fabric.charWidthsCache = {}; /** * if webgl is enabled and available, textureSize will determine the size * of the canvas backend * @since 2.0.0 * @type Number * @default */ fabric.textureSize = 2048; /** * When 'true', style information is not retained when copy/pasting text, making * pasted text use destination style. * Defaults to 'false'. * @type Boolean * @default */ fabric.disableStyleCopyPaste = false; /** * Enable webgl for filtering picture is available * A filtering backend will be initialized, this will both take memory and * time since a default 2048x2048 canvas will be created for the gl context * @since 2.0.0 * @type Boolean * @default */ fabric.enableGLFiltering = true; /** * Device Pixel Ratio * @see https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/HTML-canvas-guide/SettingUptheCanvas/SettingUptheCanvas.html */ fabric.devicePixelRatio = fabric.window.devicePixelRatio || fabric.window.webkitDevicePixelRatio || fabric.window.mozDevicePixelRatio || 1; /** * Browser-specific constant to adjust CanvasRenderingContext2D.shadowBlur value, * which is unitless and not rendered equally across browsers. * * Values that work quite well (as of October 2017) are: * - Chrome: 1.5 * - Edge: 1.75 * - Firefox: 0.9 * - Safari: 0.95 * * @since 2.0.0 * @type Number * @default 1 */ fabric.browserShadowBlurConstant = 1; /** * This object contains the result of arc to beizer conversion for faster retrieving if the same arc needs to be converted again. * It was an internal variable, is accessible since version 2.3.4 */ fabric.arcToSegmentsCache = {}; /** * This object keeps the results of the boundsOfCurve calculation mapped by the joined arguments necessary to calculate it. * It does speed up calculation, if you parse and add always the same paths, but in case of heavy usage of freedrawing * you do not get any speed benefit and you get a big object in memory. * The object was a private variable before, while now is appended to the lib so that you have access to it and you * can eventually clear it. * It was an internal variable, is accessible since version 2.3.4 */ fabric.boundsOfCurveCache = {}; /** * If disabled boundsOfCurveCache is not used. For apps that make heavy usage of pencil drawing probably disabling it is better * @default true */ fabric.cachesBoundsOfCurve = true; /** * Skip performance testing of setupGLContext and force the use of putImageData that seems to be the one that works best on * Chrome + old hardware. if your users are experiencing empty images after filtering you may try to force this to true * this has to be set before instantiating the filtering backend ( before filtering the first image ) * @type Boolean * @default false */ fabric.forceGLPutImageData = false; fabric.initFilterBackend = function () { if (fabric.enableGLFiltering && fabric.isWebglSupported && fabric.isWebglSupported(fabric.textureSize)) { console.log('max texture size: ' + fabric.maxTextureSize); return (new fabric.WebglFilterBackend({tileSize: fabric.textureSize})); } else if (fabric.Canvas2dFilterBackend) { return (new fabric.Canvas2dFilterBackend()); } }; if (typeof document !== 'undefined' && typeof window !== 'undefined') { // ensure globality even if entire library were function wrapped (as in Meteor.js packaging system) window.fabric = fabric; } (function () { /** * @private * @param {String} eventName * @param {Function} handler */ function _removeEventListener (eventName, handler) { if (!this.__eventListeners[eventName]) { return; } var eventListener = this.__eventListeners[eventName]; if (handler) { eventListener[eventListener.indexOf(handler)] = false; } else { fabric.util.array.fill(eventListener, false); } } /** * Observes specified event * @deprecated `observe` deprecated since 0.8.34 (use `on` instead) * @memberOf fabric.Observable * @alias on * @param {String|Object} eventName Event name (eg. 'after:render') or object with key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler}) * @param {Function} handler Function that receives a notification when an event of the specified type occurs * @return {Self} thisArg * @chainable */ function observe (eventName, handler) { if (!this.__eventListeners) { this.__eventListeners = {}; } // one object with key/value pairs was passed if (arguments.length === 1) { for (var prop in eventName) { this.on(prop, eventName[prop]); } } else { if (!this.__eventListeners[eventName]) { this.__eventListeners[eventName] = []; } this.__eventListeners[eventName].push(handler); } return this; } /** * Stops event observing for a particular event handler. Calling this method * without arguments removes all handlers for all events * @deprecated `stopObserving` deprecated since 0.8.34 (use `off` instead) * @memberOf fabric.Observable * @alias off * @param {String|Object} eventName Event name (eg. 'after:render') or object with key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler}) * @param {Function} handler Function to be deleted from EventListeners * @return {Self} thisArg * @chainable */ function stopObserving (eventName, handler) { if (!this.__eventListeners) { return this; } // remove all key/value pairs (event name -> event handler) if (arguments.length === 0) { for (eventName in this.__eventListeners) { _removeEventListener.call(this, eventName); } } // one object with key/value pairs was passed else if (arguments.length === 1 && typeof arguments[0] === 'object') { for (var prop in eventName) { _removeEventListener.call(this, prop, eventName[prop]); } } else { _removeEventListener.call(this, eventName, handler); } return this; } /** * Fires event with an optional options object * @deprecated `fire` deprecated since 1.0.7 (use `trigger` instead) * @memberOf fabric.Observable * @alias trigger * @param {String} eventName Event name to fire * @param {Object} [options] Options object * @return {Self} thisArg * @chainable */ function fire (eventName, options) { if (!this.__eventListeners) { return this; } var listenersForEvent = this.__eventListeners[eventName]; if (!listenersForEvent) { return this; } for (var i = 0, len = listenersForEvent.length; i < len; i++) { listenersForEvent[i] && listenersForEvent[i].call(this, options || {}); } this.__eventListeners[eventName] = listenersForEvent.filter(function (value) { return value !== false; }); return this; } /** * @namespace fabric.Observable * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#events} * @see {@link http://fabricjs.com/events|Events demo} */ fabric.Observable = { observe : observe, stopObserving: stopObserving, fire : fire, on : observe, off : stopObserving, trigger: fire }; })(); /** * @namespace fabric.Collection */ fabric.Collection = { _objects: [], /** * Adds objects to collection, Canvas or Group, then renders canvas * (if `renderOnAddRemove` is not `false`). * in case of Group no changes to bounding box are made. * Objects should be instances of (or inherit from) fabric.Object * Use of this function is highly discouraged for groups. * you can add a bunch of objects with the add method but then you NEED * to run a addWithUpdate call for the Group class or position/bbox will be wrong. * @param {...fabric.Object} object Zero or more fabric instances * @return {Self} thisArg * @chainable */ add: function () { this._objects.push.apply(this._objects, arguments); if (this._onObjectAdded) { for (var i = 0, length = arguments.length; i < length; i++) { this._onObjectAdded(arguments[i]); } } this.renderOnAddRemove && this.requestRenderAll(); return this; }, /** * Inserts an object into collection at specified index, then renders canvas (if `renderOnAddRemove` is not `false`) * An object should be an instance of (or inherit from) fabric.Object * Use of this function is highly discouraged for groups. * you can add a bunch of objects with the insertAt method but then you NEED * to run a addWithUpdate call for the Group class or position/bbox will be wrong. * @param {Object} object Object to insert * @param {Number} index Index to insert object at * @param {Boolean} nonSplicing When `true`, no splicing (shifting) of objects occurs * @return {Self} thisArg * @chainable */ insertAt: function (object, index, nonSplicing) { var objects = this._objects; if (nonSplicing) { objects[index] = object; } else { objects.splice(index, 0, object); } this._onObjectAdded && this._onObjectAdded(object); this.renderOnAddRemove && this.requestRenderAll(); return this; }, /** * Removes objects from a collection, then renders canvas (if `renderOnAddRemove` is not `false`) * @param {...fabric.Object} object Zero or more fabric instances * @return {Self} thisArg * @chainable */ remove: function () { var objects = this._objects, index, somethingRemoved = false; for (var i = 0, length = arguments.length; i < length; i++) { index = objects.indexOf(arguments[i]); // only call onObjectRemoved if an object was actually removed if (index !== -1) { somethingRemoved = true; objects.splice(index, 1); this._onObjectRemoved && this._onObjectRemoved(arguments[i]); } } this.renderOnAddRemove && somethingRemoved && this.requestRenderAll(); return this; }, /** * Executes given function for each object in this group * @param {Function} callback * Callback invoked with current object as first argument, * index - as second and an array of all objects - as third. * Callback is invoked in a context of Global Object (e.g. `window`) * when no `context` argument is given * * @param {Object} context Context (aka thisObject) * @return {Self} thisArg * @chainable */ forEachObject: function (callback, context) { var objects = this.getObjects(); for (var i = 0, len = objects.length; i < len; i++) { callback.call(context, objects[i], i, objects); } return this; }, /** * Returns an array of children objects of this instance * Type parameter introduced in 1.3.10 * since 2.3.5 this method return always a COPY of the array; * @param {String} [type] When specified, only objects of this type are returned * @return {Array} */ getObjects: function (type) { if (typeof type === 'undefined') { return this._objects.concat(); } return this._objects.filter(function (o) { return o.type === type; }); }, /** * Returns object at specified index * @param {Number} index * @return {Self} thisArg */ item: function (index) { return this._objects[index]; }, /** * Returns true if collection contains no objects * @return {Boolean} true if collection is empty */ isEmpty: function () { return this._objects.length === 0; }, /** * Returns a size of a collection (i.e: length of an array containing its objects) * @return {Number} Collection size */ size: function () { return this._objects.length; }, /** * Returns true if collection contains an object * @param {Object} object Object to check against * @return {Boolean} `true` if collection contains an object */ contains: function (object) { return this._objects.indexOf(object) > -1; }, /** * Returns number representation of a collection complexity * @return {Number} complexity */ complexity: function () { return this._objects.reduce(function (memo, current) { memo += current.complexity ? current.complexity() : 0; return memo; }, 0); } }; /** * @namespace fabric.CommonMethods */ fabric.CommonMethods = { /** * Sets object's properties from options * @param {Object} [options] Options object */ _setOptions: function (options) { for (var prop in options) { this.set(prop, options[prop]); } }, /** * @private * @param {Object} [filler] Options object * @param {String} [property] property to set the Gradient to */ _initGradient: function (filler, property) { if (filler && filler.colorStops && !(filler instanceof fabric.Gradient)) { this.set(property, new fabric.Gradient(filler)); } }, /** * @private * @param {Object} [filler] Options object * @param {String} [property] property to set the Pattern to * @param {Function} [callback] callback to invoke after pattern load */ _initPattern: function (filler, property, callback) { if (filler && filler.source && !(filler instanceof fabric.Pattern)) { this.set(property, new fabric.Pattern(filler, callback)); } else { callback && callback(); } }, /** * @private * @param {Object} [options] Options object */ _initClipping: function (options) { if (!options.clipTo || typeof options.clipTo !== 'string') { return; } var functionBody = fabric.util.getFunctionBody(options.clipTo); if (typeof functionBody !== 'undefined') { this.clipTo = new Function('ctx', functionBody); } }, /** * @private */ _setObject: function (obj) { for (var prop in obj) { this._set(prop, obj[prop]); } }, /** * Sets property to a given value. When changing position/dimension -related properties (left, top, scale, angle, etc.) `set` does not update position of object's borders/controls. If you need to update those, call `setCoords()`. * @param {String|Object} key Property name or object (if object, iterate over the object properties) * @param {Object|Function} value Property value (if function, the value is passed into it and its return value is used as a new one) * @return {fabric.Object} thisArg * @chainable */ set: function (key, value) { if (typeof key === 'object') { this._setObject(key); } else { if (typeof value === 'function' && key !== 'clipTo') { this._set(key, value(this.get(key))); } else { this._set(key, value); } } return this; }, _set: function (key, value) { this[key] = value; }, /** * Toggles specified property from `true` to `false` or from `false` to `true` * @param {String} property Property to toggle * @return {fabric.Object} thisArg * @chainable */ toggle: function (property) { var value = this.get(property); if (typeof value === 'boolean') { this.set(property, !value); } return this; }, /** * Basic getter * @param {String} property Property name * @return {*} value of a property */ get: function (property) { return this[property]; } }; (function (global) { var sqrt = Math.sqrt, atan2 = Math.atan2, pow = Math.pow, PiBy180 = Math.PI / 180, PiBy2 = Math.PI / 2; /** * @namespace fabric.util */ fabric.util = { /** * Calculate the cos of an angle, avoiding returning floats for known results * @static * @memberOf fabric.util * @param {Number} angle the angle in radians or in degree * @return {Number} */ cos: function (angle) { if (angle === 0) { return 1; } if (angle < 0) { // cos(a) = cos(-a) angle = -angle; } var angleSlice = angle / PiBy2; switch (angleSlice) { case 1: case 3: return 0; case 2: return -1; } return Math.cos(angle); }, /** * Calculate the sin of an angle, avoiding returning floats for known results * @static * @memberOf fabric.util * @param {Number} angle the angle in radians or in degree * @return {Number} */ sin: function (angle) { if (angle === 0) { return 0; } var angleSlice = angle / PiBy2, sign = 1; if (angle < 0) { // sin(-a) = -sin(a) sign = -1; } switch (angleSlice) { case 1: return sign; case 2: return 0; case 3: return -sign; } return Math.sin(angle); }, /** * Removes value from an array. * Presence of value (and its position in an array) is determined via `Array.prototype.indexOf` * @static * @memberOf fabric.util * @param {Array} array * @param {*} value * @return {Array} original array */ removeFromArray: function (array, value) { var idx = array.indexOf(value); if (idx !== -1) { array.splice(idx, 1); } return array; }, /** * Returns random number between 2 specified ones. * @static * @memberOf fabric.util * @param {Number} min lower limit * @param {Number} max upper limit * @return {Number} random value (between min and max) */ getRandomInt: function (min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; }, /** * Transforms degrees to radians. * @static * @memberOf fabric.util * @param {Number} degrees value in degrees * @return {Number} value in radians */ degreesToRadians: function (degrees) { return degrees * PiBy180; }, /** * Transforms radians to degrees. * @static * @memberOf fabric.util * @param {Number} radians value in radians * @return {Number} value in degrees */ radiansToDegrees: function (radians) { return radians / PiBy180; }, /** * Rotates `point` around `origin` with `radians` * @static * @memberOf fabric.util * @param {fabric.Point} point The point to rotate * @param {fabric.Point} origin The origin of the rotation * @param {Number} radians The radians of the angle for the rotation * @return {fabric.Point} The new rotated point */ rotatePoint: function (point, origin, radians) { point.subtractEquals(origin); var v = fabric.util.rotateVector(point, radians); return new fabric.Point(v.x, v.y).addEquals(origin); }, /** * Rotates `vector` with `radians` * @static * @memberOf fabric.util * @param {Object} vector The vector to rotate (x and y) * @param {Number} radians The radians of the angle for the rotation * @return {Object} The new rotated point */ rotateVector: function (vector, radians) { var sin = fabric.util.sin(radians), cos = fabric.util.cos(radians), rx = vector.x * cos - vector.y * sin, ry = vector.x * sin + vector.y * cos; return { x: rx, y: ry }; }, /** * Apply transform t to point p * @static * @memberOf fabric.util * @param {fabric.Point} p The point to transform * @param {Array} t The transform * @param {Boolean} [ignoreOffset] Indicates that the offset should not be applied * @return {fabric.Point} The transformed point */ transformPoint: function (p, t, ignoreOffset) { if (ignoreOffset) { return new fabric.Point( t[0] * p.x + t[2] * p.y, t[1] * p.x + t[3] * p.y ); } return new fabric.Point( t[0] * p.x + t[2] * p.y + t[4], t[1] * p.x + t[3] * p.y + t[5] ); }, /** * Returns coordinates of points's bounding rectangle (left, top, width, height) * @param {Array} points 4 points array * @param {Array} [transform] an array of 6 numbers representing a 2x3 transform matrix * @return {Object} Object with left, top, width, height properties */ makeBoundingBoxFromPoints: function (points, transform) { if (transform) { for (var i = 0; i < points.length; i++) { points[i] = fabric.util.transformPoint(points[i], transform); } } var xPoints = [points[0].x, points[1].x, points[2].x, points[3].x], minX = fabric.util.array.min(xPoints), maxX = fabric.util.array.max(xPoints), width = maxX - minX, yPoints = [points[0].y, points[1].y, points[2].y, points[3].y], minY = fabric.util.array.min(yPoints), maxY = fabric.util.array.max(yPoints), height = maxY - minY; return { left : minX, top : minY, width : width, height: height }; }, /** * Invert transformation t * @static * @memberOf fabric.util * @param {Array} t The transform * @return {Array} The inverted transform */ invertTransform: function (t) { var a = 1 / (t[0] * t[3] - t[1] * t[2]), r = [a * t[3], -a * t[1], -a * t[2], a * t[0]], o = fabric.util.transformPoint({x: t[4], y: t[5]}, r, true); r[4] = -o.x; r[5] = -o.y; return r; }, /** * A wrapper around Number#toFixed, which contrary to native method returns number, not string. * @static * @memberOf fabric.util * @param {Number|String} number number to operate on * @param {Number} fractionDigits number of fraction digits to "leave" * @return {Number} */ toFixed: function (number, fractionDigits) { return parseFloat(Number(number).toFixed(fractionDigits)); }, /** * Converts from attribute value to pixel value if applicable. * Returns converted pixels or original value not converted. * @param {Number|String} value number to operate on * @param {Number} fontSize * @return {Number|String} */ parseUnit: function (value, fontSize) { var unit = /\D{0,2}$/.exec(value), number = parseFloat(value); if (!fontSize) { fontSize = fabric.Text.DEFAULT_SVG_FONT_SIZE; } switch (unit[0]) { case 'mm': return number * fabric.DPI / 25.4; case 'cm': return number * fabric.DPI / 2.54; case 'in': return number * fabric.DPI; case 'pt': return number * fabric.DPI / 72; // or * 4 / 3 case 'pc': return number * fabric.DPI / 72 * 12; // or * 16 case 'em': return number * fontSize; default: return number; } }, /** * Function which always returns `false`. * @static * @memberOf fabric.util * @return {Boolean} */ falseFunction: function () { return false; }, /** * Returns klass "Class" object of given namespace * @memberOf fabric.util * @param {String} type Type of object (eg. 'circle') * @param {String} namespace Namespace to get klass "Class" object from * @return {Object} klass "Class" */ getKlass: function (type, namespace) { // capitalize first letter only type = fabric.util.string.camelize(type.charAt(0).toUpperCase() + type.slice(1)); return fabric.util.resolveNamespace(namespace)[type]; }, /** * Returns array of attributes for given svg that fabric parses * @memberOf fabric.util * @param {String} type Type of svg element (eg. 'circle') * @return {Array} string names of supported attributes */ getSvgAttributes: function (type) { var attributes = [ 'instantiated_by_use', 'style', 'id', 'class' ]; switch (type) { case 'linearGradient': attributes = attributes.concat(['x1', 'y1', 'x2', 'y2', 'gradientUnits', 'gradientTransform']); break; case 'radialGradient': attributes = attributes.concat(['gradientUnits', 'gradientTransform', 'cx', 'cy', 'r', 'fx', 'fy', 'fr']); break; case 'stop': attributes = attributes.concat(['offset', 'stop-color', 'stop-opacity']); break; } return attributes; }, /** * Returns object of given namespace * @memberOf fabric.util * @param {String} namespace Namespace string e.g. 'fabric.Image.filter' or 'fabric' * @return {Object} Object for given namespace (default fabric) */ resolveNamespace: function (namespace) { if (!namespace) { return fabric; } var parts = namespace.split('.'), len = parts.length, i, obj = global || fabric.window; for (i = 0; i < len; ++i) { obj = obj[parts[i]]; } return obj; }, /** * Loads image element from given url and passes it to a callback * @memberOf fabric.util * @param {String} url URL representing an image * @param {Function} callback Callback; invoked with loaded image * @param {*} [context] Context to invoke callback in * @param {Object} [crossOrigin] crossOrigin value to set image element to */ loadImage: function (url, callback, context, crossOrigin) { if (!url) { callback && callback.call(context, url); return; } var img = fabric.util.createImage(); /** @ignore */ var onLoadCallback = function () { callback && callback.call(context, img); img = img.onload = img.onerror = null; }; img.onload = onLoadCallback; /** @ignore */ img.onerror = function () { fabric.log('Error loading ' + img.src); callback && callback.call(context, null, true); img = img.onload = img.onerror = null; }; // data-urls appear to be buggy with crossOrigin // https://github.com/kangax/fabric.js/commit/d0abb90f1cd5c5ef9d2a94d3fb21a22330da3e0a#commitcomment-4513767 // see https://code.google.com/p/chromium/issues/detail?id=315152 // https://bugzilla.mozilla.org/show_bug.cgi?id=935069 if (url.indexOf('data') !== 0 && crossOrigin) { img.crossOrigin = crossOrigin; } // IE10 / IE11-Fix: SVG contents from data: URI // will only be available if the IMG is present // in the DOM (and visible) if (url.substring(0, 14) === 'data:image/svg') { img.onload = null; fabric.util.loadImageInDom(img, onLoadCallback); } img.src = url; }, /** * Attaches SVG image with data: URL to the dom * @memberOf fabric.util * @param {Object} img Image object with data:image/svg src * @param {Function} callback Callback; invoked with loaded image * @return {Object} DOM element (div containing the SVG image) */ loadImageInDom: function (img, onLoadCallback) { var div = fabric.document.createElement('div'); div.style.width = div.style.height = '1px'; div.style.left = div.style.top = '-100%'; div.style.position = 'absolute'; div.appendChild(img); fabric.document.querySelector('body').appendChild(div); /** * Wrap in function to: * 1. Call existing callback * 2. Cleanup DOM */ img.onload = function () { onLoadCallback(); div.parentNode.removeChild(div); div = null; }; }, /** * Creates corresponding fabric instances from their object representations * @static * @memberOf fabric.util * @param {Array} objects Objects to enliven * @param {Function} callback Callback to invoke when all objects are created * @param {String} namespace Namespace to get klass "Class" object from * @param {Function} reviver Method for further parsing of object elements, * called after each fabric object created. */ enlivenObjects: function (objects, callback, namespace, reviver) { objects = objects || []; var enlivenedObjects = [], numLoadedObjects = 0, numTotalObjects = objects.length; function onLoaded () { if (++numLoadedObjects === numTotalObjects) { callback && callback(enlivenedObjects.filter(function (obj) { // filter out undefined objects (objects that gave error) return obj; })); } } if (!numTotalObjects) { callback && callback(enlivenedObjects); return; } objects.forEach(function (o, index) { // if sparse array if (!o || !o.type) { onLoaded(); return; } var klass = fabric.util.getKlass(o.type, namespace); klass.fromObject(o, function (obj, error) { error || (enlivenedObjects[index] = obj); reviver && reviver(o, obj, error); onLoaded(); }); }); }, /** * Create and wait for loading of patterns * @static * @memberOf fabric.util * @param {Array} patterns Objects to enliven * @param {Function} callback Callback to invoke when all objects are created * called after each fabric object created. */ enlivenPatterns: function (patterns, callback) { patterns = patterns || []; function onLoaded () { if (++numLoadedPatterns === numPatterns) { callback && callback(enlivenedPatterns); } } var enlivenedPatterns = [], numLoadedPatterns = 0, numPatterns = patterns.length; if (!numPatterns) { callback && callback(enlivenedPatterns); return; } patterns.forEach(function (p, index) { if (p && p.source) { new fabric.Pattern(p, function (pattern) { enlivenedPatterns[index] = pattern; onLoaded(); }); } else { enlivenedPatterns[index] = p; onLoaded(); } }); }, /** * Groups SVG elements (usually those retrieved from SVG document) * @static * @memberOf fabric.util * @param {Array} elements SVG elements to group * @param {Object} [options] Options object * @param {String} path Value to set sourcePath to * @return {fabric.Object|fabric.Group} */ groupSVGElements: function (elements, options, path) { var object; if (elements && elements.length === 1) { return elements[0]; } if (options) { if (options.width && options.height) { options.centerPoint = { x: options.width / 2, y: options.height / 2 }; } else { delete options.width; delete options.height; } } object = new fabric.Group(elements, options); if (typeof path !== 'undefined') { object.sourcePath = path; } return object; }, /** * Populates an object with properties of another object * @static * @memberOf fabric.util * @param {Object} source Source object * @param {Object} destination Destination object * @return {Array} properties Properties names to include */ populateWithProperties: function (source, destination, properties) { if (properties && Object.prototype.toString.call(properties) === '[object Array]') { for (var i = 0, len = properties.length; i < len; i++) { if (properties[i] in source) { destination[properties[i]] = source[properties[i]]; } } } }, /** * Draws a dashed line between two points * * This method is used to draw dashed line around selection area. * See <a href="http://stackoverflow.com/questions/4576724/dotted-stroke-in-canvas">dotted stroke in canvas</a> * * @param {CanvasRenderingContext2D} ctx context * @param {Number} x start x coordinate * @param {Number} y start y coordinate * @param {Number} x2 end x coordinate * @param {Number} y2 end y coordinate * @param {Array} da dash array pattern */ drawDashedLine: function (ctx, x, y, x2, y2, da) { var dx = x2 - x, dy = y2 - y, len = sqrt(dx * dx + dy * dy), rot = atan2(dy, dx), dc = da.length, di = 0, draw = true; ctx.save(); ctx.translate(x, y); ctx.moveTo(0, 0); ctx.rotate(rot); x = 0; while (len > x) { x += da[di++ % dc]; if (x > len) { x = len; } ctx[draw ? 'lineTo' : 'moveTo'](x, 0); draw = !draw; } ctx.restore(); }, /** * Creates canvas element * @static * @memberOf fabric.util * @return {CanvasElement} initialized canvas element */ createCanvasElement: function () { return fabric.document.createElement('canvas'); }, /** * Creates a canvas element that is a copy of another and is also painted * @param {CanvasElement} canvas to copy size and content of * @static * @memberOf fabric.util * @return {CanvasElement} initialized canvas element */ copyCanvasElement: function (canvas) { var newCanvas = fabric.util.createCanvasElement(); newCanvas.width = canvas.width; newCanvas.height = canvas.height; newCanvas.getContext('2d').drawImage(canvas, 0, 0); return newCanvas; }, /** * since 2.6.0 moved from canvas instance to utility. * @param {CanvasElement} canvasEl to copy size and content of * @param {String} format 'jpeg' or 'png', in some browsers 'webp' is ok too * @param {Number} quality <= 1 and > 0 * @static * @memberOf fabric.util * @return {String} data url */ toDataURL: function (canvasEl, format, quality) { return canvasEl.toDataURL('image/' + format, quality); }, /** * Creates image element (works on client and node) * @static * @memberOf fabric.util * @return {HTMLImageElement} HTML image element */ createImage: function () { return fabric.document.createElement('img'); }, /** * @static * @memberOf fabric.util * @deprecated since 2.0.0 * @param {fabric.Object} receiver Object implementing `clipTo` method * @param {CanvasRenderingContext2D} ctx Context to clip */ clipContext: function (receiver, ctx) { ctx.save(); ctx.beginPath(); receiver.clipTo(ctx); ctx.clip(); }, /** * Multiply matrix A by matrix B to nest transformations * @static * @memberOf fabric.util * @param {Array} a First transformMatrix * @param {Array} b Second transformMatrix * @param {Boolean} is2x2 flag to multiply matrices as 2x2 matrices $

资源预览图

9  生活离不开规则(课件)-2025-2026学年统编版(五四制)道德与法治三年级下册-第1页
1
9  生活离不开规则(课件)-2025-2026学年统编版(五四制)道德与法治三年级下册-第2页
2
9  生活离不开规则(课件)-2025-2026学年统编版(五四制)道德与法治三年级下册-第3页
3
9  生活离不开规则(课件)-2025-2026学年统编版(五四制)道德与法治三年级下册-第4页
4
9  生活离不开规则(课件)-2025-2026学年统编版(五四制)道德与法治三年级下册-第5页
5
9  生活离不开规则(课件)-2025-2026学年统编版(五四制)道德与法治三年级下册-第6页
6

由于学科网是一个信息分享及获取的平台,不确保部分用户上传资料的 来源及知识产权归属。如您发现相关资料侵犯您的合法权益,请联系学科网,我们核实后将及时进行处理。